From 64b70beeb309d4307acd4f2766d87d8fdd61443e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 Feb 2024 18:54:59 +0000 Subject: [PATCH 001/298] 8326773: Bump update version for OpenJDK: jdk-21.0.4 Reviewed-by: sgehwolf --- .jcheck/conf | 2 +- make/conf/version-numbers.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.jcheck/conf b/.jcheck/conf index e2ca212ab3a..dac5c3e0c81 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=21.0.3 +version=21.0.4 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index b4571b544e2..55ac8cbea94 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=21 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=3 +DEFAULT_VERSION_UPDATE=4 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2024-04-16 +DEFAULT_VERSION_DATE=2024-07-16 DEFAULT_VERSION_CLASSFILE_MAJOR=65 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 From ef13a829165c9a558e9ca343ad228a13553309ac Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Wed, 28 Feb 2024 02:50:14 +0000 Subject: [PATCH 002/298] 8324817: Parallel GC does not pre-touch all heap pages when AlwaysPreTouch enabled and large page disabled Backport-of: 80642dd7af3fcc7c042f11798c5cc899e20b9368 --- .../share/gc/parallel/mutableSpace.cpp | 5 +- .../parallel/TestAlwaysPreTouchBehavior.java | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java diff --git a/src/hotspot/share/gc/parallel/mutableSpace.cpp b/src/hotspot/share/gc/parallel/mutableSpace.cpp index c6462f8c9d7..69ebf86c7c2 100644 --- a/src/hotspot/share/gc/parallel/mutableSpace.cpp +++ b/src/hotspot/share/gc/parallel/mutableSpace.cpp @@ -120,11 +120,12 @@ void MutableSpace::initialize(MemRegion mr, } if (AlwaysPreTouch) { + size_t pretouch_page_size = UseLargePages ? page_size : os::vm_page_size(); PretouchTask::pretouch("ParallelGC PreTouch head", (char*)head.start(), (char*)head.end(), - page_size, pretouch_workers); + pretouch_page_size, pretouch_workers); PretouchTask::pretouch("ParallelGC PreTouch tail", (char*)tail.start(), (char*)tail.end(), - page_size, pretouch_workers); + pretouch_page_size, pretouch_workers); } // Remember where we stopped so that we can continue later. diff --git a/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java b/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java new file mode 100644 index 00000000000..12c03661e0e --- /dev/null +++ b/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, 2024, Alibaba Group Holding Limited. 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. + */ + +package gc.parallel; + +/** + * @test TestAlwaysPreTouchBehavior + * @summary Tests AlwaysPreTouch Bahavior, pages of java heap should be pretouched with AlwaysPreTouch enabled. This test reads RSS of test process, which should be bigger than heap size(1g) with AlwaysPreTouch enabled. + * @requires vm.gc.Parallel + * @requires vm.debug != true + * @requires os.family == "linux" + * @requires os.maxMemory > 2G + * @library /test/lib + * @run main/othervm -Xmx1g -Xms1g -XX:+UseParallelGC -XX:+AlwaysPreTouch gc.parallel.TestAlwaysPreTouchBehavior + */ +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.IOException; +import java.util.*; +import javax.management.*; +import java.lang.management.*; +import jdk.test.lib.Utils; +import jdk.test.lib.Asserts; +import java.lang.management.*; +import java.util.stream.*; +import java.io.*; + +public class TestAlwaysPreTouchBehavior { + public static long getProcessRssInKb() throws IOException { + String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; + // Read RSS from /proc/$pid/status. Only available on Linux. + String processStatusFile = "/proc/" + pid + "/status"; + BufferedReader reader = new BufferedReader(new FileReader(processStatusFile)); + String line = null; + while ((line = reader.readLine()) != null) { + if (line.startsWith("VmRSS:")) { + break; + } + } + reader.close(); + return Long.valueOf(line.split("\\s+")[1].trim()); + } + public static void main(String [] args) { + long rss = 0; + Runtime runtime = Runtime.getRuntime(); + long committedMemory = runtime.totalMemory() / 1024; // in kb + try { + rss = getProcessRssInKb(); + } catch (Exception e) { + System.out.println("cannot get RSS, just skip"); + return; // Did not get avaiable RSS, just ignore this test + } + Asserts.assertGreaterThanOrEqual(rss, committedMemory, "RSS of this process(" + rss + "kb) should be bigger than or equal to committed heap mem(" + committedMemory + "kb)"); + } +} + From dc8759c631832ca2e1d350e7fd55ddbf000499f0 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Wed, 28 Feb 2024 07:05:02 +0000 Subject: [PATCH 003/298] 8316053: Open some swing tests 3 Backport-of: a2391a92cd09630cc3c46024f7e02924a997cc86 --- test/jdk/javax/swing/JDialog/bug4859570.java | 60 ++++++ test/jdk/javax/swing/JDialog/bug4936652.java | 47 +++++ test/jdk/javax/swing/JLabel/bug4768127.java | 125 ++++++++++++ .../swing/MultiMonitor/MultimonVImage.java | 183 ++++++++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 test/jdk/javax/swing/JDialog/bug4859570.java create mode 100644 test/jdk/javax/swing/JDialog/bug4936652.java create mode 100644 test/jdk/javax/swing/JLabel/bug4768127.java create mode 100644 test/jdk/javax/swing/MultiMonitor/MultimonVImage.java diff --git a/test/jdk/javax/swing/JDialog/bug4859570.java b/test/jdk/javax/swing/JDialog/bug4859570.java new file mode 100644 index 00000000000..cc0f4f7adee --- /dev/null +++ b/test/jdk/javax/swing/JDialog/bug4859570.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4859570 + * @summary SwingUtilities.sharedOwnerFrame is never disposed + * @key headful + */ + +import java.awt.Robot; +import java.awt.Window; +import javax.swing.JDialog; +import javax.swing.SwingUtilities; + +public class bug4859570 { + static Window owner; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JDialog dialog = new JDialog(); + dialog.setTitle("bug4859570"); + dialog.setBounds(100, 100, 100, 100); + dialog.setVisible(true); + + owner = dialog.getOwner(); + dialog.dispose(); + }); + + Robot r = new Robot(); + r.waitForIdle(); + r.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + if (owner.isDisplayable()) { + throw new RuntimeException("The shared owner frame should be disposed."); + } + }); + } +} diff --git a/test/jdk/javax/swing/JDialog/bug4936652.java b/test/jdk/javax/swing/JDialog/bug4936652.java new file mode 100644 index 00000000000..989c8e4194f --- /dev/null +++ b/test/jdk/javax/swing/JDialog/bug4936652.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4936652 + * @key headful + * @summary JDialog.setVisible, JDialog.dispose works incorrectly + */ + +import javax.swing.JDialog; +import javax.swing.SwingUtilities; + +public class bug4936652 { + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + for (int i = 0 ; i < 100; i++) { + System.out.println("i: " + i); + JDialog o = new JDialog(); + o.setTitle("bug4936652"); + o.setVisible(true); + o.setVisible(false); + o.dispose(); + } + }); + } +} diff --git a/test/jdk/javax/swing/JLabel/bug4768127.java b/test/jdk/javax/swing/JLabel/bug4768127.java new file mode 100644 index 00000000000..0ccb3c7998a --- /dev/null +++ b/test/jdk/javax/swing/JLabel/bug4768127.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4768127 + * @summary ToolTipManager not removed from components + * @key headful + */ + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseMotionListener; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; + +public class bug4768127 { + static JFrame fr; + static volatile Point p; + static volatile JLabel[] label = new JLabel[2]; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("bug4768127"); + + JDesktopPane jdp = new JDesktopPane(); + JInternalFrame jif1 = new JInternalFrame("jif 1"); + JInternalFrame jif2 = new JInternalFrame("jif 2"); + label[0] = new JLabel("Label 1"); + label[1] = new JLabel("Label 2"); + + label[0].setToolTipText("tooltip 1"); + jif1.getContentPane().add(label[0]); + jif1.setBounds(0, 0, 130, 160); + jif1.setVisible(true); + jdp.add(jif1); + + label[1].setToolTipText("tooltip 2"); + jif2.getContentPane().add(label[1]); + jif2.setBounds(210, 0, 130, 220); + jif2.setVisible(true); + jdp.add(jif2); + + fr.getContentPane().add(jdp); + fr.setLocationRelativeTo(null); + + fr.setSize(400, 300); + fr.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(10); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(0, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(1, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(0, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(1, robot); + robot.waitForIdle(); + robot.delay(3000); + + MouseMotionListener[] mml = label[0].getMouseMotionListeners(); + if (mml.length > 0 && mml[0] instanceof ToolTipManager) { + throw new RuntimeException("Extra MouseMotionListeners were added to the label \"Label 1\" by ToolTipManager"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + static void clickLabel(int i, Robot robot) throws Exception { + SwingUtilities.invokeAndWait(() -> { + p = label[i].getLocationOnScreen(); + }); + final Rectangle rect = label[i].getBounds(); + robot.mouseMove(p.x + rect.width / 2, p.y + rect.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + //Generate mouseMotionEvent + robot.mouseMove(p.x + rect.width / 2 + 3, p.y + rect.height / 2 + 3); + robot.mouseMove(p.x + rect.width / 2, p.y + rect.height / 2); + } +} diff --git a/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java new file mode 100644 index 00000000000..730424e306c --- /dev/null +++ b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4371134 + * @key headful + * @summary displays an animating fps (frames per second) + * counter. When the window is dragged from monitor to monitor, + * the speed of the animation should not change too greatly. + * @library /open/test/jdk/java/awt/regtesthelpers + * @run main/manual MultimonVImage + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JViewport; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class MultimonVImage { + private static final String instructionsText = + "This test should be run on any Windows platform that\n" + + "supports multiple monitors.\n" + + "You will see an animating fps (frames per second) counter at\n" + + "the bottom of the window. Drag the window into the other monitor\n" + + "and that counter should not change drastically. If the counter\n" + + "is much lower on one monitor than the other (barring situations\n" + + "described below) then the back buffer may not be accelerated\n" + + "on the second monitor and the test fails.\n" + + "Situations in which performance will differ even though there\n" + + "is acceleration on both monitors include:\n" + + " - different bit depths on each monitor. The higher the bits\n" + + " per pixel, the more data to push and the lower the fps number.\n" + + " Set the bit depths to be the same on both monitors to work\n" + + " around this issue.\n" + + " - the amount of acceleration available on each video card differs,\n" + + " so if your system uses different video cards then you should\n" + + " expect some difference between the cards. To work around this\n" + + " issue, try to use the same or similar video cards for each monitor."; + + public static void main(String[] args) throws Exception { + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("MultimonVImage Instructions") + .instructions(instructionsText) + .testTimeOut(5) + .rows(25) + .columns(50) + .build(); + + SwingUtilities.invokeAndWait(() -> { + AnimatingFrame af = new AnimatingFrame(); + af.test(); + af.run(); + + PassFailJFrame.addTestWindow(af); + PassFailJFrame.positionTestWindow(af, + PassFailJFrame.Position.HORIZONTAL); + }); + + passFailJFrame.awaitAndCheck(); + } +} + +class FrameCounter { + + String fpsString = "Calculating..."; + long startTime, endTime; + int numFrames; + + public FrameCounter() { + startTime = System.currentTimeMillis(); + } + + public String addFrame() { + ++numFrames; + return calculateFPS(); + } + + String calculateFPS() { + endTime = System.currentTimeMillis(); + double seconds = ((double) endTime - (double) startTime) / 1000; + if (seconds > 1) { + int fps = (int) (numFrames / seconds); + fpsString = fps + " fps"; + startTime = endTime; + numFrames = 0; + } + return fpsString; + } +} + +class AnimatingComponent extends JViewport { + + FrameCounter frameCounter; + int boxX, boxY; + int boxW, boxH; + int xStep = 1; + + public AnimatingComponent() { + frameCounter = new FrameCounter(); + boxX = 0; + boxY = 0; + boxW = 100; + boxH = 100; + } + + public void paintComponent(Graphics g) { + boxX += xStep; + if (boxX <= 0 || (boxX + boxW) > getWidth()) { + xStep = -xStep; + boxX += (2 * xStep); + } + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.green); + for (int i = 0; i < 100; ++i) { + g.fillRect(boxX, boxY, 100, 100); + } + g.setColor(Color.black); + g.drawString(frameCounter.addFrame(), 200, getHeight() - 30); + } +} + +class AnimatingFrame extends JFrame implements Runnable { + JViewport component; + Thread thread; + + public AnimatingFrame() { + setSize(500, 500); + setTitle("MultimonVImage Demo"); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + component = new AnimatingComponent(); + component.setPreferredSize(new Dimension(500, 500)); + setContentPane(component); + component.setVisible(true); + + setLocationRelativeTo(null); + pack(); + setVisible(true); + } + + public void test() { + thread = new Thread(this); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public void run() { + Thread me = Thread.currentThread(); + while (thread == me) { + component.repaint(); + } + } +} \ No newline at end of file From 8ac431347fdced6c4210c2b5ffad86ef484584b2 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 28 Feb 2024 07:39:55 +0000 Subject: [PATCH 004/298] 8324723: GHA: Upgrade some actions to avoid deprecated Node 16 Backport-of: 951b5f8ecb9cd2a72b3904c110179afe487ada2b --- .github/actions/do-build/action.yml | 4 ++-- .github/actions/get-bootjdk/action.yml | 2 +- .github/actions/get-bundles/action.yml | 4 ++-- .github/actions/get-jtreg/action.yml | 2 +- .github/actions/get-msys2/action.yml | 3 +-- .github/actions/upload-bundles/action.yml | 2 +- .github/workflows/build-cross-compile.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/test.yml | 4 ++-- 9 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/actions/do-build/action.yml b/.github/actions/do-build/action.yml index 3deb7f4b8f8..79eddf8c70f 100644 --- a/.github/actions/do-build/action.yml +++ b/.github/actions/do-build/action.yml @@ -66,7 +66,7 @@ runs: shell: bash - name: 'Upload build logs' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failure-logs-${{ inputs.platform }}${{ inputs.debug-suffix }} path: failure-logs @@ -74,7 +74,7 @@ runs: # This is the best way I found to abort the job with an error message - name: 'Notify about build failures' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: core.setFailed('Build failed. See summary for details.') if: steps.check.outputs.failure == 'true' diff --git a/.github/actions/get-bootjdk/action.yml b/.github/actions/get-bootjdk/action.yml index 1e569dd47c5..25ee1d8dfa0 100644 --- a/.github/actions/get-bootjdk/action.yml +++ b/.github/actions/get-bootjdk/action.yml @@ -65,7 +65,7 @@ runs: - name: 'Check cache for BootJDK' id: get-cached-bootjdk - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: bootjdk/jdk key: boot-jdk-${{ inputs.platform }}-${{ steps.sha256.outputs.value }} diff --git a/.github/actions/get-bundles/action.yml b/.github/actions/get-bundles/action.yml index 956e1520cfb..0e52320a350 100644 --- a/.github/actions/get-bundles/action.yml +++ b/.github/actions/get-bundles/action.yml @@ -48,14 +48,14 @@ runs: steps: - name: 'Download bundles artifact' id: download-bundles - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles continue-on-error: true - name: 'Download bundles artifact (retry)' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles diff --git a/.github/actions/get-jtreg/action.yml b/.github/actions/get-jtreg/action.yml index a45c0c1e6a9..faedcc18807 100644 --- a/.github/actions/get-jtreg/action.yml +++ b/.github/actions/get-jtreg/action.yml @@ -41,7 +41,7 @@ runs: - name: 'Check cache for JTReg' id: get-cached-jtreg - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: jtreg/installed key: jtreg-${{ steps.version.outputs.value }} diff --git a/.github/actions/get-msys2/action.yml b/.github/actions/get-msys2/action.yml index 7dac1538536..843b77ac064 100644 --- a/.github/actions/get-msys2/action.yml +++ b/.github/actions/get-msys2/action.yml @@ -30,8 +30,7 @@ runs: using: composite steps: - name: 'Install MSYS2' - # use a specific release of msys2/setup-msys2 to prevent jtreg build failures on newer release - uses: msys2/setup-msys2@7efe20baefed56359985e327d329042cde2434ff + uses: msys2/setup-msys2@v2.22.0 with: install: 'autoconf tar unzip zip make' path-type: minimal diff --git a/.github/actions/upload-bundles/action.yml b/.github/actions/upload-bundles/action.yml index 88f7f6e8107..b35ee3a42e9 100644 --- a/.github/actions/upload-bundles/action.yml +++ b/.github/actions/upload-bundles/action.yml @@ -69,7 +69,7 @@ runs: shell: bash - name: 'Upload bundles artifact' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 5db69f07d98..8f88075e112 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -120,7 +120,7 @@ jobs: - name: 'Check cache for sysroot' id: get-cached-sysroot - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: sysroot key: sysroot-${{ matrix.debian-arch }}-${{ hashFiles('./.github/workflows/build-cross-compile.yml') }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 686d5ba4eae..e99d17aa197 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -367,7 +367,7 @@ jobs: # Hack to get hold of the api environment variables that are only defined for actions - name: 'Get API configuration' id: api - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: 'return { url: process.env["ACTIONS_RUNTIME_URL"], token: process.env["ACTIONS_RUNTIME_TOKEN"] }' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8808ab80d0e..a8885866c12 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -211,7 +211,7 @@ jobs: if: always() - name: 'Upload test results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: results name: ${{ steps.package.outputs.artifact-name }} @@ -219,7 +219,7 @@ jobs: # This is the best way I found to abort the job with an error message - name: 'Notify about test failures' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: core.setFailed('${{ steps.run-tests.outputs.error-message }}') if: steps.run-tests.outputs.failure == 'true' From 677556d2ec39dfa5dd177a7d9c378e04a1503d1a Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 28 Feb 2024 08:04:42 +0000 Subject: [PATCH 005/298] 8320275: assert(_chunk->bitmap().at(index)) failed: Bit not set at index 8323595: is_aligned(p, alignof(OopT))) assertion fails in Jetty without compressed OOPs Reviewed-by: phh Backport-of: e9e694f4ef7b080d7fe1ad5b2f2daa2fccd0456e --- .../cpu/aarch64/sharedRuntime_aarch64.cpp | 12 +++++--- src/hotspot/cpu/arm/sharedRuntime_arm.cpp | 1 - src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 2 +- src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp | 12 +++++--- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 2 +- src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp | 3 +- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 12 +++++--- src/hotspot/share/c1/c1_FrameMap.cpp | 2 +- src/hotspot/share/code/nmethod.cpp | 2 +- src/hotspot/share/oops/method.hpp | 3 +- src/hotspot/share/oops/stackChunkOop.hpp | 2 +- .../share/oops/stackChunkOop.inline.hpp | 3 +- src/hotspot/share/prims/foreignGlobals.cpp | 2 +- .../share/runtime/continuationFreezeThaw.cpp | 30 ++++++++++++++----- src/hotspot/share/runtime/frame.cpp | 2 +- src/hotspot/share/runtime/sharedRuntime.cpp | 4 +-- src/hotspot/share/runtime/signature.cpp | 21 +++++++------ 17 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 2335a70c9fe..cd2567434f4 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -310,7 +310,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, uint int_args = 0; uint fp_args = 0; - uint stk_args = 0; // inc by 2 each time + uint stk_args = 0; for (int i = 0; i < total_args_passed; i++) { switch (sig_bt[i]) { @@ -322,8 +322,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_VOID: @@ -340,6 +341,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -348,8 +350,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_DOUBLE: @@ -357,6 +360,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -367,7 +371,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } } - return align_up(stk_args, 2); + return stk_args; } // Patch the callers callsite with entry to compiled code if it exists. diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp index e4f4107da0f..d55cdfb0251 100644 --- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp +++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp @@ -444,7 +444,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } } - if (slot & 1) slot++; return slot; } diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 401d4f4efa8..2281c083b98 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -734,7 +734,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, ShouldNotReachHere(); } } - return align_up(stk, 2); + return stk; } #if defined(COMPILER1) || defined(COMPILER2) diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 691dfa1bd70..e34ace1b02c 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -266,7 +266,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, uint int_args = 0; uint fp_args = 0; - uint stk_args = 0; // inc by 2 each time + uint stk_args = 0; for (int i = 0; i < total_args_passed; i++) { switch (sig_bt[i]) { @@ -278,8 +278,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_VOID: @@ -295,6 +296,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -303,8 +305,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_DOUBLE: @@ -312,6 +315,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -321,7 +325,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } } - return align_up(stk_args, 2); + return stk_args; } // Patch the callers callsite with entry to compiled code if it exists. diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 05b607ec03c..d28399ef819 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -755,7 +755,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, ShouldNotReachHere(); } } - return align_up(stk, 2); + return stk; } int SharedRuntime::c_calling_convention(const BasicType *sig_bt, diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp index c391349cfa3..7a7aa8e9070 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp @@ -528,8 +528,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } } - // return value can be odd number of VMRegImpl stack slots make multiple of 2 - return align_up(stack, 2); + return stack; } // Patch the callers callsite with entry to compiled code if it exists. diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index 0712ba50c07..f5847a0dc6d 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -497,7 +497,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, uint int_args = 0; uint fp_args = 0; - uint stk_args = 0; // inc by 2 each time + uint stk_args = 0; for (int i = 0; i < total_args_passed; i++) { switch (sig_bt[i]) { @@ -509,8 +509,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_VOID: @@ -527,6 +528,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (int_args < Argument::n_int_register_parameters_j) { regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -535,8 +537,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set1(VMRegImpl::stack2reg(stk_args)); - stk_args += 2; + stk_args += 1; } break; case T_DOUBLE: @@ -544,6 +547,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, if (fp_args < Argument::n_float_register_parameters_j) { regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); } else { + stk_args = align_up(stk_args, 2); regs[i].set2(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -554,7 +558,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } } - return align_up(stk_args, 2); + return stk_args; } // Patch the callers callsite with entry to compiled code if it exists. diff --git a/src/hotspot/share/c1/c1_FrameMap.cpp b/src/hotspot/share/c1/c1_FrameMap.cpp index be72b1c1459..8439887a397 100644 --- a/src/hotspot/share/c1/c1_FrameMap.cpp +++ b/src/hotspot/share/c1/c1_FrameMap.cpp @@ -72,7 +72,7 @@ CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signa } } - intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs); + intptr_t out_preserve = align_up(SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs), 2); LIR_OprList* args = new LIR_OprList(signature->length()); for (i = 0; i < sizeargs;) { BasicType t = sig_bt[i]; diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index fb2e5bd78b0..86df9db21cc 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -3059,7 +3059,7 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo assert(sig_index == sizeargs, ""); } const char* spname = "sp"; // make arch-specific? - intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs); + SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs); int stack_slot_offset = this->frame_size() * wordSize; int tab1 = 14, tab2 = 24; int sig_index = 0; diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index a4f8f3075ef..1e2234e103b 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -444,7 +444,8 @@ class Method : public Metadata { void remove_unshareable_flags() NOT_CDS_RETURN; // the number of argument reg slots that the compiled method uses on the stack. - int num_stack_arg_slots() const { return constMethod()->num_stack_arg_slots(); } + int num_stack_arg_slots(bool rounded = true) const { + return rounded ? align_up(constMethod()->num_stack_arg_slots(), 2) : constMethod()->num_stack_arg_slots(); } virtual void metaspace_pointers_do(MetaspaceClosure* iter); virtual MetaspaceObj::Type type() const { return MethodType; } diff --git a/src/hotspot/share/oops/stackChunkOop.hpp b/src/hotspot/share/oops/stackChunkOop.hpp index 36b06ecd324..abfe47ad3f1 100644 --- a/src/hotspot/share/oops/stackChunkOop.hpp +++ b/src/hotspot/share/oops/stackChunkOop.hpp @@ -155,7 +155,7 @@ class stackChunkOopDesc : public instanceOopDesc { inline void* gc_data() const; inline BitMapView bitmap() const; - inline BitMap::idx_t bit_index_for(intptr_t* p) const; + inline BitMap::idx_t bit_index_for(address p) const; inline intptr_t* address_for_bit(BitMap::idx_t index) const; template inline BitMap::idx_t bit_index_for(OopT* p) const; template inline OopT* address_for_bit(BitMap::idx_t index) const; diff --git a/src/hotspot/share/oops/stackChunkOop.inline.hpp b/src/hotspot/share/oops/stackChunkOop.inline.hpp index 1d5bb7ffa81..9bde7e255d2 100644 --- a/src/hotspot/share/oops/stackChunkOop.inline.hpp +++ b/src/hotspot/share/oops/stackChunkOop.inline.hpp @@ -256,12 +256,13 @@ inline BitMapView stackChunkOopDesc::bitmap() const { return bitmap; } -inline BitMap::idx_t stackChunkOopDesc::bit_index_for(intptr_t* p) const { +inline BitMap::idx_t stackChunkOopDesc::bit_index_for(address p) const { return UseCompressedOops ? bit_index_for((narrowOop*)p) : bit_index_for((oop*)p); } template inline BitMap::idx_t stackChunkOopDesc::bit_index_for(OopT* p) const { + assert(is_aligned(p, alignof(OopT)), "should be aligned: " PTR_FORMAT, p2i(p)); assert(p >= (OopT*)start_address(), "Address not in chunk"); return p - (OopT*)start_address(); } diff --git a/src/hotspot/share/prims/foreignGlobals.cpp b/src/hotspot/share/prims/foreignGlobals.cpp index 261be4ead59..b11ec1a4552 100644 --- a/src/hotspot/share/prims/foreignGlobals.cpp +++ b/src/hotspot/share/prims/foreignGlobals.cpp @@ -170,7 +170,7 @@ int NativeCallingConvention::calling_convention(const BasicType* sig_bt, VMStora int JavaCallingConvention::calling_convention(const BasicType* sig_bt, VMStorage* regs, int num_args) const { VMRegPair* vm_regs = NEW_RESOURCE_ARRAY(VMRegPair, num_args); - int slots = SharedRuntime::java_calling_convention(sig_bt, vm_regs, num_args); + int slots = align_up(SharedRuntime::java_calling_convention(sig_bt, vm_regs, num_args), 2); for (int i = 0; i < num_args; i++) { VMRegPair pair = vm_regs[i]; // note, we ignore second here. Signature should consist of register-size values. So there should be diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index 36ce7a532eb..662b8ef81f9 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -1741,7 +1741,7 @@ class ThawBase : public StackObj { inline void before_thaw_java_frame(const frame& hf, const frame& caller, bool bottom, int num_frame); inline void after_thaw_java_frame(const frame& f, bool bottom); inline void patch(frame& f, const frame& caller, bool bottom); - void clear_bitmap_bits(intptr_t* start, int range); + void clear_bitmap_bits(address start, address end); NOINLINE void recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames); void recurse_thaw_compiled_frame(const frame& hf, frame& caller, int num_frames, bool stub_caller); @@ -2122,13 +2122,22 @@ inline void ThawBase::patch(frame& f, const frame& caller, bool bottom) { assert(!bottom || (_cont.is_empty() != Continuation::is_cont_barrier_frame(f)), ""); } -void ThawBase::clear_bitmap_bits(intptr_t* start, int range) { +void ThawBase::clear_bitmap_bits(address start, address end) { + assert(is_aligned(start, wordSize), "should be aligned: " PTR_FORMAT, p2i(start)); + assert(is_aligned(end, VMRegImpl::stack_slot_size), "should be aligned: " PTR_FORMAT, p2i(end)); + // we need to clear the bits that correspond to arguments as they reside in the caller frame - // or they will keep objects that are otherwise unreachable alive - log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(start+range)); + // or they will keep objects that are otherwise unreachable alive. + + // Align `end` if UseCompressedOops is not set to avoid UB when calculating the bit index, since + // `end` could be at an odd number of stack slots from `start`, i.e might not be oop aligned. + // If that's the case the bit range corresponding to the last stack slot should not have bits set + // anyways and we assert that before returning. + address effective_end = UseCompressedOops ? end : align_down(end, wordSize); + log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(effective_end)); stackChunkOop chunk = _cont.tail(); - chunk->bitmap().clear_range(chunk->bit_index_for(start), - chunk->bit_index_for(start+range)); + chunk->bitmap().clear_range(chunk->bit_index_for(start), chunk->bit_index_for(effective_end)); + assert(effective_end == end || !chunk->bitmap().at(chunk->bit_index_for(effective_end)), "bit should not be set"); } NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames) { @@ -2181,7 +2190,9 @@ NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& c _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance); } else if (_cont.tail()->has_bitmap() && locals > 0) { assert(hf.is_heap_frame(), "should be"); - clear_bitmap_bits(heap_frame_bottom - locals, locals); + address start = (address)(heap_frame_bottom - locals); + address end = (address)heap_frame_bottom; + clear_bitmap_bits(start, end); } DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);) @@ -2254,7 +2265,10 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n // can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance); } else if (_cont.tail()->has_bitmap() && added_argsize > 0) { - clear_bitmap_bits(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top, added_argsize); + address start = (address)(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top); + int stack_args_slots = f.cb()->as_compiled_method()->method()->num_stack_arg_slots(false /* rounded */); + int argsize_in_bytes = stack_args_slots * VMRegImpl::stack_slot_size; + clear_bitmap_bits(start, start + argsize_in_bytes); } DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);) diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp index 6266bd004ea..51d66b8d9f8 100644 --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -1439,7 +1439,7 @@ void frame::describe(FrameValues& values, int frame_no, const RegisterMap* reg_m assert(sig_index == sizeargs, ""); } int stack_arg_slots = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs); - assert(stack_arg_slots == m->num_stack_arg_slots(), ""); + assert(stack_arg_slots == m->num_stack_arg_slots(false /* rounded */), ""); int out_preserve = SharedRuntime::out_preserve_stack_slots(); int sig_index = 0; int arg_index = (m->is_static() ? 0 : -1); diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index edbdad4f24b..6439a958ccb 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -1991,7 +1991,7 @@ void SharedRuntime::check_member_name_argument_is_last_argument(const methodHand assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); - int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1); + java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1); for (int i = 0; i < member_arg_pos; i++) { VMReg a = regs_with_member_name[i].first(); @@ -3089,7 +3089,7 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) { BasicType ret_type = si.return_type(); // Now get the compiled-Java arguments layout. - int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed); + SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed); // Generate the compiled-to-native wrapper code nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type); diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp index 30eae826c9f..c23d39a81e8 100644 --- a/src/hotspot/share/runtime/signature.cpp +++ b/src/hotspot/share/runtime/signature.cpp @@ -178,7 +178,6 @@ void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) { } #if defined(_LP64) && !defined(ZERO) - _stack_arg_slots = align_up(_stack_arg_slots, 2); #ifdef ASSERT int dbg_stack_arg_slots = compute_num_stack_arg_slots(_signature, _param_size, static_flag); assert(_stack_arg_slots == dbg_stack_arg_slots, "fingerprinter: %d full: %d", _stack_arg_slots, dbg_stack_arg_slots); @@ -235,14 +234,17 @@ void Fingerprinter::do_type_calling_convention(BasicType type) { case T_BYTE: case T_SHORT: case T_INT: -#if defined(PPC64) || defined(S390) if (_int_args < Argument::n_int_register_parameters_j) { _int_args++; } else { +#if defined(PPC64) || defined(S390) + _stack_arg_slots += 1; +#else + _stack_arg_slots = align_up(_stack_arg_slots, 2); _stack_arg_slots += 1; +#endif // defined(PPC64) || defined(S390) } break; -#endif // defined(PPC64) || defined(S390) case T_LONG: case T_OBJECT: case T_ARRAY: @@ -250,26 +252,27 @@ void Fingerprinter::do_type_calling_convention(BasicType type) { if (_int_args < Argument::n_int_register_parameters_j) { _int_args++; } else { - PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2)); - S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2)); + _stack_arg_slots = align_up(_stack_arg_slots, 2); _stack_arg_slots += 2; } break; case T_FLOAT: -#if defined(PPC64) || defined(S390) if (_fp_args < Argument::n_float_register_parameters_j) { _fp_args++; } else { +#if defined(PPC64) || defined(S390) + _stack_arg_slots += 1; +#else + _stack_arg_slots = align_up(_stack_arg_slots, 2); _stack_arg_slots += 1; +#endif // defined(PPC64) || defined(S390) } break; -#endif // defined(PPC64) || defined(S390) case T_DOUBLE: if (_fp_args < Argument::n_float_register_parameters_j) { _fp_args++; } else { - PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2)); - S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2)); + _stack_arg_slots = align_up(_stack_arg_slots, 2); _stack_arg_slots += 2; } break; From cea29fe9f073e9a40d6c2e6369c0530c20e0d1ad Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Wed, 28 Feb 2024 08:26:29 +0000 Subject: [PATCH 006/298] 8325213: Flags introduced by configure script are not passed to ADLC build Backport-of: 9ee9f288497268d64ddd48783ecb68f7e5426084 --- make/hotspot/gensrc/GensrcAdlc.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index 0898d91e1c2..bb356476847 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk @@ -51,7 +51,7 @@ ifeq ($(call check-jvm-feature, compiler2), true) endif # Set the C++ standard - ADLC_CFLAGS += $(ADLC_LANGSTD_CXXFLAG) + ADLC_CFLAGS += $(ADLC_LANGSTD_CXXFLAGS) # NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to # hurt. From 3eb5517b73b58bee4985ae6c20a6e613e35d426c Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 28 Feb 2024 15:36:10 +0000 Subject: [PATCH 007/298] 8315373: Change VirtualThread to unmount after freezing, re-mount before thawing 8312498: Thread::getState and JVM TI GetThreadState should return TIMED_WAITING virtual thread is timed parked 8312777: notifyJvmtiMount before notifyJvmtiUnmount 8321270: Virtual Thread.yield consumes parking permit 8322818: Thread::getStackTrace can fail with InternalError if virtual thread is timed-parked when pinned 8323002: test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java times out on macosx-x64 8323296: java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java#id1 timed out 8316924: java/lang/Thread/virtual/stress/ParkALot.java times out Backport-of: 9a83d55887e5e3a0a2e1e020c6ccb91604672358 --- src/hotspot/share/classfile/javaClasses.cpp | 28 +- src/hotspot/share/classfile/javaClasses.hpp | 30 +- .../jfr/recorder/stacktrace/jfrStackTrace.cpp | 7 +- .../share/jfr/support/jfrThreadLocal.cpp | 9 +- .../classes/java/lang/VirtualThread.java | 281 ++++++------ .../GetThreadState/GetThreadStateTest.java | 416 ++++++++++++++++++ .../GetThreadState/libGetThreadStateTest.c | 51 +++ .../VThreadEventTest/VThreadEventTest.java | 6 +- .../lang/Thread/virtual/CustomScheduler.java | 15 - .../java/lang/Thread/virtual/ThreadAPI.java | 325 +++++++++----- .../lang/Thread/virtual/ThreadBuilders.java | 1 - .../stress/GetStackTraceALotWhenPinned.java | 123 ++++++ .../lang/Thread/virtual/stress/ParkALot.java | 95 ++++ 13 files changed, 1102 insertions(+), 285 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java create mode 100644 test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/libGetThreadStateTest.c create mode 100644 test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java create mode 100644 test/jdk/java/lang/Thread/virtual/stress/ParkALot.java diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 3e00a3fab4e..33a8abad5ef 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1986,24 +1986,28 @@ int java_lang_VirtualThread::state(oop vthread) { JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) { JavaThreadStatus status = JavaThreadStatus::NEW; - switch (state) { - case NEW : + switch (state & ~SUSPENDED) { + case NEW: status = JavaThreadStatus::NEW; break; - case STARTED : - case RUNNABLE : - case RUNNABLE_SUSPENDED : - case RUNNING : - case PARKING : - case YIELDING : + case STARTED: + case RUNNING: + case PARKING: + case TIMED_PARKING: + case UNPARKED: + case YIELDING: + case YIELDED: status = JavaThreadStatus::RUNNABLE; break; - case PARKED : - case PARKED_SUSPENDED : - case PINNED : + case PARKED: + case PINNED: status = JavaThreadStatus::PARKED; break; - case TERMINATED : + case TIMED_PARKED: + case TIMED_PINNED: + status = JavaThreadStatus::PARKED_TIMED; + break; + case TERMINATED: status = JavaThreadStatus::TERMINATED; break; default: diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 84ce35ba767..cd9b9ac5485 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -519,20 +519,22 @@ class java_lang_VirtualThread : AllStatic { JFR_ONLY(static int _jfr_epoch_offset;) public: enum { - NEW = 0, - STARTED = 1, - RUNNABLE = 2, - RUNNING = 3, - PARKING = 4, - PARKED = 5, - PINNED = 6, - YIELDING = 7, - TERMINATED = 99, - - // can be suspended from scheduling when unmounted - SUSPENDED = 1 << 8, - RUNNABLE_SUSPENDED = (RUNNABLE | SUSPENDED), - PARKED_SUSPENDED = (PARKED | SUSPENDED) + NEW = 0, + STARTED = 1, + RUNNING = 2, + PARKING = 3, + PARKED = 4, + PINNED = 5, + TIMED_PARKING = 6, + TIMED_PARKED = 7, + TIMED_PINNED = 8, + UNPARKED = 9, + YIELDING = 10, + YIELDED = 11, + TERMINATED = 99, + + // additional state bits + SUSPENDED = 1 << 8, // suspended when unmounted }; static void compute_offsets(); diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp index f4e7c620862..48db2fd8715 100644 --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp @@ -138,9 +138,9 @@ void JfrStackFrame::write(JfrCheckpointWriter& cpw) const { class JfrVframeStream : public vframeStreamCommon { private: + bool _vthread; const ContinuationEntry* _cont_entry; bool _async_mode; - bool _vthread; bool step_to_sender(); void next_frame(); public: @@ -165,8 +165,9 @@ JfrVframeStream::JfrVframeStream(JavaThread* jt, const frame& fr, bool stop_at_j RegisterMap::UpdateMap::skip, RegisterMap::ProcessFrames::skip, walk_continuation(jt))), - _cont_entry(JfrThreadLocal::is_vthread(jt) ? jt->last_continuation() : nullptr), - _async_mode(async_mode), _vthread(JfrThreadLocal::is_vthread(jt)) { + _vthread(JfrThreadLocal::is_vthread(jt)), + _cont_entry(_vthread ? jt->last_continuation() : nullptr), + _async_mode(async_mode) { assert(!_vthread || _cont_entry != nullptr, "invariant"); _reg_map.set_async(async_mode); _frame = fr; diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp index 6e4e6644080..175ec98da44 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp @@ -395,11 +395,14 @@ traceid JfrThreadLocal::thread_id(const Thread* t) { return t->jfr_thread_local()->_thread_id_alias; } JfrThreadLocal* const tl = t->jfr_thread_local(); - if (!t->is_Java_thread() || !Atomic::load_acquire(&tl->_vthread)) { + if (!t->is_Java_thread()) { return jvm_thread_id(t, tl); } - // virtual thread const JavaThread* jt = JavaThread::cast(t); + if (!is_vthread(jt)) { + return jvm_thread_id(t, tl); + } + // virtual thread const traceid tid = vthread_id(jt); assert(tid != 0, "invariant"); if (!tl->is_vthread_excluded()) { @@ -456,7 +459,7 @@ traceid JfrThreadLocal::jvm_thread_id(const Thread* t) { bool JfrThreadLocal::is_vthread(const JavaThread* jt) { assert(jt != nullptr, "invariant"); - return Atomic::load_acquire(&jt->jfr_thread_local()->_vthread); + return Atomic::load_acquire(&jt->jfr_thread_local()->_vthread) && jt->last_continuation() != nullptr; } inline bool is_virtual(const JavaThread* jt, oop thread) { diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java index 37d092e2011..e8ac217aecf 100644 --- a/src/java.base/share/classes/java/lang/VirtualThread.java +++ b/src/java.base/share/classes/java/lang/VirtualThread.java @@ -86,41 +86,52 @@ final class VirtualThread extends BaseVirtualThread { private volatile int state; /* - * Virtual thread state and transitions: + * Virtual thread state transitions: * - * NEW -> STARTED // Thread.start + * NEW -> STARTED // Thread.start, schedule to run * STARTED -> TERMINATED // failed to start * STARTED -> RUNNING // first run + * RUNNING -> TERMINATED // done * - * RUNNING -> PARKING // Thread attempts to park - * PARKING -> PARKED // cont.yield successful, thread is parked - * PARKING -> PINNED // cont.yield failed, thread is pinned - * - * PARKED -> RUNNABLE // unpark or interrupted - * PINNED -> RUNNABLE // unpark or interrupted + * RUNNING -> PARKING // Thread parking with LockSupport.park + * PARKING -> PARKED // cont.yield successful, parked indefinitely + * PARKING -> PINNED // cont.yield failed, parked indefinitely on carrier + * PARKED -> UNPARKED // unparked, may be scheduled to continue + * PINNED -> RUNNING // unparked, continue execution on same carrier + * UNPARKED -> RUNNING // continue execution after park * - * RUNNABLE -> RUNNING // continue execution + * RUNNING -> TIMED_PARKING // Thread parking with LockSupport.parkNanos + * TIMED_PARKING -> TIMED_PARKED // cont.yield successful, timed-parked + * TIMED_PARKING -> TIMED_PINNED // cont.yield failed, timed-parked on carrier + * TIMED_PARKED -> UNPARKED // unparked, may be scheduled to continue + * TIMED_PINNED -> RUNNING // unparked, continue execution on same carrier * * RUNNING -> YIELDING // Thread.yield - * YIELDING -> RUNNABLE // yield successful - * YIELDING -> RUNNING // yield failed - * - * RUNNING -> TERMINATED // done + * YIELDING -> YIELDED // cont.yield successful, may be scheduled to continue + * YIELDING -> RUNNING // cont.yield failed + * YIELDED -> RUNNING // continue execution after Thread.yield */ private static final int NEW = 0; private static final int STARTED = 1; - private static final int RUNNABLE = 2; // runnable-unmounted - private static final int RUNNING = 3; // runnable-mounted - private static final int PARKING = 4; - private static final int PARKED = 5; // unmounted - private static final int PINNED = 6; // mounted - private static final int YIELDING = 7; // Thread.yield + private static final int RUNNING = 2; // runnable-mounted + + // untimed and timed parking + private static final int PARKING = 3; + private static final int PARKED = 4; // unmounted + private static final int PINNED = 5; // mounted + private static final int TIMED_PARKING = 6; + private static final int TIMED_PARKED = 7; // unmounted + private static final int TIMED_PINNED = 8; // mounted + private static final int UNPARKED = 9; // unmounted but runnable + + // Thread.yield + private static final int YIELDING = 10; + private static final int YIELDED = 11; // unmounted but runnable + private static final int TERMINATED = 99; // final state // can be suspended from scheduling when unmounted private static final int SUSPENDED = 1 << 8; - private static final int RUNNABLE_SUSPENDED = (RUNNABLE | SUSPENDED); - private static final int PARKED_SUSPENDED = (PARKED | SUSPENDED); // parking permit private volatile boolean parkPermit; @@ -194,8 +205,11 @@ public void run() { } /** - * Runs or continues execution of the continuation on the current thread. + * Runs or continues execution on the current thread. The virtual thread is mounted + * on the current thread before the task runs or continues. It unmounts when the + * task completes or yields. */ + @ChangesCurrentThread private void runContinuation() { // the carrier must be a platform thread if (Thread.currentThread().isVirtual()) { @@ -204,24 +218,27 @@ private void runContinuation() { // set state to RUNNING int initialState = state(); - if (initialState == STARTED && compareAndSetState(STARTED, RUNNING)) { - // first run - } else if (initialState == RUNNABLE && compareAndSetState(RUNNABLE, RUNNING)) { - // consume parking permit - setParkPermit(false); + if (initialState == STARTED || initialState == UNPARKED || initialState == YIELDED) { + // newly started or continue after parking/blocking/Thread.yield + if (!compareAndSetState(initialState, RUNNING)) { + return; + } + // consume parking permit when continuing after parking + if (initialState == UNPARKED) { + setParkPermit(false); + } } else { // not runnable return; } - // notify JVMTI before mount - notifyJvmtiMount(/*hide*/true); - + mount(); try { cont.run(); } finally { + unmount(); if (cont.isDone()) { - afterTerminate(); + afterDone(); } else { afterYield(); } @@ -231,8 +248,7 @@ private void runContinuation() { /** * Submits the runContinuation task to the scheduler. For the default scheduler, * and calling it on a worker thread, the task will be pushed to the local queue, - * otherwise it will be pushed to a submission queue. - * + * otherwise it will be pushed to an external submission queue. * @throws RejectedExecutionException */ private void submitRunContinuation() { @@ -245,7 +261,7 @@ private void submitRunContinuation() { } /** - * Submits the runContinuation task to the scheduler with a lazy submit. + * Submits the runContinuation task to given scheduler with a lazy submit. * @throws RejectedExecutionException * @see ForkJoinPool#lazySubmit(ForkJoinTask) */ @@ -259,7 +275,7 @@ private void lazySubmitRunContinuation(ForkJoinPool pool) { } /** - * Submits the runContinuation task to the scheduler as an external submit. + * Submits the runContinuation task to the given scheduler as an external submit. * @throws RejectedExecutionException * @see ForkJoinPool#externalSubmit(ForkJoinTask) */ @@ -285,16 +301,12 @@ private void submitFailed(RejectedExecutionException ree) { } /** - * Runs a task in the context of this virtual thread. The virtual thread is - * mounted on the current (carrier) thread before the task runs. It unmounts - * from its carrier thread when the task completes. + * Runs a task in the context of this virtual thread. */ - @ChangesCurrentThread private void run(Runnable task) { - assert state == RUNNING; + assert Thread.currentThread() == this && state == RUNNING; - // first mount - mount(); + // notify JVMTI, may post VirtualThreadStart event notifyJvmtiStart(); // emit JFR event if enabled @@ -322,12 +334,8 @@ private void run(Runnable task) { } } finally { - // last unmount + // notify JVMTI, may post VirtualThreadEnd event notifyJvmtiEnd(); - unmount(); - - // final state - setState(TERMINATED); } } } @@ -339,6 +347,9 @@ private void run(Runnable task) { @ChangesCurrentThread @ReservedStackAccess private void mount() { + // notify JVMTI before mount + notifyJvmtiMount(/*hide*/true); + // sets the carrier thread Thread carrier = Thread.currentCarrierThread(); setCarrierThread(carrier); @@ -375,6 +386,9 @@ private void unmount() { setCarrierThread(null); } carrier.clearInterrupt(); + + // notify JVMTI after unmount + notifyJvmtiUnmount(/*hide*/false); } /** @@ -417,21 +431,15 @@ V executeOnCarrierThread(Callable task) throws Exception { } /** - * Unmounts this virtual thread, invokes Continuation.yield, and re-mounts the - * thread when continued. When enabled, JVMTI must be notified from this method. - * @return true if the yield was successful + * Invokes Continuation.yield, notifying JVMTI (if enabled) to hide frames until + * the continuation continues. */ @Hidden - @ChangesCurrentThread private boolean yieldContinuation() { - // unmount notifyJvmtiUnmount(/*hide*/true); - unmount(); try { return Continuation.yield(VTHREAD_SCOPE); } finally { - // re-mount - mount(); notifyJvmtiMount(/*hide*/false); } } @@ -442,17 +450,17 @@ private boolean yieldContinuation() { * If yielding due to Thread.yield then it just submits the task to continue. */ private void afterYield() { - int s = state(); - assert (s == PARKING || s == YIELDING) && (carrierThread == null); + assert carrierThread == null; - if (s == PARKING) { - setState(PARKED); + int s = state(); - // notify JVMTI that unmount has completed, thread is parked - notifyJvmtiUnmount(/*hide*/false); + // LockSupport.park/parkNanos + if (s == PARKING || s == TIMED_PARKING) { + int newState = (s == PARKING) ? PARKED : TIMED_PARKED; + setState(newState); // may have been unparked while parking - if (parkPermit && compareAndSetState(PARKED, RUNNABLE)) { + if (parkPermit && compareAndSetState(newState, UNPARKED)) { // lazy submit to continue on the current thread as carrier if possible if (currentThread() instanceof CarrierThread ct) { lazySubmitRunContinuation(ct.getPool()); @@ -461,11 +469,12 @@ private void afterYield() { } } - } else if (s == YIELDING) { // Thread.yield - setState(RUNNABLE); + return; + } - // notify JVMTI that unmount has completed, thread is runnable - notifyJvmtiUnmount(/*hide*/false); + // Thread.yield + if (s == YIELDING) { + setState(YIELDED); // external submit if there are no tasks in the local task queue if (currentThread() instanceof CarrierThread ct && ct.getQueuedTaskCount() == 0) { @@ -473,30 +482,28 @@ private void afterYield() { } else { submitRunContinuation(); } + return; } + + assert false; } /** - * Invoked after the thread terminates execution. It notifies anyone - * waiting for the thread to terminate. + * Invoked after the continuation completes. */ - private void afterTerminate() { - afterTerminate(true, true); + private void afterDone() { + afterDone(true); } /** - * Invoked after the thread terminates (or start failed). This method - * notifies anyone waiting for the thread to terminate. + * Invoked after the continuation completes (or start failed). Sets the thread + * state to TERMINATED and notifies anyone waiting for the thread to terminate. * * @param notifyContainer true if its container should be notified - * @param executed true if the thread executed, false if it failed to start */ - private void afterTerminate(boolean notifyContainer, boolean executed) { - assert (state() == TERMINATED) && (carrierThread == null); - - if (executed) { - notifyJvmtiUnmount(/*hide*/false); - } + private void afterDone(boolean notifyContainer) { + assert carrierThread == null; + setState(TERMINATED); // notify anyone waiting for this virtual thread to terminate CountDownLatch termination = this.termination; @@ -546,8 +553,7 @@ void start(ThreadContainer container) { started = true; } finally { if (!started) { - setState(TERMINATED); - afterTerminate(addedToContainer, /*executed*/false); + afterDone(addedToContainer); } } } @@ -615,14 +621,14 @@ void parkNanos(long nanos) { long startTime = System.nanoTime(); boolean yielded = false; - Future unparker = scheduleUnpark(this::unpark, nanos); - setState(PARKING); + Future unparker = scheduleUnpark(nanos); // may throw OOME + setState(TIMED_PARKING); try { yielded = yieldContinuation(); // may throw } finally { assert (Thread.currentThread() == this) && (yielded == (state() == RUNNING)); if (!yielded) { - assert state() == PARKING; + assert state() == TIMED_PARKING; setState(RUNNING); } cancel(unparker); @@ -654,7 +660,7 @@ private void parkOnCarrierThread(boolean timed, long nanos) { event = null; } - setState(PINNED); + setState(timed ? TIMED_PINNED : PINNED); try { if (!parkPermit) { if (!timed) { @@ -680,14 +686,15 @@ private void parkOnCarrierThread(boolean timed, long nanos) { } /** - * Schedule an unpark task to run after a given delay. + * Schedule this virtual thread to be unparked after a given delay. */ @ChangesCurrentThread - private Future scheduleUnpark(Runnable unparker, long nanos) { + private Future scheduleUnpark(long nanos) { + assert Thread.currentThread() == this; // need to switch to current carrier thread to avoid nested parking switchToCarrierThread(); try { - return UNPARKER.schedule(unparker, nanos, NANOSECONDS); + return UNPARKER.schedule(this::unpark, nanos, NANOSECONDS); } finally { switchToVirtualThread(this); } @@ -722,7 +729,8 @@ void unpark() { Thread currentThread = Thread.currentThread(); if (!getAndSetParkPermit(true) && currentThread != this) { int s = state(); - if (s == PARKED && compareAndSetState(PARKED, RUNNABLE)) { + boolean parked = (s == PARKED) || (s == TIMED_PARKED); + if (parked && compareAndSetState(s, UNPARKED)) { if (currentThread instanceof VirtualThread vthread) { vthread.switchToCarrierThread(); try { @@ -733,11 +741,11 @@ void unpark() { } else { submitRunContinuation(); } - } else if (s == PINNED) { - // unpark carrier thread when pinned. + } else if ((s == PINNED) || (s == TIMED_PINNED)) { + // unpark carrier thread when pinned synchronized (carrierThreadAccessLock()) { Thread carrier = carrierThread; - if (carrier != null && state() == PINNED) { + if (carrier != null && ((s = state()) == PINNED || s == TIMED_PINNED)) { U.unpark(carrier); } } @@ -874,7 +882,8 @@ boolean getAndClearInterrupt() { @Override Thread.State threadState() { - switch (state()) { + int s = state(); + switch (s & ~SUSPENDED) { case NEW: return Thread.State.NEW; case STARTED: @@ -884,8 +893,8 @@ Thread.State threadState() { } else { return Thread.State.RUNNABLE; } - case RUNNABLE: - case RUNNABLE_SUSPENDED: + case UNPARKED: + case YIELDED: // runnable, not mounted return Thread.State.RUNNABLE; case RUNNING: @@ -899,13 +908,16 @@ Thread.State threadState() { // runnable, mounted return Thread.State.RUNNABLE; case PARKING: + case TIMED_PARKING: case YIELDING: - // runnable, mounted, not yet waiting + // runnable, in transition return Thread.State.RUNNABLE; case PARKED: - case PARKED_SUSPENDED: case PINNED: - return Thread.State.WAITING; + return State.WAITING; + case TIMED_PARKED: + case TIMED_PINNED: + return State.TIMED_WAITING; case TERMINATED: return Thread.State.TERMINATED; default: @@ -940,35 +952,58 @@ StackTraceElement[] asyncGetStackTrace() { /** * Returns the stack trace for this virtual thread if it is unmounted. - * Returns null if the thread is in another state. + * Returns null if the thread is mounted or in transition. */ private StackTraceElement[] tryGetStackTrace() { - int initialState = state(); - return switch (initialState) { - case RUNNABLE, PARKED -> { - int suspendedState = initialState | SUSPENDED; - if (compareAndSetState(initialState, suspendedState)) { - try { - yield cont.getStackTrace(); - } finally { - assert state == suspendedState; - setState(initialState); - - // re-submit if runnable - // re-submit if unparked while suspended - if (initialState == RUNNABLE - || (parkPermit && compareAndSetState(PARKED, RUNNABLE))) { - try { - submitRunContinuation(); - } catch (RejectedExecutionException ignore) { } - } - } - } - yield null; + int initialState = state() & ~SUSPENDED; + switch (initialState) { + case NEW, STARTED, TERMINATED -> { + return new StackTraceElement[0]; // unmounted, empty stack + } + case RUNNING, PINNED, TIMED_PINNED -> { + return null; // mounted + } + case PARKED, TIMED_PARKED -> { + // unmounted, not runnable } - case NEW, STARTED, TERMINATED -> new StackTraceElement[0]; // empty stack - default -> null; + case UNPARKED, YIELDED -> { + // unmounted, runnable + } + case PARKING, TIMED_PARKING, YIELDING -> { + return null; // in transition + } + default -> throw new InternalError("" + initialState); + } + + // thread is unmounted, prevent it from continuing + int suspendedState = initialState | SUSPENDED; + if (!compareAndSetState(initialState, suspendedState)) { + return null; + } + + // get stack trace and restore state + StackTraceElement[] stack; + try { + stack = cont.getStackTrace(); + } finally { + assert state == suspendedState; + setState(initialState); + } + boolean resubmit = switch (initialState) { + case UNPARKED, YIELDED -> { + // resubmit as task may have run while suspended + yield true; + } + case PARKED, TIMED_PARKED -> { + // resubmit if unparked while suspended + yield parkPermit && compareAndSetState(initialState, UNPARKED); + } + default -> throw new InternalError(); }; + if (resubmit) { + submitRunContinuation(); + } + return stack; } @Override diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java new file mode 100644 index 00000000000..17c17b9b1f5 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id=default + * @bug 8312498 + * @summary Basic test for JVMTI GetThreadState with virtual threads + * @run junit/othervm/native GetThreadStateTest + */ + +/* + * @test id=no-vmcontinuations + * @requires vm.continuations + * @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest + */ + +import java.util.StringJoiner; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.LockSupport; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class GetThreadStateTest { + + @BeforeAll + static void setup() { + System.loadLibrary("GetThreadStateTest"); + init(); + } + + /** + * Test state of new/unstarted thread. + */ + @Test + void testUnstarted() { + var thread = Thread.ofVirtual().unstarted(() -> { }); + check(thread, /*new*/ 0); + } + + /** + * Test state of terminated thread. + */ + @Test + void testTerminated() throws Exception { + var thread = Thread.ofVirtual().start(() -> { }); + thread.join(); + check(thread, JVMTI_THREAD_STATE_TERMINATED); + } + + /** + * Test state of runnable thread. + */ + @Test + void testRunnable() throws Exception { + var latch = new CountDownLatch(1); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + latch.countDown(); + + // spin until done + while (!done.get()) { + Thread.onSpinWait(); + } + }); + try { + // wait for thread to start execution + latch.await(); + + // thread should be runnable + int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE; + check(thread, expected); + + // re-test with interrupt status set + thread.interrupt(); + check(thread, expected | JVMTI_THREAD_STATE_INTERRUPTED); + } finally { + done.set(true); + thread.join(); + } + } + + /** + * Test state of thread waiting to enter a monitor. + */ + @Test + void testMonitorEnter() throws Exception { + var latch = new CountDownLatch(1); + Object lock = new Object(); + var thread = Thread.ofVirtual().unstarted(() -> { + latch.countDown(); + synchronized (lock) { } + }); + try { + synchronized (lock) { + // start thread and wait for it to start execution + thread.start(); + latch.await(); + + // thread should block on monitor enter + int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + await(thread, expected); + + // re-test with interrupt status set + thread.interrupt(); + check(thread, expected | JVMTI_THREAD_STATE_INTERRUPTED); + } + } finally { + thread.join(); + } + } + + /** + * Test state of thread waiting in Object.wait(). + */ + @Test + void testObjectWait() throws Exception { + var latch = new CountDownLatch(1); + Object lock = new Object(); + var thread = Thread.ofVirtual().start(() -> { + synchronized (lock) { + latch.countDown(); + try { + lock.wait(); + } catch (InterruptedException e) { } + } + }); + try { + // wait for thread to own monitor + latch.await(); + + // thread should wait + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_INDEFINITELY | + JVMTI_THREAD_STATE_IN_OBJECT_WAIT; + await(thread, expected); + + // notify so thread waits to re-enter monitor + synchronized (lock) { + lock.notifyAll(); + expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + check(thread, expected); + + // re-test with interrupt status set + thread.interrupt(); + check(thread, expected | JVMTI_THREAD_STATE_INTERRUPTED); + } + } finally { + thread.interrupt(); + thread.join(); + } + } + + /** + * Test state of thread waiting in Object.wait(millis). + */ + @Test + void testObjectWaitMillis() throws Exception { + var latch = new CountDownLatch(1); + Object lock = new Object(); + var thread = Thread.ofVirtual().start(() -> { + synchronized (lock) { + latch.countDown(); + try { + lock.wait(Long.MAX_VALUE); + } catch (InterruptedException e) { } + } + }); + try { + // wait for thread to own monitor + latch.await(); + + // thread should wait + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | + JVMTI_THREAD_STATE_IN_OBJECT_WAIT; + await(thread, expected); + + // notify so thread waits to re-enter monitor + synchronized (lock) { + lock.notifyAll(); + expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + check(thread, expected); + + // re-test with interrupt status set + thread.interrupt(); + check(thread, expected | JVMTI_THREAD_STATE_INTERRUPTED); + } + } finally { + thread.interrupt(); + thread.join(); + } + } + + /** + * Test state of thread parked with LockSupport.park. + */ + @Test + void testPark() throws Exception { + var latch = new CountDownLatch(1); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + latch.countDown(); + while (!done.get()) { + LockSupport.park(); + } + }); + try { + // wait for thread to start execution + latch.await(); + + // thread should park + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_INDEFINITELY | + JVMTI_THREAD_STATE_PARKED; + await(thread, expected); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test state of thread parked with LockSupport.parkNanos. + */ + @Test + void testParkNanos() throws Exception { + var latch = new CountDownLatch(1); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + latch.countDown(); + while (!done.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + }); + try { + // wait for thread to start execution + latch.await(); + + // thread should park + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | + JVMTI_THREAD_STATE_PARKED; + await(thread, expected); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test state of thread parked with LockSupport.park while holding a monitor. + */ + @Test + void testParkWhenPinned() throws Exception { + var latch = new CountDownLatch(1); + Object lock = new Object(); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + synchronized (lock) { + latch.countDown(); + while (!done.get()) { + LockSupport.park(); + } + } + }); + try { + // wait for thread to own monitor + latch.await(); + + // thread should park + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_INDEFINITELY | + JVMTI_THREAD_STATE_PARKED; + await(thread, expected); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test state of thread parked with LockSupport.parkNanos while holding a monitor. + */ + @Test + void testParkNanosWhenPinned() throws Exception { + var latch = new CountDownLatch(1); + Object lock = new Object(); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + synchronized (lock) { + latch.countDown(); + while (!done.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + } + }); + try { + // wait for thread to own monitor + latch.await(); + + // thread should park + int expected = JVMTI_THREAD_STATE_ALIVE | + JVMTI_THREAD_STATE_WAITING | + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | + JVMTI_THREAD_STATE_PARKED; + await(thread, expected); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Asserts that the given thread has the expected JVMTI state. + */ + private static void check(Thread thread, int expected) { + System.err.format(" expect state=0x%x (%s) ...%n", expected, jvmtiStateToString(expected)); + int state = jvmtiState(thread); + System.err.format(" thread state=0x%x (%s)%n", state, jvmtiStateToString(state)); + assertEquals(expected, state); + } + + /** + * Waits indefinitely for the given thread to get to the target JVMTI state. + */ + private static void await(Thread thread, int targetState) throws Exception { + System.err.format(" await state=0x%x (%s) ...%n", targetState, jvmtiStateToString(targetState)); + int state = jvmtiState(thread); + System.err.format(" thread state=0x%x (%s)%n", state, jvmtiStateToString(state)); + while (state != targetState) { + assertTrue(thread.isAlive(), "Thread has terminated"); + Thread.sleep(20); + state = jvmtiState(thread); + System.err.format(" thread state=0x%x (%s)%n", state, jvmtiStateToString(state)); + } + } + + private static final int JVMTI_THREAD_STATE_ALIVE = 0x0001; + private static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002; + private static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004; + private static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400; + private static final int JVMTI_THREAD_STATE_WAITING = 0x0080; + private static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010; + private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; + private static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040; + private static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100; + private static final int JVMTI_THREAD_STATE_PARKED = 0x0200; + private static final int JVMTI_THREAD_STATE_SUSPENDED = 0x100000; + private static final int JVMTI_THREAD_STATE_INTERRUPTED = 0x200000; + private static final int JVMTI_THREAD_STATE_IN_NATIVE = 0x400000; + + private static native void init(); + private static native int jvmtiState(Thread thread); + + private static String jvmtiStateToString(int state) { + StringJoiner sj = new StringJoiner(" | "); + if ((state & JVMTI_THREAD_STATE_ALIVE) != 0) + sj.add("JVMTI_THREAD_STATE_ALIVE"); + if ((state & JVMTI_THREAD_STATE_TERMINATED) != 0) + sj.add("JVMTI_THREAD_STATE_TERMINATED"); + if ((state & JVMTI_THREAD_STATE_RUNNABLE) != 0) + sj.add("JVMTI_THREAD_STATE_RUNNABLE"); + if ((state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) + sj.add("JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER"); + if ((state & JVMTI_THREAD_STATE_WAITING) != 0) + sj.add("JVMTI_THREAD_STATE_WAITING"); + if ((state & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) + sj.add("JVMTI_THREAD_STATE_WAITING_INDEFINITELY"); + if ((state & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) + sj.add("JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT"); + if ((state & JVMTI_THREAD_STATE_IN_OBJECT_WAIT) != 0) + sj.add("JVMTI_THREAD_STATE_IN_OBJECT_WAIT"); + if ((state & JVMTI_THREAD_STATE_PARKED) != 0) + sj.add("JVMTI_THREAD_STATE_PARKED"); + if ((state & JVMTI_THREAD_STATE_SUSPENDED) != 0) + sj.add("JVMTI_THREAD_STATE_SUSPENDED"); + if ((state & JVMTI_THREAD_STATE_INTERRUPTED) != 0) + sj.add("JVMTI_THREAD_STATE_INTERRUPTED"); + if ((state & JVMTI_THREAD_STATE_IN_NATIVE) != 0) + sj.add("JVMTI_THREAD_STATE_IN_NATIVE"); + String s = sj.toString(); + return s.isEmpty() ? "" : s; + } +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/libGetThreadStateTest.c b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/libGetThreadStateTest.c new file mode 100644 index 00000000000..532225670f5 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/libGetThreadStateTest.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, 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. + */ + +#include "jni.h" +#include "jvmti.h" + +static jvmtiEnv *jvmti; + +JNIEXPORT void JNICALL Java_GetThreadStateTest_init(JNIEnv *env, jclass clazz) { + JavaVM* vm; + jint res; + res = (*env)->GetJavaVM(env, &vm); + if (res != 0) { + (*env)->FatalError(env, "GetJavaVM failed"); + } else { + res = (*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION); + if (res != JNI_OK) { + (*env)->FatalError(env, "GetEnv failed"); + } + } +} + +JNIEXPORT jint JNICALL Java_GetThreadStateTest_jvmtiState(JNIEnv *env, jclass clazz, jobject thread) { + jvmtiError err; + jint state = 0; + err = (*jvmti)->GetThreadState(jvmti, thread, &state); + if (err != JVMTI_ERROR_NONE) { + (*env)->FatalError(env, "GetThreadState failed"); + } + return state; +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java index 554e83c231c..61b94a4484b 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/VThreadEventTest/VThreadEventTest.java @@ -149,12 +149,12 @@ public static void main(String[] args) throws Exception { } await(ready0); mready.countDown(); - await(ready1); // to guaranty state is not State.WAITING after await(mready) in test1() - // wait for test1 threads to reach WAITING state in sleep() + await(ready1); // to guarantee state is not State.TIMED_WAITING after await(mready) in test1() + // wait for test1 threads to reach TIMED_WAITING state in sleep() for (Thread t : test1Threads) { Thread.State state = t.getState(); log("DBG: state: " + state); - while (state != Thread.State.WAITING) { + while (state != Thread.State.TIMED_WAITING) { Thread.sleep(10); state = t.getState(); log("DBG: state: " + state); diff --git a/test/jdk/java/lang/Thread/virtual/CustomScheduler.java b/test/jdk/java/lang/Thread/virtual/CustomScheduler.java index 6d4e029f280..5bde81905ec 100644 --- a/test/jdk/java/lang/Thread/virtual/CustomScheduler.java +++ b/test/jdk/java/lang/Thread/virtual/CustomScheduler.java @@ -45,7 +45,6 @@ import static org.junit.jupiter.api.Assumptions.*; class CustomScheduler { - private static final Executor DEFAULT_SCHEDULER = defaultScheduler(); private static ExecutorService scheduler1; private static ExecutorService scheduler2; @@ -216,20 +215,6 @@ void testRunWithInterruptSet() throws Exception { } } - /** - * Returns the default scheduler. - */ - private static Executor defaultScheduler() { - try { - Field defaultScheduler = Class.forName("java.lang.VirtualThread") - .getDeclaredField("DEFAULT_SCHEDULER"); - defaultScheduler.setAccessible(true); - return (Executor) defaultScheduler.get(null); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - /** * Returns the scheduler for the given virtual thread. */ diff --git a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java index 8afb472d3f4..663da9126d6 100644 --- a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java +++ b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java @@ -23,7 +23,7 @@ /* * @test id=default - * @bug 8284161 8286788 + * @bug 8284161 8286788 8321270 * @summary Test Thread API with virtual threads * @modules java.base/java.lang:+open * @library /test/lib @@ -106,7 +106,7 @@ void testCurrentThread1() throws Exception { LockSupport.park(); after.set(Thread.currentThread()); }); - awaitParked(thread); + await(thread, Thread.State.WAITING); LockSupport.unpark(thread); thread.join(); assertTrue(before.get() == thread); @@ -130,7 +130,7 @@ void testCurrentThread2() throws Exception { }); synchronized (lock) { thread.start(); - awaitBlocked(thread); + await(thread, Thread.State.BLOCKED); } thread.join(); assertTrue(ref1.get() == thread); @@ -160,7 +160,7 @@ void testCurrentThread3() throws Exception { lock.lock(); try { thread.start(); - awaitParked(thread); + await(thread, Thread.State.WAITING); } finally { lock.unlock(); } @@ -765,6 +765,7 @@ void testJoin33() throws Exception { assertFalse(thread.join(Duration.ofMillis(100))); } finally { done.set(true); + thread.join(); } } @@ -897,7 +898,7 @@ void testInterrupt6() throws Exception { exception.set(e); } }); - awaitParked(thread); + await(thread, Thread.State.TIMED_WAITING); thread.interrupt(); thread.join(); assertNull(exception.get()); @@ -917,7 +918,7 @@ void testInterrupt7() throws Exception { exception.set(e); } }); - awaitParked(thread); + await(thread, Thread.State.WAITING); thread.interrupt(); thread.join(); assertNull(exception.get()); @@ -1032,16 +1033,16 @@ void testSetName3() throws Exception { void testSetPriority1() throws Exception { VThreadRunner.run(() -> { Thread me = Thread.currentThread(); - assertTrue(me.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, me.getPriority()); me.setPriority(Thread.MAX_PRIORITY); - assertTrue(me.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, me.getPriority()); me.setPriority(Thread.NORM_PRIORITY); - assertTrue(me.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, me.getPriority()); me.setPriority(Thread.MIN_PRIORITY); - assertTrue(me.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, me.getPriority()); assertThrows(IllegalArgumentException.class, () -> me.setPriority(-1)); }); @@ -1055,33 +1056,33 @@ void testSetPriority2() throws Exception { var thread = Thread.ofVirtual().unstarted(LockSupport::park); // not started - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.MAX_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.NORM_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.MIN_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); assertThrows(IllegalArgumentException.class, () -> thread.setPriority(-1)); // running thread.start(); try { - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.NORM_PRIORITY); thread.setPriority(Thread.MAX_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.NORM_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); thread.setPriority(Thread.MIN_PRIORITY); - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); assertThrows(IllegalArgumentException.class, () -> thread.setPriority(-1)); @@ -1091,7 +1092,7 @@ void testSetPriority2() throws Exception { thread.join(); // terminated - assertTrue(thread.getPriority() == Thread.NORM_PRIORITY); + assertEquals(Thread.NORM_PRIORITY, thread.getPriority()); } /** @@ -1190,6 +1191,36 @@ void testYield2() throws Exception { assertEquals(List.of("A", "A", "B"), list); } + /** + * Test that Thread.yield does not consume the thread's parking permit. + */ + @Test + void testYield3() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + LockSupport.unpark(Thread.currentThread()); + Thread.yield(); + LockSupport.park(); // should not park + }); + thread.join(); + } + + /** + * Test that Thread.yield does not make available the thread's parking permit. + */ + @Test + void testYield4() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + Thread.yield(); + LockSupport.park(); // should park + }); + try { + await(thread, Thread.State.WAITING); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + /** * Test Thread.onSpinWait. */ @@ -1650,53 +1681,79 @@ void testThreadId2() throws Exception { } /** - * Test Thread::getState when thread is not started. + * Test Thread::getState when thread is new/unstarted. */ @Test void testGetState1() { var thread = Thread.ofVirtual().unstarted(() -> { }); - assertTrue(thread.getState() == Thread.State.NEW); + assertEquals(Thread.State.NEW, thread.getState()); } /** - * Test Thread::getState when thread is runnable (mounted). + * Test Thread::getState when thread is terminated. */ @Test void testGetState2() throws Exception { - VThreadRunner.run(() -> { - Thread.State state = Thread.currentThread().getState(); - assertTrue(state == Thread.State.RUNNABLE); + var thread = Thread.ofVirtual().start(() -> { }); + thread.join(); + assertEquals(Thread.State.TERMINATED, thread.getState()); + } + + /** + * Test Thread::getState when thread is runnable (mounted). + */ + @Test + void testGetState3() throws Exception { + var started = new CountDownLatch(1); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + started.countDown(); + + // spin until done + while (!done.get()) { + Thread.onSpinWait(); + } }); + try { + // wait for thread to start + started.await(); + + // thread should be runnable + assertEquals(Thread.State.RUNNABLE, thread.getState()); + } finally { + done.set(true); + thread.join(); + } } /** * Test Thread::getState when thread is runnable (not mounted). */ @Test - void testGetState3() throws Exception { + void testGetState4() throws Exception { assumeTrue(ThreadBuilders.supportsCustomScheduler(), "No support for custom schedulers"); AtomicBoolean completed = new AtomicBoolean(); try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) { Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler); Thread t1 = builder.start(() -> { Thread t2 = builder.unstarted(LockSupport::park); - assertTrue(t2.getState() == Thread.State.NEW); + assertEquals(Thread.State.NEW, t2.getState()); // start t2 to make it runnable t2.start(); try { - assertTrue(t2.getState() == Thread.State.RUNNABLE); + assertEquals(Thread.State.RUNNABLE, t2.getState()); // yield to allow t2 to run and park Thread.yield(); - assertTrue(t2.getState() == Thread.State.WAITING); + assertEquals(Thread.State.WAITING, t2.getState()); } finally { // unpark t2 to make it runnable again LockSupport.unpark(t2); } // t2 should be runnable (not mounted) - assertTrue(t2.getState() == Thread.State.RUNNABLE); + assertEquals(Thread.State.RUNNABLE, t2.getState()); completed.set(true); }); @@ -1706,77 +1763,147 @@ void testGetState3() throws Exception { } /** - * Test Thread::getState when thread is parked. + * Test Thread::getState when thread is waiting to enter a monitor. */ @Test - void testGetState4() throws Exception { - var thread = Thread.ofVirtual().start(LockSupport::park); - while (thread.getState() != Thread.State.WAITING) { - Thread.sleep(20); + void testGetState5() throws Exception { + var started = new CountDownLatch(1); + var thread = Thread.ofVirtual().unstarted(() -> { + started.countDown(); + synchronized (lock) { } + }); + synchronized (lock) { + thread.start(); + started.await(); + + // wait for thread to block + await(thread, Thread.State.BLOCKED); } - LockSupport.unpark(thread); thread.join(); } /** - * Test Thread::getState when thread is parked while holding a monitor. + * Test Thread::getState when thread is waiting in Object.wait. */ @Test - void testGetState5() throws Exception { + void testGetState6() throws Exception { var thread = Thread.ofVirtual().start(() -> { synchronized (lock) { - LockSupport.park(); + try { lock.wait(); } catch (InterruptedException e) { } } }); - while (thread.getState() != Thread.State.WAITING) { - Thread.sleep(20); + try { + // wait for thread to wait + await(thread, Thread.State.WAITING); + } finally { + thread.interrupt(); + thread.join(); } - LockSupport.unpark(thread); - thread.join(); } /** - * Test Thread::getState when thread is waiting for a monitor. + * Test Thread::getState when thread is waiting in Object.wait(millis). */ @Test - void testGetState6() throws Exception { - var thread = Thread.ofVirtual().unstarted(() -> { - synchronized (lock) { } - }); - synchronized (lock) { - thread.start(); - while (thread.getState() != Thread.State.BLOCKED) { - Thread.sleep(20); + void testGetState7() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + synchronized (lock) { + try { + lock.wait(Long.MAX_VALUE); + } catch (InterruptedException e) { } } + }); + try { + // wait for thread to wait + await(thread, Thread.State.TIMED_WAITING); + } finally { + thread.interrupt(); + thread.join(); } - thread.join(); } /** - * Test Thread::getState when thread is waiting in Object.wait. + * Test Thread::getState when thread is parked. */ @Test - void testGetState7() throws Exception { + void testGetState8() throws Exception { + var thread = Thread.ofVirtual().start(LockSupport::park); + try { + await(thread, Thread.State.WAITING); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getState when thread is timed parked. + */ + @Test + void testGetState9() throws Exception { + var thread = Thread.ofVirtual().start(() -> LockSupport.parkNanos(Long.MAX_VALUE)); + try { + await(thread, Thread.State.TIMED_WAITING); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getState when thread is parked while holding a monitor. + */ + @Test + void testGetState10() throws Exception { + var started = new CountDownLatch(1); + var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { + started.countDown(); synchronized (lock) { - try { lock.wait(); } catch (InterruptedException e) { } + while (!done.get()) { + LockSupport.park(); + } } }); - while (thread.getState() != Thread.State.WAITING) { - Thread.sleep(20); + try { + // wait for thread to start + started.await(); + + // wait for thread to park + await(thread, Thread.State.WAITING); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); } - thread.interrupt(); - thread.join(); } /** - * Test Thread::getState when thread is terminated. + * Test Thread::getState when thread is timed parked while holding a monitor. */ @Test - void testGetState8() throws Exception { - var thread = Thread.ofVirtual().start(() -> { }); - thread.join(); - assertTrue(thread.getState() == Thread.State.TERMINATED); + void testGetState11() throws Exception { + var started = new CountDownLatch(1); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + started.countDown(); + synchronized (lock) { + while (!done.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + } + }); + try { + // wait for thread to start + started.await(); + + // wait for thread to park + await(thread, Thread.State.TIMED_WAITING); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } } /** @@ -1899,9 +2026,7 @@ void testGetStackTrace4() throws Exception { } // wait for virtual thread to block in wait - while (vthread.getState() != Thread.State.WAITING) { - Thread.sleep(20); - } + await(vthread, Thread.State.WAITING); // get stack trace of both carrier and virtual thread StackTraceElement[] carrierStackTrace = carrier.getStackTrace(); @@ -1928,12 +2053,7 @@ void testGetStackTrace4() throws Exception { @Test void testGetStackTrace5() throws Exception { var thread = Thread.ofVirtual().start(LockSupport::park); - - // wait for thread to park - while (thread.getState() != Thread.State.WAITING) { - Thread.sleep(20); - } - + await(thread, Thread.State.WAITING); try { StackTraceElement[] stack = thread.getStackTrace(); assertTrue(contains(stack, "LockSupport.park")); @@ -1996,9 +2116,7 @@ void testGetAllStackTraces2() throws Exception { } // wait for virtual thread to block in wait - while (vthread.getState() != Thread.State.WAITING) { - Thread.sleep(20); - } + await(vthread, Thread.State.WAITING); // get all stack traces Map map = Thread.getAllStackTraces(); @@ -2034,7 +2152,7 @@ void testThreadGroup1() throws Exception { var vgroup = thread.getThreadGroup(); thread.start(); try { - assertTrue(thread.getThreadGroup() == vgroup); + assertEquals(vgroup, thread.getThreadGroup()); } finally { LockSupport.unpark(thread); thread.join(); @@ -2051,7 +2169,7 @@ void testThreadGroup2() throws Exception { ThreadGroup vgroup = Thread.currentThread().getThreadGroup(); Thread child = new Thread(() -> { }); ThreadGroup group = child.getThreadGroup(); - assertTrue(group == vgroup); + assertEquals(vgroup, group); }); } @@ -2068,19 +2186,19 @@ void testThreadGroup3() throws Exception { thread.join(); ThreadGroup vgroup = ref.get(); - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); ThreadGroup group = new ThreadGroup(vgroup, "group"); assertTrue(group.getParent() == vgroup); - assertTrue(group.getMaxPriority() == Thread.MAX_PRIORITY); + assertEquals(Thread.MAX_PRIORITY, group.getMaxPriority()); vgroup.setMaxPriority(Thread.MAX_PRIORITY - 1); - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); - assertTrue(group.getMaxPriority() == Thread.MAX_PRIORITY - 1); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); + assertEquals(Thread.MAX_PRIORITY - 1, group.getMaxPriority()); vgroup.setMaxPriority(Thread.MIN_PRIORITY); - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); - assertTrue(group.getMaxPriority() == Thread.MIN_PRIORITY); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); + assertEquals(Thread.MIN_PRIORITY, group.getMaxPriority()); } /** @@ -2091,20 +2209,19 @@ void testThreadGroup3() throws Exception { void testThreadGroup4() throws Exception { VThreadRunner.run(() -> { ThreadGroup vgroup = Thread.currentThread().getThreadGroup(); - - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); ThreadGroup group = new ThreadGroup("group"); - assertTrue(group.getParent() == vgroup); - assertTrue(group.getMaxPriority() == Thread.MAX_PRIORITY); + assertEquals(vgroup, group.getParent()); + assertEquals(Thread.MAX_PRIORITY, group.getMaxPriority()); vgroup.setMaxPriority(Thread.MAX_PRIORITY - 1); - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); - assertTrue(group.getMaxPriority() == Thread.MAX_PRIORITY - 1); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); + assertEquals(Thread.MAX_PRIORITY - 1, group.getMaxPriority()); vgroup.setMaxPriority(Thread.MIN_PRIORITY); - assertTrue(vgroup.getMaxPriority() == Thread.MAX_PRIORITY); - assertTrue(group.getMaxPriority() == Thread.MIN_PRIORITY); + assertEquals(Thread.MAX_PRIORITY, vgroup.getMaxPriority()); + assertEquals(Thread.MIN_PRIORITY, group.getMaxPriority()); }); } @@ -2208,9 +2325,7 @@ void testToString3() throws Exception { me.setName("fred"); LockSupport.park(); }); - while (thread.getState() != Thread.State.WAITING) { - Thread.sleep(10); - } + await(thread, Thread.State.WAITING); try { assertTrue(thread.toString().contains("fred")); } finally { @@ -2233,23 +2348,11 @@ void testToString4() throws Exception { } /** - * Waits for the given thread to park. - */ - static void awaitParked(Thread thread) throws InterruptedException { - Thread.State state = thread.getState(); - while (state != Thread.State.WAITING && state != Thread.State.TIMED_WAITING) { - assertTrue(state != Thread.State.TERMINATED, "Thread has terminated"); - Thread.sleep(10); - state = thread.getState(); - } - } - - /** - * Waits for the given thread to block waiting on a monitor. + * Waits for the given thread to reach a given state. */ - static void awaitBlocked(Thread thread) throws InterruptedException { + private void await(Thread thread, Thread.State expectedState) throws InterruptedException { Thread.State state = thread.getState(); - while (state != Thread.State.BLOCKED) { + while (state != expectedState) { assertTrue(state != Thread.State.TERMINATED, "Thread has terminated"); Thread.sleep(10); state = thread.getState(); diff --git a/test/jdk/java/lang/Thread/virtual/ThreadBuilders.java b/test/jdk/java/lang/Thread/virtual/ThreadBuilders.java index 9283bf99321..a6a5d6abdbc 100644 --- a/test/jdk/java/lang/Thread/virtual/ThreadBuilders.java +++ b/test/jdk/java/lang/Thread/virtual/ThreadBuilders.java @@ -51,7 +51,6 @@ private ThreadBuilders() { } * @throws UnsupportedOperationException if custom schedulers are not supported */ static Thread.Builder.OfVirtual virtualThreadBuilder(Executor scheduler) { - Thread.Builder.OfVirtual builder = Thread.ofVirtual(); try { return (Thread.Builder.OfVirtual) VTBUILDER_CTOR.newInstance(scheduler); } catch (InvocationTargetException e) { diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java new file mode 100644 index 00000000000..e00cf89fb8c --- /dev/null +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023, 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. + */ + +/* + * @test + * @bug 8322818 + * @summary Stress test Thread.getStackTrace on a virtual thread that is pinned + * @requires vm.debug != true + * @modules java.base/java.lang:+open + * @library /test/lib + * @run main/othervm GetStackTraceALotWhenPinned 500000 + */ + +/* + * @test + * @requires vm.debug == true + * @modules java.base/java.lang:+open + * @library /test/lib + * @run main/othervm/timeout=300 GetStackTraceALotWhenPinned 200000 + */ + +import java.time.Instant; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.LockSupport; +import jdk.test.lib.thread.VThreadRunner; + +public class GetStackTraceALotWhenPinned { + + public static void main(String[] args) throws Exception { + // need at least two carrier threads when main thread is a virtual thread + if (Thread.currentThread().isVirtual()) { + VThreadRunner.ensureParallelism(2); + } + + int iterations = Integer.parseInt(args[0]); + var barrier = new Barrier(2); + + // Start a virtual thread that loops doing Thread.yield and parking while pinned. + // This loop creates the conditions for the main thread to sample the stack trace + // as it transitions from being unmounted to parking while pinned. + var thread = Thread.startVirtualThread(() -> { + boolean timed = false; + for (int i = 0; i < iterations; i++) { + // wait for main thread to arrive + barrier.await(); + + Thread.yield(); + synchronized (GetStackTraceALotWhenPinned.class) { + if (timed) { + LockSupport.parkNanos(Long.MAX_VALUE); + } else { + LockSupport.park(); + } + } + timed = !timed; + } + }); + + long lastTimestamp = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + // wait for virtual thread to arrive + barrier.await(); + + thread.getStackTrace(); + LockSupport.unpark(thread); + + long currentTime = System.currentTimeMillis(); + if ((currentTime - lastTimestamp) > 500) { + System.out.format("%s %d remaining ...%n", Instant.now(), (iterations - i)); + lastTimestamp = currentTime; + } + } + } + + /** + * Alow threads wait for each other to reach a common barrier point. This class does + * not park threads that are waiting for the barrier to trip, instead it spins. This + * makes it suitable for tests that use LockSupport.park or Thread.yield. + */ + private static class Barrier { + private final int parties; + private final AtomicInteger count; + private volatile int generation; + + Barrier(int parties) { + this.parties = parties; + this.count = new AtomicInteger(parties); + } + + void await() { + int g = generation; + if (count.decrementAndGet() == 0) { + count.set(parties); + generation = g + 1; + } else { + while (generation == g) { + Thread.onSpinWait(); + } + } + } + + } +} diff --git a/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java b/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java new file mode 100644 index 00000000000..ccba3fe1b4d --- /dev/null +++ b/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Stress test parking and unparking + * @requires vm.debug != true + * @run main/othervm ParkALot 500000 + */ + +/* + * @test + * @requires vm.debug == true + * @run main/othervm ParkALot 100000 + */ + +import java.time.Instant; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.locks.LockSupport; + +public class ParkALot { + private static final int ITERATIONS = 1_000_000; + + public static void main(String[] args) { + int iterations; + if (args.length > 0) { + iterations = Integer.parseInt(args[0]); + } else { + iterations = ITERATIONS; + } + + int maxThreads = Math.clamp(Runtime.getRuntime().availableProcessors() / 2, 1, 4); + for (int nthreads = 1; nthreads <= maxThreads; nthreads++) { + System.out.format("%s %d thread(s) ...%n", Instant.now(), nthreads); + ThreadFactory factory = Thread.ofPlatform().factory(); + try (var executor = Executors.newThreadPerTaskExecutor(factory)) { + for (int i = 0; i < nthreads; i++) { + executor.submit(() -> parkALot(iterations)); + } + } + System.out.format("%s %d thread(s) done%n", Instant.now(), nthreads); + } + } + + /** + * Creates a virtual thread that alternates between untimed and timed parking. + * A platform thread spins unparking the virtual thread. + */ + private static void parkALot(int iterations) { + Thread vthread = Thread.ofVirtual().start(() -> { + int i = 0; + boolean timed = false; + while (i < iterations) { + if (timed) { + LockSupport.parkNanos(Long.MAX_VALUE); + timed = false; + } else { + LockSupport.park(); + timed = true; + } + i++; + } + }); + + Thread.State state; + while ((state = vthread.getState()) != Thread.State.TERMINATED) { + if (state == Thread.State.WAITING || state == Thread.State.TIMED_WAITING) { + LockSupport.unpark(vthread); + } else { + Thread.yield(); + } + } + } +} From 2d791b8b856f6c3794f5f36a68548b15e93474f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Van=C4=9Bk?= Date: Wed, 28 Feb 2024 17:50:25 +0000 Subject: [PATCH 008/298] 8323170: j2dbench is using outdated javac source/target to be able to build by itself Backport-of: b5df2f43147535b4d22c6451e3a65170159f76b7 --- src/demo/share/java2d/J2DBench/Makefile | 27 +++++++++++++++++++----- src/demo/share/java2d/J2DBench/README | 3 +++ src/demo/share/java2d/J2DBench/build.xml | 25 +++++++++++++++++++++- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/demo/share/java2d/J2DBench/Makefile b/src/demo/share/java2d/J2DBench/Makefile index 04b0818a2c3..edc4494e131 100644 --- a/src/demo/share/java2d/J2DBench/Makefile +++ b/src/demo/share/java2d/J2DBench/Makefile @@ -29,6 +29,23 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # + +ifndef SOURCE +export SOURCE := 7 +endif +ifndef TARGET +export TARGET := 7 +endif +ifndef JAVAC +export JAVAC := javac +endif +ifndef JAVA +export JAVA := java +endif +ifndef JAR +export JAR := jar +endif + SOURCEPATH=src CLASSES=build DIST=dist @@ -80,18 +97,18 @@ SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files all: mkdirs J2DBench.jar J2DAnalyzer.jar run: mkdirs J2DBench.jar - java -jar $(DIST)/J2DBench.jar + $(JAVA) -jar $(DIST)/J2DBench.jar analyze: mkdirs J2DAnalyzer.jar - java -jar $(DIST)/J2DAnalyzer.jar + $(JAVA) -jar $(DIST)/J2DAnalyzer.jar J2DBench.jar: \ $(J2DBENCH_CLASSES) $(J2DBENCH_RESOURCES) \ $(CLASSES)/j2dbench.manifest - jar cvmf $(CLASSES)/j2dbench.manifest $(DIST)/J2DBench.jar -C $(CLASSES) j2dbench + $(JAR) cvmf $(CLASSES)/j2dbench.manifest $(DIST)/J2DBench.jar -C $(CLASSES) j2dbench J2DAnalyzer.jar: $(J2DANALYZER_CLASSES) $(CLASSES)/j2danalyzer.manifest - jar cvmf $(CLASSES)/j2danalyzer.manifest \ + $(JAR) cvmf $(CLASSES)/j2danalyzer.manifest \ $(DIST)/J2DAnalyzer.jar -C $(CLASSES) j2dbench/report $(CLASSES)/j2dbench/tests/iio/images: $(RESOURCES)/images @@ -120,7 +137,7 @@ $(CLASSES): mkdirs: $(DIST) $(CLASSES) $(CLASSES)/j2dbench/%.class: $(SOURCEPATH)/j2dbench/%.java - javac -g:none -source 1.7 -target 1.7 -d $(CLASSES) -sourcepath $(SOURCEPATH) $< + $(JAVAC) -g:none -source $(SOURCE) -target $(TARGET) -d $(CLASSES) -sourcepath $(SOURCEPATH) $< clean: rm -rf $(CLASSES) diff --git a/src/demo/share/java2d/J2DBench/README b/src/demo/share/java2d/J2DBench/README index 3b9f25c13f1..513c984a655 100644 --- a/src/demo/share/java2d/J2DBench/README +++ b/src/demo/share/java2d/J2DBench/README @@ -23,6 +23,9 @@ The benchmark requires at least jdk1.4 to compile and run. Note that source/target is set to 1.7 in the makefile and build.xml, because of support in jdk 14 compiler. To check compatibility with jdk1.4 you can use "-source 1.4 -target 1.4" options and jdk1.7. +Yo can use TARGET/SOURCE of makefile and -Dtarget/surce to set them up for your convinience. +Similarly you can set JAVA/JAVAC/JAR and -Djava/javac to select diffferent java/javac then is on yoru PATH +Unluckily in ant, you can not set jar, but ant should honor JAVA_HOME ----------------------------------------------------------------------- How To Compile diff --git a/src/demo/share/java2d/J2DBench/build.xml b/src/demo/share/java2d/J2DBench/build.xml index 7b202946cf1..415c315899e 100644 --- a/src/demo/share/java2d/J2DBench/build.xml +++ b/src/demo/share/java2d/J2DBench/build.xml @@ -39,6 +39,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -49,13 +70,14 @@ - + @@ -64,6 +86,7 @@ description="run J2DAnalyzer" > From 76ebcc19d7d4a3eb42aa9b6bbaa169652b94b157 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 29 Feb 2024 09:24:54 +0000 Subject: [PATCH 009/298] 8322846: Running with -Djdk.tracePinnedThreads set can hang Backport-of: faa9c6909dda635eb008b9dada6e06fca47c17d6 --- .../java/lang/PinnedThreadPrinter.java | 65 ++++++++++------- .../classes/java/lang/VirtualThread.java | 10 ++- .../Thread/virtual/TracePinnedThreads.java | 69 +++++++++++++++++-- 3 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/java.base/share/classes/java/lang/PinnedThreadPrinter.java b/src/java.base/share/classes/java/lang/PinnedThreadPrinter.java index 02e0683a1b9..a9b40d028f5 100644 --- a/src/java.base/share/classes/java/lang/PinnedThreadPrinter.java +++ b/src/java.base/share/classes/java/lang/PinnedThreadPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -34,6 +34,10 @@ import java.util.Set; import java.util.stream.Collectors; import static java.lang.StackWalker.Option.*; +import jdk.internal.access.JavaIOPrintStreamAccess; +import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.InternalLock; +import jdk.internal.vm.Continuation; /** * Helper class to print the virtual thread stack trace when pinned. @@ -42,7 +46,8 @@ * code in that Class. This is used to avoid printing the same stack trace many times. */ class PinnedThreadPrinter { - static final StackWalker STACK_WALKER; + private static final JavaIOPrintStreamAccess JIOPSA = SharedSecrets.getJavaIOPrintStreamAccess(); + private static final StackWalker STACK_WALKER; static { var options = Set.of(SHOW_REFLECT_FRAMES, RETAIN_CLASS_REFERENCE); PrivilegedAction pa = () -> @@ -86,45 +91,59 @@ private static int hash(List stack) { } /** - * Prints the continuation stack trace. + * Returns true if the frame is native, a class initializer, or holds monitors. + */ + private static boolean isInterestingFrame(LiveStackFrame f) { + return f.isNativeMethod() + || "".equals(f.getMethodName()) + || (f.getMonitors().length > 0); + } + + /** + * Prints the current thread's stack trace. * * @param printAll true to print all stack frames, false to only print the * frames that are native or holding a monitor */ - static void printStackTrace(PrintStream out, boolean printAll) { + static void printStackTrace(PrintStream out, Continuation.Pinned reason, boolean printAll) { List stack = STACK_WALKER.walk(s -> s.map(f -> (LiveStackFrame) f) .filter(f -> f.getDeclaringClass() != PinnedThreadPrinter.class) .collect(Collectors.toList()) ); + Object lockObj = JIOPSA.lock(out); + if (lockObj instanceof InternalLock lock && lock.tryLock()) { + try { + // find the closest frame that is causing the thread to be pinned + stack.stream() + .filter(f -> isInterestingFrame(f)) + .map(LiveStackFrame::getDeclaringClass) + .findFirst() + .ifPresentOrElse(klass -> { + // print the stack trace if not already seen + int hash = hash(stack); + if (HASHES.get(klass).add(hash)) { + printStackTrace(out, reason, stack, printAll); + } + }, () -> printStackTrace(out, reason, stack, true)); // not found - // find the closest frame that is causing the thread to be pinned - stack.stream() - .filter(f -> (f.isNativeMethod() || f.getMonitors().length > 0)) - .map(LiveStackFrame::getDeclaringClass) - .findFirst() - .ifPresentOrElse(klass -> { - int hash = hash(stack); - Hashes hashes = HASHES.get(klass); - synchronized (hashes) { - // print the stack trace if not already seen - if (hashes.add(hash)) { - printStackTrace(stack, out, printAll); - } - } - }, () -> printStackTrace(stack, out, true)); // not found + } finally { + lock.unlock(); + } + } } - private static void printStackTrace(List stack, - PrintStream out, + private static void printStackTrace(PrintStream out, + Continuation.Pinned reason, + List stack, boolean printAll) { - out.println(Thread.currentThread()); + out.format("%s reason:%s%n", Thread.currentThread(), reason); for (LiveStackFrame frame : stack) { var ste = frame.toStackTraceElement(); int monitorCount = frame.getMonitors().length; if (monitorCount > 0) { out.format(" %s <== monitors:%d%n", ste, monitorCount); - } else if (frame.isNativeMethod() || printAll) { + } else if (printAll || isInterestingFrame(frame)) { out.format(" %s%n", ste); } } diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java index e8ac217aecf..1b2b40b8c08 100644 --- a/src/java.base/share/classes/java/lang/VirtualThread.java +++ b/src/java.base/share/classes/java/lang/VirtualThread.java @@ -191,7 +191,15 @@ private static class VThreadContinuation extends Continuation { protected void onPinned(Continuation.Pinned reason) { if (TRACE_PINNING_MODE > 0) { boolean printAll = (TRACE_PINNING_MODE == 1); - PinnedThreadPrinter.printStackTrace(System.out, printAll); + VirtualThread vthread = (VirtualThread) Thread.currentThread(); + int oldState = vthread.state(); + try { + // avoid printing when in transition states + vthread.setState(RUNNING); + PinnedThreadPrinter.printStackTrace(System.out, reason, printAll); + } finally { + vthread.setState(oldState); + } } } private static Runnable wrap(VirtualThread vthread, Runnable task) { diff --git a/test/jdk/java/lang/Thread/virtual/TracePinnedThreads.java b/test/jdk/java/lang/Thread/virtual/TracePinnedThreads.java index 01fbdc76d49..5db29c631a3 100644 --- a/test/jdk/java/lang/Thread/virtual/TracePinnedThreads.java +++ b/test/jdk/java/lang/Thread/virtual/TracePinnedThreads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8284161 8289284 + * @bug 8284161 8289284 8322846 * @summary Basic test of debugging option to trace pinned threads * @requires vm.continuations * @library /test/lib @@ -34,6 +34,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.time.Duration; +import java.util.concurrent.Executors; import java.util.concurrent.locks.LockSupport; import jdk.test.lib.thread.VThreadRunner; @@ -67,8 +68,8 @@ void testPinnedCausedBySynchronizedBlock() throws Exception { park(); } }); + assertContains(output, "reason:MONITOR"); assertContains(output, "<== monitors:1"); - assertDoesNotContain(output, "(Native Method)"); } /** @@ -78,8 +79,68 @@ void testPinnedCausedBySynchronizedBlock() throws Exception { void testPinnedCausedByNativeMethod() throws Exception { System.loadLibrary("TracePinnedThreads"); String output = run(() -> invokePark()); + assertContains(output, "reason:NATIVE"); assertContains(output, "(Native Method)"); - assertDoesNotContain(output, "<== monitors"); + } + + /** + * Test parking in class initializer. + */ + @Test + void testPinnedCausedByClassInitializer() throws Exception { + class C { + static { + park(); + } + } + String output = run(C::new); + assertContains(output, "reason:NATIVE"); + assertContains(output, ""); + } + + /** + * Test contention writing to System.out when pinned. The test creates four threads + * that write to System.out when pinned, this is enough to potentially deadlock + * without the changes in JDK-8322846. + */ + @Test + void testContention() throws Exception { + // use several classes to avoid duplicate stack traces + class C1 { + synchronized void print() { + System.out.println("hello"); + } + } + class C2 { + synchronized void print() { + System.out.println("hello"); + } + } + class C3 { + synchronized void print() { + System.out.println("hello"); + } + } + class C4 { + synchronized void print() { + System.out.println("hello"); + } + } + + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { + executor.submit(() -> { + new C1().print(); + }); + executor.submit(() -> { + new C2().print(); + }); + executor.submit(() -> { + new C3().print(); + }); + executor.submit(() -> { + new C4().print(); + }); + } } /** From e667521b09c2db849dfe2349f96b8b17c9ba7e34 Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Thu, 29 Feb 2024 16:27:30 +0000 Subject: [PATCH 010/298] 8324123: aarch64: fix prfm literal encoding in assembler Backport-of: bde87895c8b1b9df198e3883d24cd9ea840efc98 --- src/hotspot/cpu/aarch64/assembler_aarch64.cpp | 20 +++++++++++++++++++ src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 13 ++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index afeb19e906e..c7b867a4207 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -187,6 +187,26 @@ void Address::lea(MacroAssembler *as, Register r) const { zrf(Rd, 0); } +// This encoding is similar (but not quite identical) to the encoding used +// by literal ld/st. see JDK-8324123. +// PRFM does not support writeback or pre/post index. +void Assembler::prfm(const Address &adr, prfop pfop) { + Address::mode mode = adr.getMode(); + // PRFM does not support pre/post index + guarantee((mode != Address::pre) && (mode != Address::post), "prfm does not support pre/post indexing"); + if (mode == Address::literal) { + starti; + f(0b11, 31, 30), f(0b011, 29, 27), f(0b000, 26, 24); + f(pfop, 4, 0); + int64_t offset = (adr.target() - pc()) >> 2; + sf(offset, 23, 5); + } else { + assert((mode == Address::base_plus_offset) + || (mode == Address::base_plus_offset_reg), "must be base_plus_offset/base_plus_offset_reg"); + ld_st2(as_Register(pfop), adr, 0b11, 0b10); + } +} + // An "all-purpose" add/subtract immediate, per ARM documentation: // A "programmer-friendly" assembler may accept a negative immediate // between -(2^24 -1) and -1 inclusive, causing it to convert a diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index a53d8329645..dd143ac004a 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -795,6 +795,8 @@ class Assembler : public AbstractAssembler { void adrp(Register Rd, const Address &dest, uint64_t &offset) = delete; + void prfm(const Address &adr, prfop pfop = PLDL1KEEP); + #undef INSN void add_sub_immediate(Instruction_aarch64 ¤t_insn, Register Rd, Register Rn, @@ -1572,17 +1574,6 @@ class Assembler : public AbstractAssembler { #undef INSN -#define INSN(NAME, size, op) \ - void NAME(const Address &adr, prfop pfop = PLDL1KEEP) { \ - ld_st2(as_Register(pfop), adr, size, op); \ - } - - INSN(prfm, 0b11, 0b10); // FIXME: PRFM should not be used with - // writeback modes, but the assembler - // doesn't enfore that. - -#undef INSN - #define INSN(NAME, size, op) \ void NAME(FloatRegister Rt, const Address &adr) { \ ld_st2(as_Register(Rt), adr, size, op, 1); \ From 4243aed45758772dc6ba24c65b2e15cedbf2bac5 Mon Sep 17 00:00:00 2001 From: Patrick Zhang Date: Fri, 1 Mar 2024 09:39:07 +0000 Subject: [PATCH 011/298] 8324824: AArch64: Detect Ampere-1B core and update default options for Ampere CPUs Backport-of: 9936aeea32b71509151099e6d28905e0322b2bc2 --- src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 12 ++++++++++-- src/hotspot/cpu/aarch64/vm_version_aarch64.hpp | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index f33e64b3af0..b76bb7efef3 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -144,11 +144,19 @@ void VM_Version::initialize() { } } - // Ampere CPUs: Ampere-1 and Ampere-1A - if (_cpu == CPU_AMPERE && ((_model == CPU_MODEL_AMPERE_1) || (_model == CPU_MODEL_AMPERE_1A))) { + // Ampere CPUs + if (_cpu == CPU_AMPERE && ((_model == CPU_MODEL_AMPERE_1) || + (_model == CPU_MODEL_AMPERE_1A) || + (_model == CPU_MODEL_AMPERE_1B))) { if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); } + if (FLAG_IS_DEFAULT(OnSpinWaitInst)) { + FLAG_SET_DEFAULT(OnSpinWaitInst, "isb"); + } + if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) { + FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2); + } } // ThunderX diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index a141127387e..0380f14e5c3 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -110,7 +110,8 @@ enum Ampere_CPU_Model { CPU_MODEL_ALTRA = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ CPU_MODEL_ALTRAMAX = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ CPU_MODEL_AMPERE_1 = 0xac3, /* CPU implementer is CPU_AMPERE */ - CPU_MODEL_AMPERE_1A = 0xac4 /* CPU implementer is CPU_AMPERE */ + CPU_MODEL_AMPERE_1A = 0xac4, /* CPU implementer is CPU_AMPERE */ + CPU_MODEL_AMPERE_1B = 0xac5 /* AMPERE_1B core Implements ARMv8.7 with CSSC, MTE, SM3/SM4 extensions */ }; #define CPU_FEATURE_FLAGS(decl) \ From 94634c08e6eaecbdb61223d390c1fc4f8ebab848 Mon Sep 17 00:00:00 2001 From: KIRIYAMA Takuya Date: Fri, 1 Mar 2024 15:15:17 +0000 Subject: [PATCH 012/298] 8313394: Array Elements in OldObjectSample event has the incorrect description Backport-of: e8c325dea39f959ab6bb310c3913b98655e95734 --- src/hotspot/share/jfr/metadata/metadata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index ac73a0b36c7..47245923da4 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -740,7 +740,7 @@ - + From ee6445c4952171b42b05638e5ea46a0b35fc4b99 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sat, 2 Mar 2024 02:44:31 +0000 Subject: [PATCH 013/298] 8323210: Update the usage of cmsFLAGS_COPY_ALPHA Backport-of: aba19334eaeb46d37169cddeef929b13e050a60e --- src/java.desktop/share/native/liblcms/LCMS.c | 9 +++++++-- .../cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/java.desktop/share/native/liblcms/LCMS.c b/src/java.desktop/share/native/liblcms/LCMS.c index 0d779ede511..08774c2beca 100644 --- a/src/java.desktop/share/native/liblcms/LCMS.c +++ b/src/java.desktop/share/native/liblcms/LCMS.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -188,8 +188,13 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform } } + cmsUInt32Number dwFlags = 0; + if (T_EXTRA(inFormatter) > 0 && T_EXTRA(outFormatter) > 0) { + dwFlags |= cmsFLAGS_COPY_ALPHA; + } + sTrans = cmsCreateMultiprofileTransform(iccArray, j, - inFormatter, outFormatter, renderingIntent, cmsFLAGS_COPY_ALPHA); + inFormatter, outFormatter, renderingIntent, dwFlags); (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0); diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java index 31db9d1a380..22868ffaf3c 100644 --- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java @@ -52,7 +52,7 @@ /* * @test - * @bug 8012229 8300725 8279216 + * @bug 8012229 8300725 8279216 8323210 * @summary one more test to check the alpha channel */ public final class ColCvtAlphaDifferentSrcDst { From 500d85aad72b4bfd64ba6208e9bdd49cd3992956 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Mon, 4 Mar 2024 03:09:00 +0000 Subject: [PATCH 014/298] 8318580: "javax/swing/MultiMonitor/MultimonVImage.java failing with Error. Can't find library: /open/test/jdk/java/awt/regtesthelpers" after JDK-8316053 Backport-of: e4803e0cbf00da89b98c8703769edc403bb5055b --- test/jdk/javax/swing/MultiMonitor/MultimonVImage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java index 730424e306c..42cb9c96da5 100644 --- a/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java +++ b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java @@ -28,7 +28,8 @@ * @summary displays an animating fps (frames per second) * counter. When the window is dragged from monitor to monitor, * the speed of the animation should not change too greatly. - * @library /open/test/jdk/java/awt/regtesthelpers + * @library /java/awt/regtesthelpers + * @build PassFailJFrame * @run main/manual MultimonVImage */ @@ -180,4 +181,5 @@ public void run() { component.repaint(); } } -} \ No newline at end of file +} + From dbcce04ae9e3ee903cadf7b877aee34ea21ed9ea Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 4 Mar 2024 11:19:49 +0000 Subject: [PATCH 015/298] 8323519: Add applications/ctw/modules to Hotspot tiered testing Backport-of: ba3c3bbd879eaf7532663663d73e21fafc65b574 --- test/hotspot/jtreg/TEST.groups | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index c1b8aadbd9f..c6e8461a54c 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -253,6 +253,7 @@ tier2_compiler = \ -:hotspot_slow_compiler tier3_compiler = \ + applications/ctw/modules \ compiler/c2/ \ compiler/ciReplay/ \ compiler/compilercontrol/ \ From fdbed07d38d4217d209380544d4447ce9b85bad7 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 4 Mar 2024 11:46:03 +0000 Subject: [PATCH 016/298] 8325862: set -XX:+ErrorFileToStderr when executing java in containers for some container related jtreg tests Backport-of: 9f4ec21f4793d4c5fc10f93a32140c26ec0eec00 --- .../lib/jdk/test/lib/containers/docker/DockerRunOptions.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/lib/jdk/test/lib/containers/docker/DockerRunOptions.java b/test/lib/jdk/test/lib/containers/docker/DockerRunOptions.java index 508c17fc399..fc3b793c47a 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerRunOptions.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerRunOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -60,6 +60,9 @@ public DockerRunOptions(String imageNameAndTag, String javaCmd, this.command = javaCmd; this.classToRun = classToRun; this.addJavaOpts(javaOpts); + // always print hserr to stderr in the docker tests to avoid + // trouble accessing it after a crash in the container + this.addJavaOpts("-XX:+ErrorFileToStderr"); } public DockerRunOptions addDockerOpts(String... opts) { From 2d62854922ea6fd3a948af64bd0f263db7dd6aa3 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 4 Mar 2024 17:50:11 +0000 Subject: [PATCH 017/298] 8320343: Generate GIF images for AbstractButton/5049549/bug5049549.java Backport-of: 9481d06e62334872af539ccfb8c1ea25e30a6da3 --- .../swing/AbstractButton/5049549/DE1.gif | Bin 955 -> 0 bytes .../swing/AbstractButton/5049549/DI1.gif | Bin 919 -> 0 bytes .../swing/AbstractButton/5049549/DS1.gif | Bin 988 -> 0 bytes .../swing/AbstractButton/5049549/PR1.gif | Bin 963 -> 0 bytes .../swing/AbstractButton/5049549/RO1.gif | Bin 995 -> 0 bytes .../swing/AbstractButton/5049549/RS1.gif | Bin 992 -> 0 bytes .../swing/AbstractButton/5049549/SE1.gif | Bin 958 -> 0 bytes .../AbstractButton/5049549/bug5049549.java | 54 ++++++++++++------ 8 files changed, 36 insertions(+), 18 deletions(-) delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/DE1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/DI1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/DS1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/PR1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/RO1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/RS1.gif delete mode 100644 test/jdk/javax/swing/AbstractButton/5049549/SE1.gif diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif deleted file mode 100644 index 3c12953f9a5f17764dee94422d92b9b425001ddd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 955 zcmb`GyKB{P483Zc|j#hT$5h{g=RFTe`R6G*6g64JLN|=WxR<-|b zSR}GsI`XZ~|3qiwm_$>{;puzxmm639{rY0Mee2m@%{#_l^|j9rtysVG!MBf-FGt$; z-)I=V)wX-+$CBGEk4D$Lxw&!6%y`%A)VsS)CkJ~zZ(iGFyDkhiKRfc}^~B!OgIC5r zt$Y8l?|%10_o`F9Q~R!6JT|;gdwPBKrJ0UD3$+hd2RcU&zTNQsz~sQl+VeBb X^D|G*_is9Sr+@LX*4}f+_sGtF7~G-C diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif deleted file mode 100644 index a812a358b9d3954028e1c0eef067dbfaef60fb37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 919 zcmb`GJ8P6-5QV2q8ZVs@(WnqFqzF!E+41PO^orxW9X zT6y^cD>hN52|-lQCe;=;RyM-;%=;T0SiYT|nKS2{`F8T?k-ht-cgkk@BNg5D>9$9g ztXt9V_mkgKvORe6jo`Qc7b;>RE)ungOjXoGT{J|qil$;F=3*h1)$1y5;w~QIS)-v6 zCgBnxQA{OO(j;9npk2TP4Hm<6XYHvlRaXtwthHojYOWS)Su7~Jsk?fpXOW^eOv5!o zBjL!XrfIrnXtEX7fI%9T(4xj-uz?1P;VeOw6K)n}S^8K@=58M5S#n`PG29|767`Ux z*U~M+5_$LmO{TE}{g6N*tO0{GENO)Yi@^pOtSslMOiqM*mXYXVEm?#|;wy4tLD4fj z@e!vn0A93XG-|ODKcLApcEAb2D1~2McV+d{g3g@&JM!+u@?vLx_wA8~gQ*9jyAJ;Rc5=t^+^LzV eFHf#MKfZ9{#^p!fuMEESF0Q<~aBgB$_WuKSXO!*$ diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif deleted file mode 100644 index 5559452e839af18b6fcb41f5cb948949a15a14aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 988 zcmb_b%S+U85T77oee^)AR??y<@DP*@v|AmFqvqeCFHWF6WHvMx<} zkVre2AezzRvK4^~Q=X!vPDTjUAy3h1`poxlXkhv6?96=T^ZCqgTiXxi_nc~^jr4~i z3h7fwj{>qnM5$DA{O;uGfhWEp@Z0|jCK4hgve<--nOKOG*oZxf!X!eXBu3)Vt4u1S zN@}DYqsC-HresDIOv#yC$d%kcJAeZkSQtjP$DRmbR%T=NSc^=AMOlo+g9VBztjcPv z9;DD~!lrD-=HQ4?c41d`W5-so1{g?#C1|0B#lQwMurTZ)C~|~~n23iytVO0OYN8%; z!2(57F%xsB2PyQ5tGJ0n9{d1JOv4W72MH(yYk+|?SfUj?uo&2Y29}3&QAUn1RSzSf z4{MQ`sX2UwT(Ce<-PGYDoQ475g?1PXwXhO?fF`D42RK166oNItKpK;v1s+%oY(RUQ zD7sNbj&NKIMnWIfBD3_8g|F$}QA{Tco6}XIHyItSC+}i3*%3!b3Ii#Tj+-PN0i2-m zI^aq$51O!Q^WWvmh}O{dc&p<-(VBTlUQypRG5n@Kv$D5)=I-F$zRc45GuhRr58S9~ z>gC3+lP$N_w-oE!Cm)xuR#(k;XD{@0T-$MQ_fUC!r1N3zk;QN2sVB4d^Osf)WoysQ zJjmrLPs~j`>e9N3UDG#@_I$dY-?ZiS!ob%T#pZX#hR)|t=cab{pWpW7^5}~PD5>J07s2XkSuIsgCw diff --git a/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif b/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif deleted file mode 100644 index adefa4459d837b2e75d49689a01d095ff76d95c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 963 zcmb`G-D}Tr6vvN}M#v&5OIuQ_J!qX`8dAz0SVrPvC3EpXE|hZN%G$W_PCt ziyUlD(C5nVeIJ6Tup}}I9?#MkEMb%VYHF7OkDOya6Yl&n*(TbX>xmqMC zdcCNdx~m5q8PzBnrr{cFg*9N1h9$J9u^4Qi!D2X4Q09b{;-y6DV=b9kF)tP=7Zw!V zihJ=uJ*4O@VI{l-^6&$iOk)T7A%Q|z0|seW(h3h2gAFuTk-FBTi!gylBU0)M6!mK$B_gfD?jI2y4I~%_Owo!D6t1jyzFzQzj>Zi(w@C zSWD*BOP0P?_s(KPpr|Xq>Ia=9~N2nAgQbjs%Qt?RO3Yyn}D`6g*Sk>@% z{ydRo(wuK~{wF$XMkN;3bv+z?Ib2hFvVVGHu6=09+O4~ejx@YJvohxTSN$HFx?I2g z!V24S==r&y3$A{eZu|Ofc>QckUH9WVGuPXX-QWDS<@V&2)klUdeg5!c_gG{1qTZ)_ zzrVWCH{Nrz=gHmK@!Hu_XS??O>bkXf;_&?Uz4xZBt^3%zW#|6pFOOQ!ztN5jO)nlC fA87q{dSmOv#clmdXZqVt^gTPUyy>8~*GtDg*+iz5 diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif deleted file mode 100644 index 68bcf8bed1fa69a67917e42e274e8194a3c558ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 995 zcmb_b&r8&C5S>y?2~0>*QY#OFf?XO9RtF>(&}go>Dmhd!)DrYdTp9&*6~ zMN=^obEpR?^opyvi9;Uz08LE84(JC7ChjURzjxbdZBcTs# zk(sGEe1%-FKvCV);Uk=e0pNvp7!9?s5`KUtreOy-K`<18HNZd`lb{72SPX1Hdz>h` zQAUn%Tnt7+AJ!tX^pb_I>E2OHCk&g@RiZZ;9j+(uVl>$iM@R|-DUptwBpv~rpz%83 zN-z(au&VY?;VPmsYK*r!{uAxRdGeC#JUnyR9CObQHXYzc>mnYfBrJJXEi>kJb z9vG_KJy_Y=U)?b_(lJ!fIg>4ZzPR^9MeBpVeS>w=w>MTzG`$&r^zPoSi%ah>oUMO- zw{qZ9dGn3K`>w8CGj+Y;M_t#Y^*#N^`+qIBTr1yNRFjz){WyMf;ce57`7QIqhg#Zd zRz5V$-C7wtc5rTBF>|h~qU&Mi^wZ9K!#CMKTsG2u^YZ5nOPNzgvad>iF4r`^Jo$CD Sw{NC9Gx_5CLSeyb+W8MpthN6D diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif deleted file mode 100644 index 09e183eb531cd6a00e46e0ee29de5d2ffe1dc4f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 992 zcmb_b!Aq2J5S^lf;-QTWL1eXSM3k4Biy~zmTs86LrLsc=0~ypQ=+I%;K&6a~AQO8p@HSw*_nCs-kWb*+w%>LXZF!fTBC?U z`V`WmfUFQvE|(p@J9&EGiEjw}_Wy#3gh+`jHX&ms7GfnfVvnLQiI6CXk$ChflM1Pl z8mY&qF`1AlnUMukawZpYB{$Fx;D81ehSBY@CqkH&*_b`nA`@Xz7Gv>XfuahlvKp%g zDfF7KDVwo5IAWAt*p=Pbu@$TV2GU>&TBu<$umKG$40{NQ9HAm6;-L>~k*SKBsE1sz zK+#mp#2o5D3ccbgZsL#!KR^@Humk!*0t&$zU?2^aXax@}1~#C9<>6eEkt0mi!$|1E zT4ZKw4qqV`EKpQ8b@&LUVE}lc9Y#Yftb`w+iD}pYP7n-*U=1*k#w2Kg2NnYx&>km> zZj_ND92bL;(1*3iEWKpmYr1z7(+R`obd~5$Mu+RkyBJMWFhKuVjAp;k!#i4~|}{%x>wLzcE_Ab+GwIW&Y{d``&GJ3-xWkatn7h zw@mD*x_#=!NNxM_;JeJO&f%KVuVxx1S6jxL-(0Khc=qVT&12_#N0+AdcJ-ahPW=70 z_%Q$2r+VJb|GdyWcD!zO`1TJ=EWjO z(d$~=ihJ>ZBcmm>gq83TY=t#okcK6+sIeGqpuu7|Qc&iEsk&;UKGu?%skvIDTv$+a zQ+M@1J*4Q>Fb&s09)3WRY3x8hBv1%zz#t7vTH(QBuz?0E(zz^?6K)o1B>GrO=58MN zidTRSPVAMktfP-%H%|FF^ohX zYstKN$2$jM_sz~QeDjo@3LGwCrCCoz;t2X~` zY!F!|Tk@^W|3q)ogv6@0z0;F#N1N6zeqEd%s$E#Ip+0*?dK zuk@d)->uI*`80L3=lPvqEzA4I24DSM^ZoGhzH@zD9~Z8koT|;#-?Z);{Gp#8p569r Y?&X>LJMSHsUEMzLVtQ$;p+S270hny0 Date: Tue, 5 Mar 2024 10:55:30 +0000 Subject: [PATCH 018/298] 8324648: Avoid NoSuchMethodError when instantiating NativePRNG Backport-of: 69b2674c6861fdb7d9f9cb39e07d50515c73e33a --- .../sun/security/provider/NativePRNG.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/java.base/unix/classes/sun/security/provider/NativePRNG.java b/src/java.base/unix/classes/sun/security/provider/NativePRNG.java index 25548bfeb80..edc5197df2c 100644 --- a/src/java.base/unix/classes/sun/security/provider/NativePRNG.java +++ b/src/java.base/unix/classes/sun/security/provider/NativePRNG.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -203,11 +203,13 @@ static boolean isAvailable() { } // constructor, called by the JCA framework - public NativePRNG() { - super(); + public NativePRNG(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError("NativePRNG not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed @@ -251,11 +253,13 @@ static boolean isAvailable() { } // constructor, called by the JCA framework - public Blocking() { - super(); + public Blocking(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError("NativePRNG$Blocking not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed @@ -300,12 +304,14 @@ static boolean isAvailable() { } // constructor, called by the JCA framework - public NonBlocking() { - super(); + public NonBlocking(SecureRandomParameters params) { if (INSTANCE == null) { throw new AssertionError( "NativePRNG$NonBlocking not available"); } + if (params != null) { + throw new IllegalArgumentException("Unsupported params: " + params.getClass()); + } } // set the seed From 4244cb0d9927bd2b6c565b10e6bd40be0c3c7843 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 5 Mar 2024 11:57:40 +0000 Subject: [PATCH 019/298] 8306040: HttpResponseInputStream.available() returns 1 on empty stream Backport-of: acaab6fd74f507bb6b18167505d88e505bdf24bd --- .../net/http/ResponseSubscribers.java | 4 +- .../HttpInputStreamAvailableTest.java | 161 ++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index 6a58fe18fc9..fe10ef58d09 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -538,8 +538,8 @@ public int available() throws IOException { if (available != 0) return available; Iterator iterator = currentListItr; if (iterator != null && iterator.hasNext()) return 1; - if (buffers.isEmpty()) return 0; - return 1; + if (!buffers.isEmpty() && buffers.peek() != LAST_LIST ) return 1; + return available; } @Override diff --git a/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java b/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java new file mode 100644 index 00000000000..5cca88716b6 --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8306040 + * @summary HttpResponseInputStream.available() returns 1 on empty stream + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @run junit/othervm HttpInputStreamAvailableTest + * + */ +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import jdk.test.lib.net.URIBuilder; + +import java.io.IOException; +import java.io.InputStream; +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 org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class HttpInputStreamAvailableTest { + + private HttpServer server; + private int port; + static final String TEST_MESSAGE = "This is test message"; + static final int ZERO = 0; + + @BeforeAll + void setup() throws Exception { + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress addr = new InetSocketAddress(loopback, 0); + server = HttpServer.create(addr, 0); + port = server.getAddress().getPort(); + FirstHandler fHandler = new FirstHandler(); + server.createContext("/NonZeroResponse/", fHandler); + SecondHandler sHandler = new SecondHandler(); + server.createContext("/ZeroResponse/", sHandler); + server.start(); + } + + @AfterAll + void teardown() throws Exception { + server.stop(0); + } + + @Test + public void test() throws Exception { + HttpClient client = HttpClient + .newBuilder() + .proxy(HttpClient.Builder.NO_PROXY) + .build(); + + URI uri = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/NonZeroResponse/") + .build(); + + HttpRequest request = HttpRequest + .newBuilder(uri) + .GET() + .build(); + + // Send a httpRequest and assert the bytes available + HttpResponse response = client.send(request, + HttpResponse.BodyHandlers.ofInputStream()); + try ( InputStream in = response.body()) { + in.readNBytes(2); + // this is not guaranteed, but a failure here would be surprising + assertEquals(TEST_MESSAGE.length() - 2, in.available()); + //read the remaining data + in.readAllBytes(); + //available should return 0 + assertEquals(ZERO, in.available()); + } + } + + @Test + public void test1() throws Exception { + HttpClient client = HttpClient + .newBuilder() + .proxy(HttpClient.Builder.NO_PROXY) + .build(); + + URI uri = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/ZeroResponse/") + .build(); + + HttpRequest request = HttpRequest + .newBuilder(uri) + .GET() + .build(); + + // Send a httpRequest and assert the bytes available + HttpResponse response = client.send(request, + HttpResponse.BodyHandlers.ofInputStream()); + try ( InputStream in = response.body()) { + assertEquals(ZERO, in.available()); + in.readAllBytes(); + assertEquals(ZERO, in.available()); + } + } + + static class FirstHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + try ( OutputStream os = exchange.getResponseBody()) { + byte[] workingResponse = TEST_MESSAGE.getBytes(); + exchange.sendResponseHeaders(200, workingResponse.length); + os.write(workingResponse); + os.flush(); + } + } + } + + static class SecondHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + exchange.sendResponseHeaders(204, -1); + } + } +} From ad1d32484a8130c9b641cff38c07e8544b3fd271 Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Wed, 6 Mar 2024 09:05:25 +0000 Subject: [PATCH 020/298] 8327036: [macosx-aarch64] SIGBUS in MarkActivationClosure::do_code_blob reached from Unsafe_CopySwapMemory0 Reviewed-by: mdoerr --- src/hotspot/share/runtime/interfaceSupport.inline.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index 9de1f8126d1..ee204cb2e1c 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp @@ -409,6 +409,7 @@ extern "C" { \ #define JVM_ENTRY_FROM_LEAF(env, result_type, header) \ { { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) From e071843318f81136a34f5a325a01a30bb1bfe19a Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 7 Mar 2024 08:07:18 +0000 Subject: [PATCH 021/298] 8326638: Crash in PhaseIdealLoop::remix_address_expressions due to unexpected Region instead of Loop Backport-of: 9f0e7da64e21237322e55ca4f0e3639fa5d1c4ed --- src/hotspot/share/opto/loopopts.cpp | 6 +- ...AddressExpressionsWithIrreducibleLoop.java | 57 +++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index be2ec7dbc07..be9f5599d53 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -521,8 +521,8 @@ Node* PhaseIdealLoop::remix_address_expressions(Node* n) { } // Replace ((I1 +p V) +p I2) with ((I1 +p I2) +p V), - // but not if I2 is a constant. - if (n_op == Op_AddP) { + // but not if I2 is a constant. Skip for irreducible loops. + if (n_op == Op_AddP && n_loop->_head->is_Loop()) { if (n2_loop == n_loop && n3_loop != n_loop) { if (n->in(2)->Opcode() == Op_AddP && !n->in(3)->is_Con()) { Node* n22_ctrl = get_ctrl(n->in(2)->in(2)); diff --git a/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java b/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java new file mode 100644 index 00000000000..ff7be96007d --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java @@ -0,0 +1,57 @@ +/* + * 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. + * + */ + +/* + * @test + * @bug 8326638 + * @summary Test handling of irreducible loops in PhaseIdealLoop::remix_address_expressions. + * @run main/othervm -XX:-TieredCompilation -Xbatch + * -XX:CompileCommand=compileonly,TestRemixAddressExpressionsWithIrreducibleLoop::test + * TestRemixAddressExpressionsWithIrreducibleLoop + */ + +public class TestRemixAddressExpressionsWithIrreducibleLoop { + + public static void main(String[] args) { + test("4"); + } + + public static void test(String arg) { + for (int i = 0; i < 100_000; ++i) { + int j = 0; + while (true) { + boolean tmp = "1\ufff0".startsWith(arg, 2 - arg.length()); + if (j++ > 100) + break; + } + loop: + while (i >= 100) { + for (int i2 = 0; i2 < 1; i2 = 1) + if (j > 300) + break loop; + j++; + } + } + } +} From bfaec80e80ee51d6f9b0e91fe136d4d77a885d10 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 7 Mar 2024 08:07:50 +0000 Subject: [PATCH 022/298] 8325972: Add -x to bash for building with LOG=debug Backport-of: 8668198c26bdac412f0a9d1255ca74da860761c5 --- make/common/MakeBase.gmk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk index 252d9dd50da..3858b652ee6 100644 --- a/make/common/MakeBase.gmk +++ b/make/common/MakeBase.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -152,6 +152,10 @@ define SetupLogging endif endif + ifneq ($$(findstring $$(LOG_LEVEL), debug trace),) + SHELL := $$(SHELL) -x + endif + ifeq ($$(LOG_LEVEL), trace) SHELL_NO_RECURSE := $$(SHELL) # Shell redefinition trick inspired by http://www.cmcrossroads.com/ask-mr-make/6535-tracing-rule-execution-in-gnu-make From 555f824c763a6f5b72fc53edbc20bbdae3814d1b Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Thu, 7 Mar 2024 10:11:51 +0000 Subject: [PATCH 023/298] 8315898: Open source swing JMenu tests Backport-of: fecd2fd8f26d0e8905a519e30e9aa171683c9df1 --- test/jdk/javax/swing/JMenu/bug4143592.java | 49 +++++++++++ test/jdk/javax/swing/JMenu/bug4148154.java | 50 +++++++++++ test/jdk/javax/swing/JMenu/bug4156316.java | 43 ++++++++++ test/jdk/javax/swing/JMenu/bug4161866.java | 58 +++++++++++++ test/jdk/javax/swing/JMenu/bug4244796.java | 58 +++++++++++++ test/jdk/javax/swing/JMenu/bug4767393.java | 99 ++++++++++++++++++++++ 6 files changed, 357 insertions(+) create mode 100644 test/jdk/javax/swing/JMenu/bug4143592.java create mode 100644 test/jdk/javax/swing/JMenu/bug4148154.java create mode 100644 test/jdk/javax/swing/JMenu/bug4156316.java create mode 100644 test/jdk/javax/swing/JMenu/bug4161866.java create mode 100644 test/jdk/javax/swing/JMenu/bug4244796.java create mode 100644 test/jdk/javax/swing/JMenu/bug4767393.java diff --git a/test/jdk/javax/swing/JMenu/bug4143592.java b/test/jdk/javax/swing/JMenu/bug4143592.java new file mode 100644 index 00000000000..334128f39ff --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4143592.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4143592 + * @summary Tests the method add(Component, int) of JMenu for insertion + the given component to a specified position of menu + * @run main bug4143592 + */ + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +public class bug4143592 { + + public static void main(String[] argv) { + JMenuBar mb = new JMenuBar(); + JMenu m = mb.add(new JMenu("Order")); + m.add("beginning"); + m.add("middle"); + m.add("end"); + m.add(new JMenuItem("in between"), 1); + if (!m.getItem(1).getText().equals("in between")) { + throw new RuntimeException("Item was inserted incorrectly."); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4148154.java b/test/jdk/javax/swing/JMenu/bug4148154.java new file mode 100644 index 00000000000..1da1549af19 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4148154.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4148154 + * @summary Tests that menu items created by JMenu.add(Action) method + have right HorizontalTextPosition. + * @run main bug4148154 + */ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.JMenu; +import javax.swing.JMenuItem; + +public class bug4148154 +{ + public static void main(String[] args) { + JMenu menu = new JMenu(); + JMenuItem mi = menu.add(new AbstractAction() { + public void actionPerformed(ActionEvent ev) {} + }); + if (mi.getHorizontalTextPosition() != JMenu.LEADING && + mi.getHorizontalTextPosition() != JMenu.TRAILING) { + + throw new RuntimeException("Failed:"); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4156316.java b/test/jdk/javax/swing/JMenu/bug4156316.java new file mode 100644 index 00000000000..2d569903205 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4156316.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4156316 + * @summary checks if JMenu.add(Component) throws NullPointerException + * @run main bug4156316 + */ + +import javax.swing.JComponent; +import javax.swing.JMenu; + +public class bug4156316 { + + public static void main(String[] args) { + JMenu m = new JMenu("test"); + m.add(new XComponent()); + } + + static class XComponent extends JComponent { + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4161866.java b/test/jdk/javax/swing/JMenu/bug4161866.java new file mode 100644 index 00000000000..0363404e486 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4161866.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4161866 + * @summary Method AccessibleJMenu.removeAccessibleSelection does not + remove selections correctly + * @run main bug4161866 + */ + +import javax.accessibility.AccessibleSelection; +import javax.swing.JMenu; +import javax.swing.JMenuBar; + +public class bug4161866 { + + public static void main(String[] argv) { + JMenuBar mb = new JMenuBar(); + JMenu mnu = new JMenu(); + AccessibleSelection acs = mnu.getAccessibleContext(). + getAccessibleSelection(); + mb.add(mnu); + JMenu jm = new JMenu(); + mnu.add(jm); + jm.setSelected(true); + acs.addAccessibleSelection(0); + if (!jm.isSelected()) { + throw new RuntimeException("Selection should be non-empty..."); + } + + acs.removeAccessibleSelection(0); + if (jm.isSelected()) { + throw new RuntimeException("Selection still non-empty after " + + "it was removed"); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4244796.java b/test/jdk/javax/swing/JMenu/bug4244796.java new file mode 100644 index 00000000000..cbb6d66280c --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4244796.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4244796 + * @summary Tests that JMenu has JMenu(Action) constructor + * @run main bug4244796 + */ + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Action; +import javax.swing.JMenu; + +public class bug4244796 { + + /** + * Auxilliary class implementing Action + */ + static class NullAction implements Action { + public void addPropertyChangeListener( + PropertyChangeListener listener) {} + public void removePropertyChangeListener( + PropertyChangeListener listener) {} + public void putValue(String key, Object value) {} + public void setEnabled(boolean b) {} + public void actionPerformed(ActionEvent e) {} + + public Object getValue(String key) { return null; } + public boolean isEnabled() { return false; } + } + + public static void main(String[] argv) { + Action action = new NullAction(); + JMenu menu = new JMenu(action); + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4767393.java b/test/jdk/javax/swing/JMenu/bug4767393.java new file mode 100644 index 00000000000..617d50983f9 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4767393.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4767393 + * @summary Disabled JMenu is selectable via mnemonic + * @key headful + * @run main bug4767393 + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.SwingUtilities; + +public class bug4767393 { + + public static JFrame mainFrame; + public static JMenuBar menuBar; + public static JMenu menu; + public static JMenu disabled; + public static volatile boolean disabledMenuSelected = true; + + public static void main(String[] args) throws Exception { + try { + Robot robo = new Robot(); + robo.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + mainFrame = new JFrame("Bug4767393"); + menuBar = new JMenuBar(); + menu = new JMenu("File"); + disabled = new JMenu("Disabled"); + menuBar.add(menu); + menu.add("Menu Item 1"); + menu.add("Menu Item 2"); + disabled.setEnabled(false); + disabled.setMnemonic('D'); + disabled.add("Dummy menu item"); + menu.add(disabled); + menu.add("Menu Item 3"); + menu.add("Menu Item 4"); + mainFrame.setJMenuBar(menuBar); + + mainFrame.setSize(200, 200); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + }); + robo.waitForIdle(); + robo.delay(500); + + robo.keyPress(KeyEvent.VK_F10); + robo.keyRelease(KeyEvent.VK_F10); + robo.keyPress(KeyEvent.VK_DOWN); + robo.keyRelease(KeyEvent.VK_DOWN); + robo.delay(500); + robo.keyPress(KeyEvent.VK_D); + robo.keyRelease(KeyEvent.VK_D); + robo.delay(100); + + SwingUtilities.invokeAndWait(() -> { + disabledMenuSelected = disabled.isSelected(); + }); + + if (disabledMenuSelected) { + throw new RuntimeException("Disabled JMenu is selected" + + " by the mnemonic. Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } +} From e8d2535856e47966b2db9c4f2ec5e31b552e14d5 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Thu, 7 Mar 2024 10:12:05 +0000 Subject: [PATCH 024/298] 8315609: Open source few more swing text/html tests Backport-of: a04c6c1ac663a1eab7d45913940cb6ac0af2c11c --- .../javax/swing/text/html/Map/bug4322891.java | 107 ++++++++++++++++ .../text/html/StyleSheet/bug4476002.java | 99 +++++++++++++++ .../swing/text/html/TableView/bug4412522.java | 115 ++++++++++++++++++ .../swing/text/html/TableView/bug4690812.java | 101 +++++++++++++++ 4 files changed, 422 insertions(+) create mode 100644 test/jdk/javax/swing/text/html/Map/bug4322891.java create mode 100644 test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java create mode 100644 test/jdk/javax/swing/text/html/TableView/bug4412522.java create mode 100644 test/jdk/javax/swing/text/html/TableView/bug4690812.java diff --git a/test/jdk/javax/swing/text/html/Map/bug4322891.java b/test/jdk/javax/swing/text/html/Map/bug4322891.java new file mode 100644 index 00000000000..daee724e3a1 --- /dev/null +++ b/test/jdk/javax/swing/text/html/Map/bug4322891.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4322891 + * @summary Tests if image map receives correct coordinates. + * @key headful + * @run main bug4322891 +*/ + +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4322891 { + + private boolean finished = false; + private static boolean passed = false; + private static Robot robot; + private static JFrame f; + private static JEditorPane jep; + private static volatile Point p; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + try { + bug4322891 test = new bug4322891(); + SwingUtilities.invokeAndWait(test::init); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = jep.getLocationOnScreen(); + }); + robot.mouseMove(p.x, p.y); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + for (int i = 1; i < 30; i++) { + robot.mouseMove(p.x + i, p.y + i); + robot.waitForIdle(); + } + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public void init() { + String text = "" + + "" + + "" + + ""; + + f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + jep.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + passed = true; + } + }); + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + +} diff --git a/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java b/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java new file mode 100644 index 00000000000..bb3a1d72b0e --- /dev/null +++ b/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4476002 + * @summary Verifies JEditorPane:
    list numbers do not pick up color of the list text + * @key headful + * @run main bug4476002 +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +public class bug4476002 { + + private static boolean passed = true; + private static JLabel htmlComponent; + + private static Robot robot; + private static JFrame mainFrame; + private static volatile Point p; + private static volatile Dimension d; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + + try { + SwingUtilities.invokeAndWait(() -> { + String htmlText = + "" + + "
    1. wwwww
    "; + + mainFrame = new JFrame("bug4476002"); + + htmlComponent = new JLabel(htmlText); + mainFrame.getContentPane().add(htmlComponent); + + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = htmlComponent.getLocationOnScreen(); + d = htmlComponent.getSize(); + }); + int x0 = p.x; + int y = p.y + d.height/2; + + for (int x = x0; x < x0 + d.width; x++) { + if (robot.getPixelColor(x, y).equals(Color.black)) { + passed = false; + break; + } + } + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } + +} diff --git a/test/jdk/javax/swing/text/html/TableView/bug4412522.java b/test/jdk/javax/swing/text/html/TableView/bug4412522.java new file mode 100644 index 00000000000..f983b07ecfc --- /dev/null +++ b/test/jdk/javax/swing/text/html/TableView/bug4412522.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4412522 + * @summary Tests if HTML that has comments inside of tables is rendered correctly + * @key headful + * @run main bug4412522 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + +import java.awt.Robot; +import java.awt.Shape; + +public class bug4412522 { + + private static boolean passed = false; + + private static JEditorPane jep; + private static JFrame f; + private static Robot robot; + + public void init() { + + String text = + "" + + "" + + "" + + "
    first cellsecond cell
    row heading
    "; + + JFrame f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + + public static void main(String args[]) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + bug4412522 test = new bug4412522(); + try { + SwingUtilities.invokeAndWait(() -> test.init()); + robot.waitForIdle(); + robot.delay(1000); + Shape r = jep.getBounds(); + View v = jep.getUI().getRootView(jep); + int tableWidth = 0; + int cellsWidth = 0; + + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableWidth = r.getBounds().width; + } + + if (viewName.endsWith("CellView")) { + cellsWidth = r.getBounds().x + r.getBounds().width; + } + + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + + passed = ((tableWidth - cellsWidth) > 10); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/text/html/TableView/bug4690812.java b/test/jdk/javax/swing/text/html/TableView/bug4690812.java new file mode 100644 index 00000000000..263bba71f14 --- /dev/null +++ b/test/jdk/javax/swing/text/html/TableView/bug4690812.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4690812 + * @summary Tests if tables are correctly formatted in some cases + * @key headful + * @run main bug4690812 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + +import java.awt.Robot; +import java.awt.Shape; + +public class bug4690812 { + + private static boolean passed = false; + + private static JEditorPane jep; + private static JFrame f; + + public void init() { + + String text = + "" + + "" + + "" + + "" + + "
    a
    something
    "; + + JFrame f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + public static void main(String args[]) throws Exception { + Robot robot = new Robot(); + bug4690812 test = new bug4690812(); + try { + SwingUtilities.invokeAndWait(() -> test.init()); + robot.waitForIdle(); + robot.delay(1000); + Shape r = jep.getBounds(); + View v = jep.getUI().getRootView(jep); + int tableHeight = 0; + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + // left column in the second table row should have width == 1 + passed = (r.getBounds().width == 1) ? true : false; + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} From 5c3dfe46a5832efb42ede781133addfe7f00a07e Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Thu, 7 Mar 2024 10:13:07 +0000 Subject: [PATCH 025/298] 8316563: test tools/jpackage/linux/LinuxResourceTest.java fails on CentOS Linux release 8.5.2111 and Fedora 27 Backport-of: 52814994efc4831fdbc1f796ed1db6ae88cb616c --- test/jdk/tools/jpackage/linux/LinuxResourceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java index 70bf389d312..f38e0763d28 100644 --- a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java @@ -102,6 +102,7 @@ public static void testHardcodedProperties() throws IOException { "License: APPLICATION_LICENSE_TYPE", "Prefix: %{dirname:APPLICATION_DIRECTORY}", "Provides: dont-install-me", + "%define _build_id_links none", "%description", "APPLICATION_DESCRIPTION", "%prep", From e328bf37fc9c4b82ae92d307dcb04abe64645af9 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Thu, 7 Mar 2024 10:14:45 +0000 Subject: [PATCH 026/298] 8325024: java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java incorrect comment information Backport-of: 432756b6e51c903e2bff8b9c3028a4f2ea8973f4 --- .../java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java index 4df00c5aa9a..3e2648af7cb 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java @@ -188,7 +188,7 @@ private static void createPKI() throws Exception { rootOcsp.setDisableContentLength(true); rootOcsp.start(); - // Wait 5 seconds for server ready + // Wait 60 seconds for server ready boolean readyStatus = rootOcsp.awaitServerReady(60, TimeUnit.SECONDS); if (!readyStatus) { throw new RuntimeException("Server not ready"); From 47c67bda68cfddad42eb5bdc3138f40d2d87a4db Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:23:44 +0000 Subject: [PATCH 027/298] 8309763: Move tests in test/jdk/sun/misc/URLClassPath directory to test/jdk/jdk/internal/loader Backport-of: 57fc9a3e968cafe3b618a216630e703a39d5676e --- .../loader}/URLClassPath/ClassnameCharTest.java | 0 .../loader}/URLClassPath/FileLoaderTest.java | 0 .../loader}/URLClassPath/JarLoaderTest.java | 0 .../URLClassPath/LargeClasspathWithPkgPrefix.java | 0 .../internal/loader}/URLClassPath/testclasses.jar | Bin 5 files changed, 0 insertions(+), 0 deletions(-) rename test/jdk/{sun/misc => jdk/internal/loader}/URLClassPath/ClassnameCharTest.java (100%) rename test/jdk/{sun/misc => jdk/internal/loader}/URLClassPath/FileLoaderTest.java (100%) rename test/jdk/{sun/misc => jdk/internal/loader}/URLClassPath/JarLoaderTest.java (100%) rename test/jdk/{sun/misc => jdk/internal/loader}/URLClassPath/LargeClasspathWithPkgPrefix.java (100%) rename test/jdk/{sun/misc => jdk/internal/loader}/URLClassPath/testclasses.jar (100%) diff --git a/test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java b/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java diff --git a/test/jdk/sun/misc/URLClassPath/FileLoaderTest.java b/test/jdk/jdk/internal/loader/URLClassPath/FileLoaderTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/FileLoaderTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/FileLoaderTest.java diff --git a/test/jdk/sun/misc/URLClassPath/JarLoaderTest.java b/test/jdk/jdk/internal/loader/URLClassPath/JarLoaderTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/JarLoaderTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/JarLoaderTest.java diff --git a/test/jdk/sun/misc/URLClassPath/LargeClasspathWithPkgPrefix.java b/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/LargeClasspathWithPkgPrefix.java rename to test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java diff --git a/test/jdk/sun/misc/URLClassPath/testclasses.jar b/test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar similarity index 100% rename from test/jdk/sun/misc/URLClassPath/testclasses.jar rename to test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar From 22672926eabb6fcd8f7d08b7803c7eb87125a55a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:27:09 +0000 Subject: [PATCH 028/298] 8310070: Test: javax/net/ssl/DTLS/DTLSWontNegotiateV10.java timed out Backport-of: af7f95e24ad5981c5de4b5dbf37da6f4f5e42129 --- .../net/ssl/DTLS/DTLSWontNegotiateV10.java | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java index 2532f524371..f67a02b3052 100644 --- a/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java +++ b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java @@ -48,6 +48,8 @@ public class DTLSWontNegotiateV10 { private static final String DTLS = "DTLS"; private static final String DTLSV_1_2 = "DTLSv1.2"; + private static final int READ_TIMEOUT_SECS = Integer.getInteger("readtimeout", 30); + public static void main(String[] args) throws Exception { if (args[0].equals(DTLSV_1_0)) { SecurityUtils.removeFromDisabledTlsAlgs(DTLSV_1_0); @@ -63,20 +65,43 @@ public static void main(String[] args) throws Exception { } else { // server process // args: protocol - try (DTLSServer server = new DTLSServer(args[0])) { - List command = List.of( - Path.of(System.getProperty("java.home"), "bin", "java").toString(), - "DTLSWontNegotiateV10", - // if server is "DTLS" then the client should be v1.0 and vice versa - args[0].equals(DTLS) ? DTLSV_1_0 : DTLS, - Integer.toString(server.getListeningPortNumber()) - ); - - ProcessBuilder builder = new ProcessBuilder(command); - Process p = builder.inheritIO().start(); - server.run(); - p.destroy(); - System.out.println("Success: DTLSv1.0 connection was not established."); + final int totalAttempts = 5; + int tries; + for (tries = 0 ; tries < totalAttempts ; ++tries) { + try { + System.out.printf("Starting server %d/%d attempts%n", tries+1, totalAttempts); + runServer(args[0]); + break; + } catch (SocketTimeoutException exc) { + System.out.println("The server timed-out waiting for packets from the client."); + } + } + if (tries == totalAttempts) { + throw new RuntimeException("The server/client communications timed-out after " + totalAttempts + " tries."); + } + } + } + + private static void runServer(String protocol) throws Exception { + // args: protocol + Process clientProcess = null; + try (DTLSServer server = new DTLSServer(protocol)) { + List command = List.of( + Path.of(System.getProperty("java.home"), "bin", "java").toString(), + "DTLSWontNegotiateV10", + // if server is "DTLS" then the client should be v1.0 and vice versa + protocol.equals(DTLS) ? DTLSV_1_0 : DTLS, + Integer.toString(server.getListeningPortNumber()) + ); + + ProcessBuilder builder = new ProcessBuilder(command); + clientProcess = builder.inheritIO().start(); + server.run(); + System.out.println("Success: DTLSv1.0 connection was not established."); + + } finally { + if (clientProcess != null) { + clientProcess.destroy(); } } } @@ -89,6 +114,9 @@ private static class DTLSClient extends DTLSEndpoint { public DTLSClient(String protocol, int portNumber) throws Exception { super(true, protocol); remotePort = portNumber; + socket.setSoTimeout(READ_TIMEOUT_SECS * 1000); + log("Client listening on port " + socket.getLocalPort() + + ". Sending data to server port " + remotePort); log("Enabled protocols: " + String.join(" ", engine.getEnabledProtocols())); } @@ -287,6 +315,8 @@ private static class DTLSServer extends DTLSEndpoint implements AutoCloseable { public DTLSServer(String protocol) throws Exception { super(false, protocol); + socket.setSoTimeout(READ_TIMEOUT_SECS * 1000); + log("Server listening on port: " + socket.getLocalPort()); log("Enabled protocols: " + String.join(" ", engine.getEnabledProtocols())); } From 45e20c5a5ca65bae64bbd33309a047fef5735f8f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:28:18 +0000 Subject: [PATCH 029/298] 8311792: java/net/httpclient/ResponsePublisher.java fails intermittently with AssertionError: Found some outstanding operations Backport-of: 1664e793eb725d6328751657d5718df96175da29 --- .../net/httpclient/ResponsePublisher.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/jdk/java/net/httpclient/ResponsePublisher.java b/test/jdk/java/net/httpclient/ResponsePublisher.java index b74329e1360..e8d76430946 100644 --- a/test/jdk/java/net/httpclient/ResponsePublisher.java +++ b/test/jdk/java/net/httpclient/ResponsePublisher.java @@ -36,6 +36,7 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.internal.net.http.common.OperationTrackers; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -100,6 +101,16 @@ public class ResponsePublisher implements HttpServerAdapters { // a shared executor helps reduce the amount of threads created by the test static final Executor executor = Executors.newCachedThreadPool(); + static final long start = System.nanoTime(); + + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } + interface BHS extends Supplier>>> { static BHS of(BHS impl, String name) { return new BHSImpl(impl, name); @@ -216,6 +227,12 @@ public void testExceptions(String uri, boolean sameClient, BHS handlers) throws // Get the final result and compare it with the expected body String body = ofString.getBody().toCompletableFuture().get(); assertEquals(body, ""); + // ensure client closes before next iteration + if (!sameClient) { + var tracker = TRACKER.getTracker(client); + client = null; + clientCleanup(tracker); + } } } @@ -239,6 +256,12 @@ public void testNoBody(String uri, boolean sameClient, BHS handlers) throws Exce // Get the final result and compare it with the expected body String body = ofString.getBody().toCompletableFuture().get(); assertEquals(body, ""); + // ensure client closes before next iteration + if (!sameClient) { + var tracker = TRACKER.getTracker(client); + client = null; + clientCleanup(tracker); + } } } @@ -265,6 +288,12 @@ public void testNoBodyAsync(String uri, boolean sameClient, BHS handlers) throws }); // Get the final result and compare it with the expected body assertEquals(result.get(), ""); + // ensure client closes before next iteration + if (!sameClient) { + var tracker = TRACKER.getTracker(client); + client = null; + clientCleanup(tracker); + } } } @@ -288,6 +317,12 @@ public void testAsString(String uri, boolean sameClient, BHS handlers) throws Ex // Get the final result and compare it with the expected body String body = ofString.getBody().toCompletableFuture().get(); assertEquals(body, WITH_BODY); + // ensure client closes before next iteration + if (!sameClient) { + var tracker = TRACKER.getTracker(client); + client = null; + clientCleanup(tracker); + } } } @@ -314,6 +349,12 @@ public void testAsStringAsync(String uri, boolean sameClient, BHS handlers) thro // Get the final result and compare it with the expected body String body = result.get(); assertEquals(body, WITH_BODY); + // ensure client closes before next iteration + if (!sameClient) { + var tracker = TRACKER.getTracker(client); + client = null; + clientCleanup(tracker); + } } } @@ -451,6 +492,23 @@ public void teardown() throws Exception { } } + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because we want to get some diagnosis if a client doesn't release + // its resources and terminates as expected + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + public void clientCleanup(OperationTrackers.Tracker tracker){ + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } + static final String WITH_BODY = "Lorem ipsum dolor sit amet, consectetur" + " adipiscing elit, sed do eiusmod tempor incididunt ut labore et" + " dolore magna aliqua. Ut enim ad minim veniam, quis nostrud" + From 5838aed21e1715be0e5eed00a0efed4d0332f44c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:29:30 +0000 Subject: [PATCH 030/298] 8314824: Fix serviceability/jvmti/8036666/GetObjectLockCount.java to use vm flags Backport-of: 93e82c01460a70f214653a558d53c1c6180ae0d3 --- .../serviceability/jvmti/8036666/GetObjectLockCount.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/8036666/GetObjectLockCount.java b/test/hotspot/jtreg/serviceability/jvmti/8036666/GetObjectLockCount.java index 70b525f552e..e34da9013d5 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/8036666/GetObjectLockCount.java +++ b/test/hotspot/jtreg/serviceability/jvmti/8036666/GetObjectLockCount.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2014 SAP SE. All rights reserved. + * Copyright (c) 2023, 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 @@ -56,12 +57,14 @@ import com.sun.jdi.request.ClassPrepareRequest; import com.sun.jdi.request.EventRequestManager; +import jdk.test.lib.Utils; /* * @test GetObjectLockCount.java * @bug 8036666 * @summary verify jvm returns correct lock recursion count * @requires vm.jvmti + * @library /test/lib * @run compile -g RecursiveObjectLock.java * @run main/othervm GetObjectLockCount * @author axel.siebenborn@sap.com @@ -71,8 +74,6 @@ public class GetObjectLockCount { public static final String CLASS_NAME = "RecursiveObjectLock"; public static final String METHOD_NAME = "breakpoint1"; - public static final String ARGUMENTS = ""; - /** * Find a com.sun.jdi.CommandLineLaunch connector @@ -119,7 +120,7 @@ static Map connectorArguments(LaunchingConnector con if (optionsArg == null) { throw new Error("Bad launching connector"); } - optionsArg.setValue(ARGUMENTS); + optionsArg.setValue(String.join(" ", Utils.getTestJavaOpts())); return arguments; } From e7994c1d6a74c8d9e1a7d0002a8a028e102bda54 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:30:39 +0000 Subject: [PATCH 031/298] 8303525: Refactor/cleanup open/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java Backport-of: 704c6ea16cabc217588f430fd3c302d6df5e9c19 --- .../rmi/ssl/SSLSocketParametersTest.java | 156 +++++------------- test/lib/jdk/test/lib/Asserts.java | 40 +++++ 2 files changed, 81 insertions(+), 115 deletions(-) diff --git a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java b/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java index 63d9332f353..6da32894587 100644 --- a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java +++ b/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java @@ -24,6 +24,7 @@ /* * @test * @bug 5016500 + * @library /test/lib/ * @summary Test SslRmi[Client|Server]SocketFactory SSL socket parameters. * @run main/othervm SSLSocketParametersTest 1 * @run main/othervm SSLSocketParametersTest 2 @@ -33,14 +34,15 @@ * @run main/othervm SSLSocketParametersTest 6 * @run main/othervm SSLSocketParametersTest 7 */ +import jdk.test.lib.Asserts; + import java.io.IOException; import java.io.File; import java.io.Serializable; -import java.net.ServerSocket; -import java.net.Socket; +import java.lang.ref.Reference; +import java.rmi.ConnectIOException; import java.rmi.Remote; import java.rmi.RemoteException; -import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.UnicastRemoteObject; import javax.net.ssl.SSLContext; @@ -50,121 +52,30 @@ public class SSLSocketParametersTest implements Serializable { public interface Hello extends Remote { - public String sayHello() throws RemoteException; + String sayHello() throws RemoteException; } - public class HelloImpl extends UnicastRemoteObject implements Hello { - - public HelloImpl(int port, - RMIClientSocketFactory csf, - RMIServerSocketFactory ssf) - throws RemoteException { - super(port, csf, ssf); - } - + public class HelloImpl implements Hello { public String sayHello() { return "Hello World!"; } - - public Remote runServer() throws IOException { - System.out.println("Inside HelloImpl::runServer"); - // Get a remote stub for this RMI object - // - Remote stub = toStub(this); - System.out.println("Stub = " + stub); - return stub; - } - } - - public class HelloClient { - - public void runClient(Remote stub) throws IOException { - System.out.println("Inside HelloClient::runClient"); - // "obj" is the identifier that we'll use to refer - // to the remote object that implements the "Hello" - // interface - Hello obj = (Hello) stub; - String message = obj.sayHello(); - System.out.println(message); - } - } - - public static class ClientFactory extends SslRMIClientSocketFactory { - - public ClientFactory() { - super(); - } - - public Socket createSocket(String host, int port) throws IOException { - System.out.println("ClientFactory::Calling createSocket(" + - host + "," + port + ")"); - return super.createSocket(host, port); - } - } - - public static class ServerFactory extends SslRMIServerSocketFactory { - - public ServerFactory() { - super(); - } - - public ServerFactory(String[] ciphers, - String[] protocols, - boolean need) { - super(ciphers, protocols, need); - } - - public ServerFactory(SSLContext context, - String[] ciphers, - String[] protocols, - boolean need) { - super(context, ciphers, protocols, need); - } - - public ServerSocket createServerSocket(int port) throws IOException { - System.out.println("ServerFactory::Calling createServerSocket(" + - port + ")"); - return super.createServerSocket(port); - } } - public void testRmiCommunication(RMIServerSocketFactory serverFactory, boolean expectException) { - - HelloImpl server = null; + public void testRmiCommunication(RMIServerSocketFactory serverSocketFactory) throws Exception { + HelloImpl server = new HelloImpl(); + Hello stub = (Hello)UnicastRemoteObject.exportObject(server, + 0, new SslRMIClientSocketFactory(), serverSocketFactory); try { - server = new HelloImpl(0, - new ClientFactory(), - serverFactory); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - if (expectException) { - throw new RuntimeException("Test completed without throwing an expected exception."); - } - - } catch (IOException exc) { - if (!expectException) { - throw new RuntimeException("An error occurred during test execution", exc); - } else { - System.out.println("Caught expected exception: " + exc); - } - + String msg = stub.sayHello(); + Asserts.assertEquals("Hello World!", msg); + } finally { + Reference.reachabilityFence(server); } } - private static void testServerFactory(String[] cipherSuites, String[] protocol, String expectedMessage) throws Exception { - try { - new ServerFactory(SSLContext.getDefault(), + private static void testSslServerSocketFactory(String[] cipherSuites, String[] protocol) throws Exception { + new SslRMIServerSocketFactory(SSLContext.getDefault(), cipherSuites, protocol, false); - throw new RuntimeException( - "The expected exception for "+ expectedMessage + " was not thrown."); - } catch (IllegalArgumentException exc) { - // expecting an exception with a specific message - // anything else is an error - if (!exc.getMessage().toLowerCase().contains(expectedMessage)) { - throw exc; - } - } } public void runTest(int testNumber) throws Exception { @@ -172,34 +83,49 @@ public void runTest(int testNumber) throws Exception { switch (testNumber) { /* default constructor - default config */ - case 1 -> testRmiCommunication(new ServerFactory(), false); + case 1 -> + testRmiCommunication(new SslRMIServerSocketFactory()); /* non-default constructor - default config */ - case 2 -> testRmiCommunication(new ServerFactory(null, null, false), false); + case 2 -> + testRmiCommunication(new SslRMIServerSocketFactory(null, null, false)); /* needClientAuth=true */ - case 3 -> testRmiCommunication(new ServerFactory(null, null, null, true), false); + case 3 -> + testRmiCommunication(new SslRMIServerSocketFactory(null, null, null, true)); /* server side dummy_ciphersuite */ - case 4 -> - testServerFactory(new String[]{"dummy_ciphersuite"}, null, "unsupported ciphersuite"); + case 4 -> { + Exception exc = Asserts.assertThrows(IllegalArgumentException.class, + () -> testSslServerSocketFactory(new String[]{"dummy_ciphersuite"}, null)); + if (!exc.getMessage().toLowerCase().contains("unsupported ciphersuite")) { + throw exc; + } + } /* server side dummy_protocol */ - case 5 -> - testServerFactory(null, new String[]{"dummy_protocol"}, "unsupported protocol"); + case 5 -> { + Exception thrown = Asserts.assertThrows(IllegalArgumentException.class, + () -> testSslServerSocketFactory(null, new String[]{"dummy_protocol"})); + if (!thrown.getMessage().toLowerCase().contains("unsupported protocol")) { + throw thrown; + } + } /* client side dummy_ciphersuite */ case 6 -> { System.setProperty("javax.rmi.ssl.client.enabledCipherSuites", "dummy_ciphersuite"); - testRmiCommunication(new ServerFactory(), true); + Asserts.assertThrows(ConnectIOException.class, + () -> testRmiCommunication(new SslRMIServerSocketFactory())); } /* client side dummy_protocol */ case 7 -> { System.setProperty("javax.rmi.ssl.client.enabledProtocols", "dummy_protocol"); - testRmiCommunication(new ServerFactory(), true); + Asserts.assertThrows(ConnectIOException.class, + () -> testRmiCommunication(new SslRMIServerSocketFactory())); } default -> diff --git a/test/lib/jdk/test/lib/Asserts.java b/test/lib/jdk/test/lib/Asserts.java index 5abe03d6c47..d503ea8e544 100644 --- a/test/lib/jdk/test/lib/Asserts.java +++ b/test/lib/jdk/test/lib/Asserts.java @@ -552,6 +552,46 @@ public static void assertStringsEqual(String str1, String str2, } } + /** + * A functional interface for executing tests in assertThrownException + */ + @FunctionalInterface + public interface TestMethod { + void execute() throws Throwable; + } + + + public static T assertThrows(Class expected, TestMethod testMethod) { + return assertThrows(expected, testMethod, "An unexpected exception was thrown."); + } + + /** + * Asserts that the given exception (or a subclass of it) is thrown when + * executing the test method. + * + * If the test method throws the correct exception, the exception is returned + * to the caller for additional validation e.g., comparing the exception + * message. + * + * @param expected The expected exception + * @param testMethod The code to execute that should throw the exception + * @param msg A description of the assumption + * @return The thrown exception. + */ + public static T assertThrows(Class expected, TestMethod testMethod, String msg) { + try { + testMethod.execute(); + } catch (Throwable exc) { + if (expected.isInstance(exc)) { + return (T) exc; + } else { + fail(Objects.toString(msg, "An unexpected exception was thrown.") + + " Expected " + expected.getName(), exc); + } + } + throw new RuntimeException("No exception was thrown. Expected: " + expected.getName()); + } + /** * Returns a string formatted with a message and expected and actual values. * @param lhs the actual value From 0b01febb9e8e1682b993e32e36a2e762d7e47301 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:33:50 +0000 Subject: [PATCH 032/298] 8319757: java/nio/channels/DatagramChannel/InterruptibleOrNot.java failed: wrong exception thrown Backport-of: ace010b38a83e0c9b43aeeb6bc5c92d0886dc53f --- .../DatagramChannel/InterruptibleOrNot.java | 238 ++++++++++-------- 1 file changed, 132 insertions(+), 106 deletions(-) diff --git a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java index 7d369d7ddd9..794ede84a92 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, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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,7 +25,7 @@ * @test * @bug 8236246 * @modules java.base/sun.nio.ch - * @run testng InterruptibleOrNot + * @run junit InterruptibleOrNot * @summary Test SelectorProviderImpl.openDatagramChannel(boolean) to create * DatagramChannel objects that optionally support interrupt */ @@ -40,152 +40,178 @@ import java.nio.channels.ClosedByInterruptException; import java.nio.channels.DatagramChannel; import java.time.Duration; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import java.util.Arrays; import sun.nio.ch.DefaultSelectorProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.function.Executable; +import static org.junit.jupiter.api.Assertions.*; -@Test public class InterruptibleOrNot { + // DatagramChannel implementation class + private static String dcImplClassName; - public void testInterruptBeforeInterruptibleReceive() throws Exception { - testInterruptBeforeReceive(true); - } - - public void testInterruptDuringInterruptibleReceive() throws Exception { - testInterruptDuringReceive(true); - } - - public void testInterruptBeforeUninterruptibleReceive() throws Exception { - testInterruptBeforeReceive(false); - } - - public void testInterruptDuringUninterruptibleReceive() throws Exception { - testInterruptDuringReceive(false); - } - - public void testInterruptBeforeInterruptibleSend() throws Exception { - testInterruptBeforeSend(true); + @BeforeAll + static void setup() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(true)) { + dcImplClassName = dc.getClass().getName(); + } } - public void testInterruptBeforeUninterruptibleSend() throws Exception { - testInterruptBeforeSend(false); + /** + * Call DatagramChannel.receive with the interrupt status set, the DatagramChannel + * is interruptible. + */ + @Test + public void testInterruptBeforeInterruptibleReceive() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(true)) { + ByteBuffer buf = ByteBuffer.allocate(100); + Thread.currentThread().interrupt(); + assertThrows(ClosedByInterruptException.class, () -> dc.receive(buf)); + assertFalse(dc.isOpen()); + } finally { + Thread.interrupted(); // clear interrupt status + } } /** - * Test invoking DatagramChannel receive with interrupt status set + * Test interrupting a thread blocked in DatagramChannel.receive, the DatagramChannel + * is interruptible. */ - static void testInterruptBeforeReceive(boolean interruptible) - throws Exception - { - try (DatagramChannel dc = openDatagramChannel(interruptible)) { - dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); - Future timeout = scheduleClose(dc, Duration.ofSeconds(2)); - try { - ByteBuffer buf = ByteBuffer.allocate(100); - Thread.currentThread().interrupt(); - assertThrows(expectedException(interruptible), () -> dc.receive(buf)); - } finally { - timeout.cancel(false); - } + @Test + public void testInterruptDuringInterruptibleReceive() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(true)) { + ByteBuffer buf = ByteBuffer.allocate(100); + Thread thread = Thread.currentThread(); + onReceive(thread::interrupt); + assertThrows(ClosedByInterruptException.class, () -> dc.receive(buf)); + assertFalse(dc.isOpen()); } finally { - Thread.interrupted(); // clear interrupt + Thread.interrupted(); // clear interrupt status } } /** - * Test Thread.interrupt when target thread is blocked in DatagramChannel receive + * Call DatagramChannel.receive with the interrupt status set, the DatagramChannel + * is not interruptible. */ - static void testInterruptDuringReceive(boolean interruptible) - throws Exception - { - try (DatagramChannel dc = openDatagramChannel(interruptible)) { - dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); - Future timerTask = scheduleClose(dc, Duration.ofSeconds(5)); - Future interruptTask = scheduleInterrupt(Thread.currentThread(), Duration.ofSeconds(1)); - try { - ByteBuffer buf = ByteBuffer.allocate(100); - assertThrows(expectedException(interruptible), () -> dc.receive(buf)); - } finally { - timerTask.cancel(false); - interruptTask.cancel(false); - } + @Test + public void testInterruptBeforeUninterruptibleReceive() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(false)) { + ByteBuffer buf = ByteBuffer.allocate(100); + onReceive(() -> { + // close the channel after a delay to ensure receive wakes up + Thread.sleep(1000); + dc.close(); + }); + Thread.currentThread().interrupt(); + assertThrows(AsynchronousCloseException.class, () -> dc.receive(buf)); + assertFalse(dc.isOpen()); } finally { - Thread.interrupted(); // clear interrupt + Thread.interrupted(); // clear interrupt status } } /** - * Test invoking DatagramChannel send with interrupt status set + * Test interrupting a thread blocked in DatagramChannel.receive, the DatagramChannel + * is not interruptible. */ - static void testInterruptBeforeSend(boolean interruptible) - throws Exception - { - try (DatagramChannel dc = openDatagramChannel(interruptible)) { - dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); - Future timeout = scheduleClose(dc, Duration.ofSeconds(2)); - try { - ByteBuffer buf = ByteBuffer.allocate(100); - SocketAddress target = dc.getLocalAddress(); - Thread.currentThread().interrupt(); - if (interruptible) { - assertThrows(ClosedByInterruptException.class, () -> dc.send(buf, target)); - } else { - int n = dc.send(buf, target); - assertTrue(n == 100); - } - } finally { - timeout.cancel(false); - } + @Test + public void testInterruptDuringUninterruptibleReceive() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(true)) { + ByteBuffer buf = ByteBuffer.allocate(100); + + Thread thread = Thread.currentThread(); + onReceive(() -> { + // interrupt should not cause the receive to wakeup + thread.interrupt(); + + // close the channel after a delay to ensure receive wakes up + Thread.sleep(1000); + dc.close(); + }); + assertThrows(AsynchronousCloseException.class, () -> dc.receive(buf)); + assertFalse(dc.isOpen()); } finally { - Thread.interrupted(); // clear interrupt + Thread.interrupted(); // clear interrupt status } } /** - * Creates a DatagramChannel that is interruptible or not. + * Call DatagramChannel.send with the interrupt status set, the DatagramChannel + * is interruptible. */ - static DatagramChannel openDatagramChannel(boolean interruptible) throws IOException { - if (interruptible) { - return DatagramChannel.open(); - } else { - return DefaultSelectorProvider.get().openUninterruptibleDatagramChannel(); + @Test + public void testInterruptBeforeInterruptibleSend() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(true)) { + ByteBuffer buf = ByteBuffer.allocate(100); + SocketAddress target = dc.getLocalAddress(); + Thread.currentThread().interrupt(); + assertThrows(ClosedByInterruptException.class, () -> dc.send(buf, target)); + assertFalse(dc.isOpen()); + } finally { + Thread.interrupted(); // clear interrupt } } /** - * Expect ClosedByInterruptException if interruptible. + * Call DatagramChannel.send with the interrupt status set, the DatagramChannel + * is not interruptible. */ - static Class expectedException(boolean expectInterrupt) { - if (expectInterrupt) { - return ClosedByInterruptException.class; - } else { - return AsynchronousCloseException.class; + @Test + public void testInterruptBeforeUninterruptibleSend() throws Exception { + try (DatagramChannel dc = boundDatagramChannel(false)) { + ByteBuffer buf = ByteBuffer.allocate(100); + SocketAddress target = dc.getLocalAddress(); + Thread.currentThread().interrupt(); + int n = dc.send(buf, target); + assertEquals(100, n); + assertTrue(dc.isOpen()); + } finally { + Thread.interrupted(); // clear interrupt status } } /** - * Schedule the given object to be closed. + * Creates a DatagramChannel that is interruptible or not, and bound to the loopback + * address. */ - static Future scheduleClose(Closeable c, Duration timeout) { - long nanos = TimeUnit.NANOSECONDS.convert(timeout); - return STPE.schedule(() -> { - c.close(); - return null; - }, nanos, TimeUnit.NANOSECONDS); + static DatagramChannel boundDatagramChannel(boolean interruptible) throws IOException { + DatagramChannel dc; + if (interruptible) { + dc = DatagramChannel.open(); + } else { + dc = DefaultSelectorProvider.get().openUninterruptibleDatagramChannel(); + } + try { + dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } catch (IOException ioe) { + dc.close(); + throw ioe; + } + return dc; } /** - * Schedule the given thread to be interrupted. + * Runs the given action when the current thread is sampled in DatagramChannel.receive. */ - static Future scheduleInterrupt(Thread t, Duration timeout) { - long nanos = TimeUnit.NANOSECONDS.convert(timeout); - return STPE.schedule(t::interrupt, nanos, TimeUnit.NANOSECONDS); + static void onReceive(Executable action) { + Thread target = Thread.currentThread(); + Thread.ofPlatform().daemon().start(() -> { + try { + boolean found = false; + while (!found) { + Thread.sleep(20); + StackTraceElement[] stack = target.getStackTrace(); + found = Arrays.stream(stack) + .anyMatch(e -> dcImplClassName.equals(e.getClassName()) + && "receive".equals(e.getMethodName())); + } + action.execute(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + }); } - - static final ScheduledExecutorService STPE = Executors.newScheduledThreadPool(0); } From d4823c21e106f22d00d9d86d49c38fc01f061e5c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:35:32 +0000 Subject: [PATCH 033/298] 8322477: order of subclasses in the permits clause can differ between compilations Reviewed-by: mdoerr Backport-of: 5ba69e17340cf44194c080a38219c6e150418fcf --- .../com/sun/tools/javac/code/Symbol.java | 40 ++++++++++++++-- .../com/sun/tools/javac/code/Types.java | 2 +- .../com/sun/tools/javac/comp/Attr.java | 46 +++++++++---------- .../com/sun/tools/javac/comp/Flow.java | 4 +- .../com/sun/tools/javac/comp/TypeEnter.java | 4 +- .../com/sun/tools/javac/jvm/ClassReader.java | 4 +- .../com/sun/tools/javac/jvm/ClassWriter.java | 8 ++-- .../JavacProcessingEnvironment.java | 2 +- .../sealed/SealedDiffConfigurationsTest.java | 35 +++++++++++++- 9 files changed, 106 insertions(+), 39 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java index 9e08a8cdd83..7a939abb38c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java @@ -27,6 +27,7 @@ import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -1300,10 +1301,12 @@ public static class ClassSymbol extends TypeSymbol implements TypeElement { // sealed classes related fields /** The classes, or interfaces, permitted to extend this class, or interface */ - public List permitted; + private java.util.List permitted; public boolean isPermittedExplicit = false; + private record PermittedClassWithPos(Symbol permittedClass, int pos) {} + public ClassSymbol(long flags, Name name, Type type, Symbol owner) { super(TYP, flags, name, type, owner); this.members_field = null; @@ -1312,7 +1315,7 @@ public ClassSymbol(long flags, Name name, Type type, Symbol owner) { this.sourcefile = null; this.classfile = null; this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); - this.permitted = List.nil(); + this.permitted = new ArrayList<>(); } public ClassSymbol(long flags, Name name, Symbol owner) { @@ -1324,6 +1327,37 @@ public ClassSymbol(long flags, Name name, Symbol owner) { this.type.tsym = this; } + public void addPermittedSubclass(ClassSymbol csym, int pos) { + Assert.check(!isPermittedExplicit); + // we need to insert at the right pos + PermittedClassWithPos element = new PermittedClassWithPos(csym, pos); + int index = Collections.binarySearch(permitted, element, java.util.Comparator.comparing(PermittedClassWithPos::pos)); + if (index < 0) { + index = -index - 1; + } + permitted.add(index, element); + } + + public boolean isPermittedSubclass(Symbol csym) { + for (PermittedClassWithPos permittedClassWithPos : permitted) { + if (permittedClassWithPos.permittedClass.equals(csym)) { + return true; + } + } + return false; + } + + public void clearPermittedSubclasses() { + permitted.clear(); + } + + public void setPermittedSubclasses(List permittedSubs) { + permitted.clear(); + for (Symbol csym : permittedSubs) { + permitted.add(new PermittedClassWithPos(csym, 0)); + } + } + /** The Java source which this symbol represents. */ public String toString() { @@ -1640,7 +1674,7 @@ public boolean isRecord() { @DefinedBy(Api.LANGUAGE_MODEL) public List getPermittedSubclasses() { - return permitted.map(s -> s.type); + return permitted.stream().map(s -> s.permittedClass().type).collect(List.collector()); } @Override @DefinedBy(Api.LANGUAGE_MODEL) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java index c9e4eafa08a..f4e2ea66fc2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java @@ -1693,7 +1693,7 @@ private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) { // permitted subtypes have to be disjoint with the other symbol ClassSymbol sealedOne = ts.isSealed() ? ts : ss; ClassSymbol other = sealedOne == ts ? ss : ts; - return sealedOne.permitted.stream().allMatch(sym -> areDisjoint((ClassSymbol)sym, other)); + return sealedOne.getPermittedSubclasses().stream().allMatch(type -> areDisjoint((ClassSymbol)type.tsym, other)); } return false; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index d7313ea2067..e90ff143bc2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -5406,58 +5406,58 @@ void attribClass(ClassSymbol c) throws CompletionFailure { if (c.isSealed() && !c.isEnum() && !c.isPermittedExplicit && - c.permitted.isEmpty()) { + c.getPermittedSubclasses().isEmpty()) { log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.SealedClassMustHaveSubclasses); } if (c.isSealed()) { Set permittedTypes = new HashSet<>(); boolean sealedInUnnamed = c.packge().modle == syms.unnamedModule || c.packge().modle == syms.noModule; - for (Symbol subTypeSym : c.permitted) { + for (Type subType : c.getPermittedSubclasses()) { boolean isTypeVar = false; - if (subTypeSym.type.getTag() == TYPEVAR) { + if (subType.getTag() == TYPEVAR) { isTypeVar = true; //error recovery - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), - Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subTypeSym.type))); + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree), + Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subType))); } - if (subTypeSym.isAnonymous() && !c.isEnum()) { - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), Errors.LocalClassesCantExtendSealed(Fragments.Anonymous)); + if (subType.tsym.isAnonymous() && !c.isEnum()) { + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree), Errors.LocalClassesCantExtendSealed(Fragments.Anonymous)); } - if (permittedTypes.contains(subTypeSym)) { + if (permittedTypes.contains(subType.tsym)) { DiagnosticPosition pos = env.enclClass.permitting.stream() - .filter(permittedExpr -> TreeInfo.diagnosticPositionFor(subTypeSym, permittedExpr, true) != null) + .filter(permittedExpr -> TreeInfo.diagnosticPositionFor(subType.tsym, permittedExpr, true) != null) .limit(2).collect(List.collector()).get(1); - log.error(pos, Errors.InvalidPermitsClause(Fragments.IsDuplicated(subTypeSym.type))); + log.error(pos, Errors.InvalidPermitsClause(Fragments.IsDuplicated(subType))); } else { - permittedTypes.add(subTypeSym); + permittedTypes.add(subType.tsym); } if (sealedInUnnamed) { - if (subTypeSym.packge() != c.packge()) { - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), + if (subType.tsym.packge() != c.packge()) { + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree), Errors.ClassInUnnamedModuleCantExtendSealedInDiffPackage(c) ); } - } else if (subTypeSym.packge().modle != c.packge().modle) { - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), + } else if (subType.tsym.packge().modle != c.packge().modle) { + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree), Errors.ClassInModuleCantExtendSealedInDiffModule(c, c.packge().modle) ); } - if (subTypeSym == c.type.tsym || types.isSuperType(subTypeSym.type, c.type)) { - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, ((JCClassDecl)env.tree).permitting), + if (subType.tsym == c.type.tsym || types.isSuperType(subType, c.type)) { + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, ((JCClassDecl)env.tree).permitting), Errors.InvalidPermitsClause( - subTypeSym == c.type.tsym ? + subType.tsym == c.type.tsym ? Fragments.MustNotBeSameClass : - Fragments.MustNotBeSupertype(subTypeSym.type) + Fragments.MustNotBeSupertype(subType) ) ); } else if (!isTypeVar) { - boolean thisIsASuper = types.directSupertypes(subTypeSym.type) + boolean thisIsASuper = types.directSupertypes(subType) .stream() .anyMatch(d -> d.tsym == c); if (!thisIsASuper) { - log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), - Errors.InvalidPermitsClause(Fragments.DoesntExtendSealed(subTypeSym.type))); + log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree), + Errors.InvalidPermitsClause(Fragments.DoesntExtendSealed(subType))); } } } @@ -5492,7 +5492,7 @@ void attribClass(ClassSymbol c) throws CompletionFailure { if (!c.type.isCompound()) { for (ClassSymbol supertypeSym : sealedSupers) { - if (!supertypeSym.permitted.contains(c.type.tsym)) { + if (!supertypeSym.isPermittedSubclass(c.type.tsym)) { log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym)); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 2fe5183bb11..dd7b3c8cdc4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -920,8 +920,8 @@ private Set allPermittedSubTypes(ClassSymbol root, Predicate baseEnv) { !supClass.isPermittedExplicit && supClassEnv != null && supClassEnv.toplevel == baseEnv.toplevel) { - supClass.permitted = supClass.permitted.append(sym); + supClass.addPermittedSubclass(sym, tree.pos); } } } @@ -933,7 +933,7 @@ private void fillPermits(JCClassDecl tree, Env baseEnv) { Type pt = attr.attribBase(permitted, baseEnv, false, false, false); permittedSubtypeSymbols.append(pt.tsym); } - sym.permitted = permittedSubtypeSymbols.toList(); + sym.setPermittedSubclasses(permittedSubtypeSymbols.toList()); } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java index e0e6ff6adb1..ac24377997d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1296,7 +1296,7 @@ protected void read(Symbol sym, int attrLen) { for (int i = 0; i < numberOfPermittedSubtypes; i++) { subtypes.add(poolReader.getClass(nextChar())); } - ((ClassSymbol)sym).permitted = subtypes.toList(); + ((ClassSymbol)sym).setPermittedSubclasses(subtypes.toList()); } } }, @@ -2613,7 +2613,7 @@ void readClass(ClassSymbol c) { for (int i = 0; i < methodCount; i++) skipMember(); readClassAttrs(c); - if (c.permitted != null && !c.permitted.isEmpty()) { + if (!c.getPermittedSubclasses().isEmpty()) { c.flags_field |= SEALED; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index aed63c44bb1..625d3fb890b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -922,11 +922,11 @@ private void listNested(Symbol sym, ListBuffer seen) { /** Write "PermittedSubclasses" attribute. */ int writePermittedSubclassesIfNeeded(ClassSymbol csym) { - if (csym.permitted.nonEmpty()) { + if (csym.getPermittedSubclasses().nonEmpty()) { int alenIdx = writeAttr(names.PermittedSubclasses); - databuf.appendChar(csym.permitted.size()); - for (Symbol c : csym.permitted) { - databuf.appendChar(poolWriter.putClass((ClassSymbol) c)); + databuf.appendChar(csym.getPermittedSubclasses().size()); + for (Type t : csym.getPermittedSubclasses()) { + databuf.appendChar(poolWriter.putClass((ClassSymbol) t.tsym)); } endAttr(alenIdx); return 1; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 028b8ba8f9f..c9fba238901 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1643,7 +1643,7 @@ public void visitClassDef(JCClassDecl node) { originalAnnos.forEach(a -> visitAnnotation(a)); } // we should empty the list of permitted subclasses for next round - node.sym.permitted = List.nil(); + node.sym.clearPermittedSubclasses(); } node.sym = null; } diff --git a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java index 0e7e37e6547..bda7b2e22a5 100644 --- a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java +++ b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java @@ -140,7 +140,6 @@ private void checkSealedClassFile(Path out, String cfName, List expected } catch (ConstantPoolException ex) { } }); - subtypeNames.sort((s1, s2) -> s1.compareTo(s2)); for (int i = 0; i < expectedSubTypeNames.size(); i++) { Assert.check(expectedSubTypeNames.get(0).equals(subtypeNames.get(0))); } @@ -693,4 +692,38 @@ public void testSupertypePermitsLoop(Path base) throws Exception { .run() .writeAll(); } + + @Test + public void testClientSwapsPermittedSubclassesOrder(Path base) throws Exception { + Path src = base.resolve("src"); + Path foo = src.resolve("Foo.java"); + Path fooUser = src.resolve("FooUser.java"); + + tb.writeFile(foo, + """ + public sealed interface Foo { + record R1() implements Foo {} + record R2() implements Foo {} + } + """); + + tb.writeFile(fooUser, + """ + public class FooUser { + // see that the order of arguments differ from the order of subclasses of Foo in the source above + // we need to check that the order of permitted subclasses of Foo in the class file corresponds to the + // original order in the source code + public void blah(Foo.R2 a, Foo.R1 b) {} + } + """); + + Path out = base.resolve("out"); + Files.createDirectories(out); + + new JavacTask(tb) + .outdir(out) + .files(fooUser, foo) + .run(); + checkSealedClassFile(out, "Foo.class", List.of("Foo$R1", "Foo$R2")); + } } From 40f0254b435080cda6b3db02f979155f34b7cc1b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:40:54 +0000 Subject: [PATCH 034/298] 8323276: StressDirListings.java fails on AIX Backport-of: e5aed6be7a184a86a32fa671d48e0781fab54183 --- .../sun/net/httpserver/simpleserver/StressDirListings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/StressDirListings.java b/test/jdk/com/sun/net/httpserver/simpleserver/StressDirListings.java index c74d800860e..8197fd436e7 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/StressDirListings.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/StressDirListings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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,7 +25,7 @@ * @test * @summary Test to stress directory listings * @library /test/lib - * @run testng/othervm/timeout=180 StressDirListings + * @run testng/othervm/timeout=180 -Dsun.net.httpserver.nodelay=true StressDirListings */ import java.io.IOException; From ab6e02744fed7d26b4b45ac3f10ebcdd5bb55a06 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 10:44:22 +0000 Subject: [PATCH 035/298] 8320712: Rewrite BadFactoryTest in pure Java Backport-of: 66971600f7ba796ff5bb9714591c3faa0bb2249d --- .../script/JDK_8196959/BadFactoryTest.java | 28 ++++++++- .../script/JDK_8196959/BadFactoryTest.sh | 60 ------------------- 2 files changed, 26 insertions(+), 62 deletions(-) delete mode 100644 test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java index 9f02c61511d..36e3391be7f 100644 --- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java +++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -21,10 +21,34 @@ * questions. */ +import org.junit.jupiter.api.Test; + +import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertTrue; +/* + * @test + * @bug 8196959 8320712 + * @summary Verify that ScriptEngineManager can load BadFactory without throwing NPE + * @build BadFactory BadFactoryTest + * @run junit/othervm BadFactoryTest + * @run junit/othervm -Djava.security.manager=allow BadFactoryTest + */ public class BadFactoryTest { - public static void main(String[] args) { + + @Test + public void scriptEngineManagerShouldLoadBadFactory() { + // Check that ScriptEngineManager initializes even in the + // presence of a ScriptEngineFactory returning nulls ScriptEngineManager m = new ScriptEngineManager(); + + // Sanity check that ScriptEngineManager actually found the BadFactory + Optional badFactory = m.getEngineFactories().stream() + .filter(fac -> fac.getClass() == BadFactory.class) + .findAny(); + assertTrue(badFactory.isPresent(), "BadFactory not found"); } } diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh deleted file mode 100644 index e5d1a063840..00000000000 --- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 8196959 -# @summary BadFactory that results in NPE being thrown from ScriptEngineManager -# -# @build BadFactory BadFactoryTest -# @run shell BadFactoryTest.sh - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -. ${TESTSRC}/../CommonSetup.sh - -echo "Creating JAR file ..." - -$JAR ${TESTTOOLVMOPTS} -cf ${TESTCLASSES}/badfactory.jar \ - -C ${TESTCLASSES} BadFactory.class \ - -C ${TESTCLASSES} BadFactoryTest.class \ - -C "${TESTSRC}" META-INF/services/javax.script.ScriptEngineFactory - -echo "Running test with security manager ..." -$JAVA ${TESTVMOPTS} -Djava.security.manager -classpath \ - "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \ - BadFactoryTest - -ret=$? -if [ $ret -ne 0 ] -then - exit $ret -fi - -echo "Running test without security manager ..." -$JAVA ${TESTVMOPTS} -classpath \ - "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \ - BadFactoryTest From 315d051f6842120f233bb5b7dd488cabcd2e968d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 7 Mar 2024 11:42:14 +0000 Subject: [PATCH 036/298] 8314828: Mark 3 jcmd command-line options test as vm.flagless 8316228: jcmd tests are broken by 8314828 Backport-of: 23fab1181b6a053efc4661d5a10caa90b109aa06 --- test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java | 3 ++- .../serviceability/dcmd/framework/InvalidCommandTest.java | 3 ++- .../jtreg/serviceability/dcmd/framework/VMVersionTest.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java index 5e159aaeb9e..7d88faaaa30 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -34,6 +34,7 @@ * @summary Test of diagnostic command help (tests all DCMD executors) * @library /test/lib * /vmTestbase + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.compiler * java.management diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java index 178216fe89c..1d44b16dcdd 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -34,6 +34,7 @@ * @summary Test of invalid diagnostic command (tests all DCMD executors) * @library /test/lib * /vmTestbase + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.compiler * java.management diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java index 97891d408ef..4b1d486640a 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java @@ -27,7 +27,6 @@ import jdk.test.lib.dcmd.MainClassJcmdExecutor; import jdk.test.lib.dcmd.FileJcmdExecutor; import jdk.test.lib.dcmd.JMXExecutor; -import nsk.share.jdi.ArgumentHandler; import org.testng.annotations.Test; @@ -45,6 +44,7 @@ * jdk.internal.jvmstat/sun.jvmstat.monitor * @library /test/lib * /vmTestbase + * @requires vm.flagless * @run testng/othervm -XX:+UsePerfData VMVersionTest */ public class VMVersionTest { From c26cad30271780e72b1f7e25457760785bf7a8e3 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Thu, 7 Mar 2024 15:10:20 +0000 Subject: [PATCH 037/298] 8278527: java/util/concurrent/tck/JSR166TestCase.java fails nanoTime test Backport-of: 54f09d734584a71c648520664447f8395050adbe --- .../util/concurrent/tck/JSR166TestCase.java | 1 - .../java/util/concurrent/tck/SystemTest.java | 75 ------------------- 2 files changed, 76 deletions(-) delete mode 100644 test/jdk/java/util/concurrent/tck/SystemTest.java diff --git a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java index 1f5a6e09683..21aa43e1816 100644 --- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java +++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java @@ -602,7 +602,6 @@ public static Test suite() { ScheduledExecutorSubclassTest.suite(), SemaphoreTest.suite(), SynchronousQueueTest.suite(), - SystemTest.suite(), ThreadLocalTest.suite(), ThreadPoolExecutorTest.suite(), ThreadPoolExecutorSubclassTest.suite(), diff --git a/test/jdk/java/util/concurrent/tck/SystemTest.java b/test/jdk/java/util/concurrent/tck/SystemTest.java deleted file mode 100644 index c34bdabea31..00000000000 --- a/test/jdk/java/util/concurrent/tck/SystemTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. - */ - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class SystemTest extends JSR166TestCase { - public static void main(String[] args) { - main(suite(), args); - } - - public static Test suite() { - return new TestSuite(SystemTest.class); - } - - /** - * Worst case rounding for millisecs; set for 60 cycle millis clock. - * This value might need to be changed on JVMs with coarser - * System.currentTimeMillis clocks. - */ - static final long MILLIS_ROUND = 17; - - /** - * Nanos between readings of millis is no longer than millis (plus - * possible rounding), and vice versa. - * This shows only that nano timing not (much) worse than milli. - */ - public void testNanoTime() throws InterruptedException { - long m0 = System.currentTimeMillis(); - long n0 = System.nanoTime(); - Thread.sleep(1); - long m1 = System.currentTimeMillis(); - long n1 = System.nanoTime(); - Thread.sleep(50); // avoid possibly scaled SHORT_DELAY_MS - long m2 = System.currentTimeMillis(); - long n2 = System.nanoTime(); - Thread.sleep(1); - long m3 = System.currentTimeMillis(); - long n3 = System.nanoTime(); - assertTrue((n2 - n1) / 1_000_000 <= m3 - m0 + MILLIS_ROUND); - assertTrue(m2 - m1 <= (n3 - n0) / 1_000_000 + MILLIS_ROUND); - } -} From c4c4b22c0b3ff089ccbe4b3d795d6110ea1f7b37 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Fri, 8 Mar 2024 05:37:04 +0000 Subject: [PATCH 038/298] 8325326: [PPC64] Don't relocate in case of allocation failure Backport-of: 4388095cde20dec602ada9fe2977f1a359ceab91 --- src/hotspot/cpu/ppc/ppc.ad | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 7fe5203aa15..582f19de09b 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2798,15 +2798,16 @@ encode %{ intptr_t val = $src$$constant; relocInfo::relocType constant_reloc = $src->constant_reloc(); // src address const_toc_addr; + RelocationHolder r; // Initializes type to none. if (constant_reloc == relocInfo::oop_type) { // Create an oop constant and a corresponding relocation. - AddressLiteral a = __ allocate_oop_address((jobject)val); + AddressLiteral a = __ constant_oop_address((jobject)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); + r = a.rspec(); } else if (constant_reloc == relocInfo::metadata_type) { + // Notify OOP recorder (don't need the relocation) AddressLiteral a = __ constant_metadata_address((Metadata *)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); } else { // Create a non-oop constant, no relocation needed. const_toc_addr = __ long_constant((jlong)$src$$constant); @@ -2816,6 +2817,7 @@ encode %{ ciEnv::current()->record_out_of_memory_failure(); return; } + __ relocate(r); // If set above. // Get the constant's TOC offset. toc_offset = __ offset_to_method_toc(const_toc_addr); @@ -2829,15 +2831,16 @@ encode %{ intptr_t val = $src$$constant; relocInfo::relocType constant_reloc = $src->constant_reloc(); // src address const_toc_addr; + RelocationHolder r; // Initializes type to none. if (constant_reloc == relocInfo::oop_type) { // Create an oop constant and a corresponding relocation. - AddressLiteral a = __ allocate_oop_address((jobject)val); + AddressLiteral a = __ constant_oop_address((jobject)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); + r = a.rspec(); } else if (constant_reloc == relocInfo::metadata_type) { + // Notify OOP recorder (don't need the relocation) AddressLiteral a = __ constant_metadata_address((Metadata *)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); } else { // non-oop pointers, e.g. card mark base, heap top // Create a non-oop constant, no relocation needed. const_toc_addr = __ long_constant((jlong)$src$$constant); @@ -2847,6 +2850,7 @@ encode %{ ciEnv::current()->record_out_of_memory_failure(); return; } + __ relocate(r); // If set above. // Get the constant's TOC offset. const int toc_offset = __ offset_to_method_toc(const_toc_addr); // Store the toc offset of the constant. From 9a8d91a99ff175c2e72538e2b82c777b04059e59 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Fri, 8 Mar 2024 05:38:20 +0000 Subject: [PATCH 039/298] 8315677: Open source few swing JFileChooser and other tests Backport-of: fe5ef5f20dcf647b4ca30963b42fa01449f0d9c0 --- .../javax/swing/JFileChooser/bug4624353.java | 87 +++++++++++++ .../javax/swing/JFileChooser/bug4673161.java | 70 ++++++++++ .../javax/swing/JFileChooser/bug4782168.java | 40 ++++++ test/jdk/javax/swing/JLabel/bug4822331.java | 120 ++++++++++++++++++ .../javax/swing/JOptionPane/bug4191835.java | 43 +++++++ 5 files changed, 360 insertions(+) create mode 100644 test/jdk/javax/swing/JFileChooser/bug4624353.java create mode 100644 test/jdk/javax/swing/JFileChooser/bug4673161.java create mode 100644 test/jdk/javax/swing/JFileChooser/bug4782168.java create mode 100644 test/jdk/javax/swing/JLabel/bug4822331.java create mode 100644 test/jdk/javax/swing/JOptionPane/bug4191835.java diff --git a/test/jdk/javax/swing/JFileChooser/bug4624353.java b/test/jdk/javax/swing/JFileChooser/bug4624353.java new file mode 100644 index 00000000000..c977cb9ed95 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4624353.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4624353 + * @summary Tests that Motif FileChooser is not able to show control buttons + * @key headful + * @run main bug4624353 + */ + +import java.awt.Component; +import java.awt.Container; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class bug4624353 { + static volatile boolean passed = true; + static JFrame fr; + static JFileChooser fc; + + public static void main(String args[]) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("bug4624353"); + fc = new JFileChooser(); + fc.setControlButtonsAreShown(false); + fr.getContentPane().add(fc); + fr.pack(); + fr.setVisible(true); + + passAround(fc); + }); + if (!passed) { + throw new RuntimeException("Test failed"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static void passAround(Container c) { + Component[] list = c.getComponents(); + if (list.length == 0) { + return; + } + for (int i = 0; i < list.length; i++) { + if (list[i] != null) { + if ((list[i] instanceof JButton) && + "OK".equals(((JButton)list[i]).getText())) { + passed = false; + return; + } + passAround((Container)list[i]); + } + } + } +} diff --git a/test/jdk/javax/swing/JFileChooser/bug4673161.java b/test/jdk/javax/swing/JFileChooser/bug4673161.java new file mode 100644 index 00000000000..82b6a5ea69c --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4673161.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4673161 + * @requires (os.family == "windows") + * @summary Tests if JFileChooser preferred size depends on selected files + * @run main bug4673161 + */ + +import java.awt.Dimension; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.UIManager; + +public class bug4673161 { + + public static void main(String[] args) throws Exception { + JFileChooser fc = new JFileChooser(); + Dimension d = fc.getPreferredSize(); + JFileChooser fc2 = new JFileChooser(); + File[] files = new File[50]; + for (int i = 0; i < 50; i++) { + files[i] = new File("file" + i); + } + fc2.setSelectedFiles(files); + Dimension d2 = fc2.getPreferredSize(); + if (!d.equals(d2)) { + throw new RuntimeException("Test failed: JFileChooser preferred " + + "size depends on selected files"); + } + + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + + JFileChooser fc3 = new JFileChooser(); + d = fc3.getPreferredSize(); + fc2 = new JFileChooser(); + files = new File[50]; + for (int i = 0; i < 50; i++) { + files[i] = new File("file" + i); + } + fc2.setSelectedFiles(files); + d2 = fc2.getPreferredSize(); + if (!d.equals(d2)) { + throw new RuntimeException("Test failed: JFileChooser preferred " + + "size depends on selected files"); + } + } +} diff --git a/test/jdk/javax/swing/JFileChooser/bug4782168.java b/test/jdk/javax/swing/JFileChooser/bug4782168.java new file mode 100644 index 00000000000..0bfeb46ed18 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4782168.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4782168 + * @summary Tests if DefaultShellFolder.isHidden() crashes for the + root folder on Solaris + * @modules java.desktop/sun.awt.shell + * @run main bug4782168 + */ + +public class bug4782168 { + + public static void main(String args[]) throws Exception { + sun.awt.shell.ShellFolder sf = sun.awt.shell.ShellFolder. + getShellFolder(new java.io.File("/")); + sf.isHidden(); + } +} diff --git a/test/jdk/javax/swing/JLabel/bug4822331.java b/test/jdk/javax/swing/JLabel/bug4822331.java new file mode 100644 index 00000000000..5de8d88fc85 --- /dev/null +++ b/test/jdk/javax/swing/JLabel/bug4822331.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4822331 + * @summary setLaberFor does not transfer focus to the JSpinner editor + * @library /test/lib + * @key headful + * @run main bug4822331 + */ + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.FlowLayout; +import java.awt.Robot; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JSpinner; +import javax.swing.SwingUtilities; +import jdk.test.lib.Platform; + +public class bug4822331 { + + static JFrame fr; + static JButton button; + static JSpinner spinner; + static volatile boolean tfFocused = false; + static volatile boolean passed = false; + + public static void main(String []args) throws Exception { + bug4822331 test = new bug4822331(); + test.init(); + } + + public void init() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + fr.getContentPane().setLayout(new FlowLayout()); + + button = new JButton("Button"); + fr.getContentPane().add(button); + + spinner = new JSpinner(); + JLabel spinnerLabel = new JLabel("spinner"); + spinnerLabel.setDisplayedMnemonic(KeyEvent.VK_S); + spinnerLabel.setLabelFor(spinner); + fr.getContentPane().add(spinnerLabel); + fr.getContentPane().add(spinner); + + JSpinner.DefaultEditor editor = + (JSpinner.DefaultEditor) spinner.getEditor(); + JFormattedTextField ftf = editor.getTextField(); + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + passed = true; + } + }); + fr.pack(); + fr.setVisible(true); + }); + start(); + if ( !passed ) { + throw new RuntimeException("The activation of spinner's " + + "mnemonic didn't focus the editor component."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + robot.waitForIdle(); + button.requestFocus(); + if (Platform.isOSX()) { + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_ALT); + robot.keyRelease(KeyEvent.VK_CONTROL); + } else { + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_ALT); + } + } +} diff --git a/test/jdk/javax/swing/JOptionPane/bug4191835.java b/test/jdk/javax/swing/JOptionPane/bug4191835.java new file mode 100644 index 00000000000..17709e9a8b9 --- /dev/null +++ b/test/jdk/javax/swing/JOptionPane/bug4191835.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4191835 + * @summary JOptionPane should allow Dialog as window owner. + * @key headful + * @run main bug4191835 + */ + +import java.awt.Dialog; +import javax.swing.JDialog; +import javax.swing.JOptionPane; + +public class bug4191835 { + + public static void main(String[] args) { + JOptionPane op = new JOptionPane(); + Dialog dlg = new Dialog(new JDialog()); + JDialog jd = op.createDialog(dlg, "Dialog"); + } +} From 8e439ba64ac90610f9a3d03567648e2c432985bc Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Fri, 8 Mar 2024 05:39:33 +0000 Subject: [PATCH 040/298] 8317287: [macos14] InterJVMGetDropSuccessTest.java: Child VM: abnormal termination Backport-of: cbfddf4e1d3ff8dddb95bcb9242b31c175b768fc --- .../InterJVMGetDropSuccessTest.java | 130 +++++++++--------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java b/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java index 3656c44246f..9548bd4fe2f 100644 --- a/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java +++ b/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,16 +29,37 @@ @run main InterJVMGetDropSuccessTest */ -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.dnd.*; -import java.awt.event.*; -import java.io.*; +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.InputStream; public class InterJVMGetDropSuccessTest { private int returnCode = Util.CODE_NOT_RETURNED; - private boolean successCodes[] = { true, false }; + private final boolean[] successCodes = { true, false }; private int dropCount = 0; final Frame frame = new Frame("Target Frame"); @@ -68,7 +89,9 @@ public void start() { frame.setVisible(true); try { - Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(Util.FRAME_ACTIVATION_TIMEOUT); Point p = frame.getLocationOnScreen(); Dimension d = frame.getSize(); @@ -136,10 +159,9 @@ final class Util implements AWTEventListener { public static final int CODE_SECOND_SUCCESS = 0x2; public static final int CODE_FAILURE = 0x1; - public static final int FRAME_ACTIVATION_TIMEOUT = 3000; + public static final int FRAME_ACTIVATION_TIMEOUT = 1000; static final Object SYNC_LOCK = new Object(); - static final int MOUSE_RELEASE_TIMEOUT = 1000; static final Util theInstance = new Util(); @@ -158,45 +180,13 @@ public static int sign(int n) { return n < 0 ? -1 : n == 0 ? 0 : 1; } - private Component clickedComponent = null; - - private void reset() { - clickedComponent = null; - } - public void eventDispatched(AWTEvent e) { if (e.getID() == MouseEvent.MOUSE_RELEASED) { - clickedComponent = (Component)e.getSource(); synchronized (SYNC_LOCK) { SYNC_LOCK.notifyAll(); } } } - - public static boolean pointInComponent(Robot robot, Point p, Component comp) - throws InterruptedException { - return theInstance.pointInComponentImpl(robot, p, comp); - } - - private boolean pointInComponentImpl(Robot robot, Point p, Component comp) - throws InterruptedException { - robot.waitForIdle(); - reset(); - robot.mouseMove(p.x, p.y); - robot.mousePress(InputEvent.BUTTON1_MASK); - synchronized (SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); - SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); - } - - Component c = clickedComponent; - - while (c != null && c != comp) { - c = c.getParent(); - } - - return c == comp; - } } class Child { @@ -226,6 +216,9 @@ public void dragDropEnd(DragSourceDropEvent dsde) { } } + private volatile boolean success1 = false; + private volatile boolean success2 = false; + final Frame frame = new Frame("Source Frame"); final DragSource dragSource = DragSource.getDefaultDragSource(); final DragSourceDropListener dragSourceListener = new DragSourceDropListener(); @@ -258,53 +251,62 @@ public void run(String[] args) { frame.setBounds(300, 200, 150, 150); frame.setVisible(true); - Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(Util.FRAME_ACTIVATION_TIMEOUT); Point sourcePoint = Util.getCenterLocationOnScreen(frame); - Point targetPoint = new Point(x + w / 2, y + h / 2); - Robot robot = new Robot(); robot.mouseMove(sourcePoint.x, sourcePoint.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); for (Point p = new Point(sourcePoint); !p.equals(targetPoint); - p.translate(Util.sign(targetPoint.x - p.x), - Util.sign(targetPoint.y - p.y))) { + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - Thread.sleep(50); + robot.delay(5); } synchronized (Util.SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); } - if (!dragSourceListener.isDropFinished()) { - throw new RuntimeException("Drop not finished"); - } + EventQueue.invokeAndWait(() -> { + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + success1 = dragSourceListener.getDropSuccess(); + dragSourceListener.reset(); + }); - boolean success1 = dragSourceListener.getDropSuccess(); - dragSourceListener.reset(); robot.mouseMove(sourcePoint.x, sourcePoint.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); for (Point p = new Point(sourcePoint); !p.equals(targetPoint); - p.translate(Util.sign(targetPoint.x - p.x), - Util.sign(targetPoint.y - p.y))) { + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - Thread.sleep(50); + robot.delay(5); } synchronized (Util.SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); } - if (!dragSourceListener.isDropFinished()) { - throw new RuntimeException("Drop not finished"); - } + EventQueue.invokeAndWait(() -> { + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + success2 = dragSourceListener.getDropSuccess(); + dragSourceListener.reset(); + }); - boolean success2 = dragSourceListener.getDropSuccess(); int retCode = 0; if (success1) { From 066af44353e5bd3a35f9d3533c45f6e8ef0fd26f Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Fri, 8 Mar 2024 05:39:48 +0000 Subject: [PATCH 041/298] 8325137: com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java can fail in Xcomp with out of expected range Backport-of: 91d8dac9cff5689abcf2fc8950b15d284f933afd --- .../com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java index c7fded7399e..b3c7b064b30 100644 --- a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java +++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -28,6 +28,7 @@ * @summary Basic test of ThreadMXBean.getThreadCpuTime(long[]) and * getThreadUserTime(long[]). * @author Paul Hohensee + * @requires vm.compMode != "Xcomp" */ import java.lang.management.*; From 624e6034a7c068a4338c72cf27df405e357e2cdd Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Fri, 8 Mar 2024 05:42:31 +0000 Subject: [PATCH 042/298] 8315834: Open source several Swing JSpinner related tests Backport-of: 4a63eb05221c1829b157a025a4d35cdd77a9fe04 --- test/jdk/javax/swing/JSpinner/bug4522737.java | 51 ++++++++ test/jdk/javax/swing/JSpinner/bug4656590.java | 117 ++++++++++++++++++ test/jdk/javax/swing/JSpinner/bug4680204.java | 116 +++++++++++++++++ test/jdk/javax/swing/JSpinner/bug4862257.java | 40 ++++++ test/jdk/javax/swing/JSpinner/bug5104421.java | 46 +++++++ 5 files changed, 370 insertions(+) create mode 100644 test/jdk/javax/swing/JSpinner/bug4522737.java create mode 100644 test/jdk/javax/swing/JSpinner/bug4656590.java create mode 100644 test/jdk/javax/swing/JSpinner/bug4680204.java create mode 100644 test/jdk/javax/swing/JSpinner/bug4862257.java create mode 100644 test/jdk/javax/swing/JSpinner/bug5104421.java diff --git a/test/jdk/javax/swing/JSpinner/bug4522737.java b/test/jdk/javax/swing/JSpinner/bug4522737.java new file mode 100644 index 00000000000..60ea8d5c10f --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4522737.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2002, 2023, 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 javax.swing.JComponent; +import javax.swing.JSpinner; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4522737 + * @summary Cannot serialize JSpinner twice. + * @run main bug4522737 + */ + +public class bug4522737 { + public static void main(String[] args) throws Exception { + final JComponent originalComponent = new JSpinner(); + + ByteArrayOutputStream byteArrayOutputStream = + new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = + new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(originalComponent); + + objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(originalComponent); + + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug4656590.java b/test/jdk/javax/swing/JSpinner/bug4656590.java new file mode 100644 index 00000000000..b2cfd3123ee --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4656590.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.SpinnerDateModel; +import javax.swing.SpinnerListModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Robot; + +/* + * @test + * @bug 4656590 + * @summary JSpinner.setFont() does nothing + * @key headful + * @run main bug4656590 + */ + +public class bug4656590 { + private static JSpinner[] spinner = new JSpinner[6]; + private static Font font = new Font("Arial", Font.BOLD, 24); + private static volatile boolean failed = false; + private static JFrame frame; + private static Robot robot; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.getContentPane().setLayout(new GridLayout(3, 2)); + spinner[0] = new JSpinner(); + spinner[0].setModel(new SpinnerNumberModel()); + spinner[0].setFont(font); + frame.getContentPane().add(spinner[0]); + + spinner[1] = new JSpinner(); + spinner[1].setModel(new SpinnerDateModel()); + spinner[1].setFont(font); + frame.getContentPane().add(spinner[1]); + + spinner[2] = new JSpinner(); + spinner[2].setModel(new SpinnerListModel + (new Object[]{"one", "two", "three"})); + spinner[2].setFont(font); + frame.getContentPane().add(spinner[2]); + + spinner[3] = new JSpinner(); + spinner[3].setFont(font); + spinner[3].setModel(new SpinnerNumberModel()); + frame.getContentPane().add(spinner[3]); + + spinner[4] = new JSpinner(); + spinner[4].setFont(font); + spinner[4].setModel(new SpinnerDateModel()); + frame.getContentPane().add(spinner[4]); + + spinner[5] = new JSpinner(); + spinner[5].setFont(font); + spinner[5].setModel(new SpinnerListModel + (new Object[]{"one", "two", "three"})); + frame.getContentPane().add(spinner[5]); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + JFormattedTextField ftf; + for (int i = 1; i < 6; i++) { + ftf = ((JSpinner.DefaultEditor) + spinner[i].getEditor()).getTextField(); + if (!ftf.getFont().equals(font)) { + failed = true; + } + } + }); + robot.waitForIdle(); + robot.delay(1000); + if (failed) { + throw new RuntimeException("JSpinner.setFont() " + + "doesn't set the font properly"); + } + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug4680204.java b/test/jdk/javax/swing/JSpinner/bug4680204.java new file mode 100644 index 00000000000..ecd923f2a4d --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4680204.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Robot; + +/* + * @test + * @bug 4680204 + * @summary JSpinner shows ToolTipText only on it's border + * @key headful + * @run main bug4680204 + */ + +public class bug4680204 { + + private static JSpinner sp1, sp2; + private static final String TOOL_TIP_TEXT = "ToolTipText"; + private static JFrame frame; + private static Robot robot; + private static volatile boolean failed = false; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.getContentPane().setLayout(new FlowLayout()); + + sp1 = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1)); + sp1.setToolTipText(TOOL_TIP_TEXT); + frame.getContentPane().add(sp1); + + sp2 = new JSpinner(); + sp2.setToolTipText(TOOL_TIP_TEXT); + frame.getContentPane().add(sp2); + sp2.setModel(new SpinnerNumberModel(1, 1, 100, 1)); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + Component[] children = sp1.getComponents(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof JSpinner.DefaultEditor) { + JTextField tf = ((JSpinner.DefaultEditor) children[i]).getTextField(); + if (!TOOL_TIP_TEXT.equals(tf.getToolTipText())) { + failed = true; + } + } else if (children[i] instanceof JComponent) { + String text = ((JComponent) children[i]).getToolTipText(); + if (!TOOL_TIP_TEXT.equals(text)) { + failed = true; + } + } + } + + children = sp2.getComponents(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof JSpinner.DefaultEditor) { + JTextField tf = ((JSpinner.DefaultEditor) children[i]).getTextField(); + if (!TOOL_TIP_TEXT.equals(tf.getToolTipText())) { + failed = true; + } + } else if (children[i] instanceof JComponent) { + String text = ((JComponent) children[i]).getToolTipText(); + if (!TOOL_TIP_TEXT.equals(text)) { + failed = true; + } + } + } + }); + robot.waitForIdle(); + robot.delay(1000); + if (failed) { + throw new RuntimeException("The tooltip text is not correctly set for JSpinner"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug4862257.java b/test/jdk/javax/swing/JSpinner/bug4862257.java new file mode 100644 index 00000000000..b87b7b359a3 --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4862257.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JButton; +import javax.swing.JSpinner; + +/* + * @test + * @bug 4862257 + * @summary Class cast Exception occurred when JButton is set to JSpinner + * @run main bug4862257 + */ + +public class bug4862257 { + public static void main(String[] argv) { + JSpinner spinner = new JSpinner(); + spinner.setEditor(new JButton("JButton")); + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug5104421.java b/test/jdk/javax/swing/JSpinner/bug5104421.java new file mode 100644 index 00000000000..cad5d8c9e0a --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug5104421.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, 2023, 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 javax.swing.SpinnerDateModel; + +/* + * @test + * @bug 5104421 + * @summary SpinnerDateModel.setValue(Object) throws exception with incorrect message + * @run main bug5104421 + */ + +public class bug5104421 { + public static void main(String[] args) { + SpinnerDateModel model = new SpinnerDateModel(); + try { + model.setValue(Integer.valueOf(42)); + } catch (IllegalArgumentException e) { + if (e.getMessage().toLowerCase().indexOf("null value") != -1) { + throw new RuntimeException("SpinnerDateModel.setValue(Object) throws " + + "exception with incorrect message"); + } + } + System.out.println("Test Passed!"); + } +} From 83cc4cb50d1e10b72b81b246bc05d14601d35a33 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 11 Mar 2024 08:08:50 +0000 Subject: [PATCH 043/298] 8327059: os::Linux::print_proc_sys_info add swappiness information Backport-of: f3b15abcb7dcd00158df84818965fc1282dcc1d9 --- src/hotspot/os/linux/os_linux.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index aa8be1d897d..9ffc43d87b8 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2145,6 +2145,8 @@ void os::Linux::print_proc_sys_info(outputStream* st) { "/proc/sys/kernel/threads-max", st); _print_ascii_file_h("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have)", "/proc/sys/vm/max_map_count", st); + _print_ascii_file_h("/proc/sys/vm/swappiness (control to define how aggressively the kernel swaps out anonymous memory)", + "/proc/sys/vm/swappiness", st); _print_ascii_file_h("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers)", "/proc/sys/kernel/pid_max", st); } From 3086ed886463ffe7250cc681c0f67f5aa5c47d6e Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 11 Mar 2024 08:15:08 +0000 Subject: [PATCH 044/298] 8324834: Use _LARGE_FILES on AIX Backport-of: 8e45182357f4990c86fd0b711a7a91887945480b --- make/autoconf/flags-cflags.m4 | 2 +- src/hotspot/os/aix/attachListener_aix.cpp | 14 +++++++------- src/hotspot/os/aix/os_aix.cpp | 18 +++++++++++------- src/hotspot/os/posix/os_posix.cpp | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 06a62c9a8f1..5037c65fb7d 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -485,7 +485,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER], CFLAGS_OS_DEF_JVM="-D_ALLBSD_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE" CFLAGS_OS_DEF_JDK="-D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT" elif test "x$OPENJDK_TARGET_OS" = xaix; then - CFLAGS_OS_DEF_JVM="-DAIX" + CFLAGS_OS_DEF_JVM="-DAIX -D_LARGE_FILES" elif test "x$OPENJDK_TARGET_OS" = xbsd; then CFLAGS_OS_DEF_JDK="-D_ALLBSD_SOURCE" elif test "x$OPENJDK_TARGET_OS" = xwindows; then diff --git a/src/hotspot/os/aix/attachListener_aix.cpp b/src/hotspot/os/aix/attachListener_aix.cpp index 02bf4727194..616976e633f 100644 --- a/src/hotspot/os/aix/attachListener_aix.cpp +++ b/src/hotspot/os/aix/attachListener_aix.cpp @@ -477,14 +477,14 @@ AttachOperation* AttachListener::dequeue() { void AttachListener::vm_start() { char fn[UNIX_PATH_MAX]; - struct stat64 st; + struct stat st; int ret; int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == 0) { ret = ::unlink(fn); if (ret == -1) { @@ -504,8 +504,8 @@ int AttachListener::pd_init() { bool AttachListener::check_socket_file() { int ret; - struct stat64 st; - ret = stat64(AixAttachListener::path(), &st); + struct stat st; + ret = stat(AixAttachListener::path(), &st); if (ret == -1) { // need to restart attach listener. log_debug(attach)("Socket file %s does not exist - Restart Attach Listener", AixAttachListener::path()); @@ -544,14 +544,14 @@ bool AttachListener::is_init_trigger() { } char fn[PATH_MAX + 1]; int ret; - struct stat64 st; + struct stat st; os::snprintf_checked(fn, sizeof(fn), ".attach_pid%d", os::current_process_id()); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == -1) { log_trace(attach)("Failed to find attach file: %s, trying alternate", fn); snprintf(fn, sizeof(fn), "%s/.attach_pid%d", os::get_temp_directory(), os::current_process_id()); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == -1) { log_debug(attach)("Failed to find attach file: %s", fn); } diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 3321c32a687..b1339104c35 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -113,6 +113,10 @@ #include #include +#ifndef _LARGE_FILES +#error Hotspot on AIX must be compiled with -D_LARGE_FILES +#endif + // Missing prototypes for various system APIs. extern "C" int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t); @@ -2495,10 +2499,10 @@ int os::open(const char *path, int oflag, int mode) { // IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE int oflag_with_o_cloexec = oflag | O_CLOEXEC; - int fd = ::open64(path, oflag_with_o_cloexec, mode); + int fd = ::open(path, oflag_with_o_cloexec, mode); if (fd == -1) { // we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804) - fd = ::open64(path, oflag, mode); + fd = ::open(path, oflag, mode); if (fd == -1) { return -1; } @@ -2506,8 +2510,8 @@ int os::open(const char *path, int oflag, int mode) { // If the open succeeded, the file might still be a directory. { - struct stat64 buf64; - int ret = ::fstat64(fd, &buf64); + struct stat buf64; + int ret = ::fstat(fd, &buf64); int st_mode = buf64.st_mode; if (ret != -1) { @@ -2561,17 +2565,17 @@ int os::open(const char *path, int oflag, int mode) { int os::create_binary_file(const char* path, bool rewrite_existing) { int oflags = O_WRONLY | O_CREAT; oflags |= rewrite_existing ? O_TRUNC : O_EXCL; - return ::open64(path, oflags, S_IREAD | S_IWRITE); + return ::open(path, oflags, S_IREAD | S_IWRITE); } // return current position of file pointer jlong os::current_file_offset(int fd) { - return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); + return (jlong)::lseek(fd, (off_t)0, SEEK_CUR); } // move file pointer to the specified offset jlong os::seek_to_file_offset(int fd, jlong offset) { - return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); + return (jlong)::lseek(fd, (off_t)offset, SEEK_SET); } // Map a block of memory. diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index af7de184b14..56f6d32bd4d 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -753,11 +753,11 @@ void os::dll_unload(void *lib) { } jlong os::lseek(int fd, jlong offset, int whence) { - return (jlong) AIX_ONLY(::lseek64) NOT_AIX(::lseek)(fd, offset, whence); + return (jlong) ::lseek(fd, offset, whence); } int os::ftruncate(int fd, jlong length) { - return AIX_ONLY(::ftruncate64) NOT_AIX(::ftruncate)(fd, length); + return ::ftruncate(fd, length); } const char* os::get_current_directory(char *buf, size_t buflen) { From 50f447c5f4222ba81c366ea2710695f9e43f8624 Mon Sep 17 00:00:00 2001 From: Long Yang Date: Mon, 11 Mar 2024 08:16:55 +0000 Subject: [PATCH 045/298] 8326446: The User and System of jdk.CPULoad on Apple M1 are inaccurate Backport-of: 8dbd4b391f7deb1a46a5f07f0bc46f23d6715ddb --- src/hotspot/os/bsd/os_perf_bsd.cpp | 52 +++++++++++++----------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/hotspot/os/bsd/os_perf_bsd.cpp b/src/hotspot/os/bsd/os_perf_bsd.cpp index f91dfa87f07..631d2135b64 100644 --- a/src/hotspot/os/bsd/os_perf_bsd.cpp +++ b/src/hotspot/os/bsd/os_perf_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -39,6 +39,7 @@ #include #include #include + #include #endif static const double NANOS_PER_SEC = 1000000000.0; @@ -47,10 +48,10 @@ class CPUPerformanceInterface::CPUPerformance : public CHeapObj { friend class CPUPerformanceInterface; private: #ifdef __APPLE__ - uint64_t _total_cpu_nanos; + uint64_t _jvm_real; uint64_t _total_csr_nanos; - uint64_t _jvm_user_nanos; - uint64_t _jvm_system_nanos; + uint64_t _jvm_user; + uint64_t _jvm_system; long _jvm_context_switches; long _used_ticks; long _total_ticks; @@ -86,11 +87,11 @@ class CPUPerformanceInterface::CPUPerformance : public CHeapObj { CPUPerformanceInterface::CPUPerformance::CPUPerformance() { #ifdef __APPLE__ - _total_cpu_nanos= 0; + _jvm_real = 0; _total_csr_nanos= 0; _jvm_context_switches = 0; - _jvm_user_nanos = 0; - _jvm_system_nanos = 0; + _jvm_user = 0; + _jvm_system = 0; _used_ticks = 0; _total_ticks = 0; _active_processor_count = 0; @@ -152,42 +153,35 @@ int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* cpu_ int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { #ifdef __APPLE__ int result = cpu_load_total_process(psystemTotalLoad); - mach_port_t task = mach_task_self(); - mach_msg_type_number_t task_info_count = TASK_INFO_MAX; - task_info_data_t task_info_data; - kern_return_t kr = task_info(task, TASK_ABSOLUTETIME_INFO, (task_info_t)task_info_data, &task_info_count); - if (kr != KERN_SUCCESS) { + + struct tms buf; + clock_t jvm_real = times(&buf); + if (jvm_real == (clock_t) (-1)) { return OS_ERR; } - task_absolutetime_info_t absolutetime_info = (task_absolutetime_info_t)task_info_data; int active_processor_count = os::active_processor_count(); - uint64_t jvm_user_nanos = absolutetime_info->total_user; - uint64_t jvm_system_nanos = absolutetime_info->total_system; - - uint64_t total_cpu_nanos; - if(!now_in_nanos(&total_cpu_nanos)) { - return OS_ERR; - } + uint64_t jvm_user = buf.tms_utime; + uint64_t jvm_system = buf.tms_stime; - if (_total_cpu_nanos == 0 || active_processor_count != _active_processor_count) { - // First call or change in active processor count + if (active_processor_count != _active_processor_count) { + // Change in active processor count result = OS_ERR; } else { - uint64_t delta_nanos = active_processor_count * (total_cpu_nanos - _total_cpu_nanos); - if (delta_nanos == 0) { + uint64_t delta = active_processor_count * (jvm_real - _jvm_real); + if (delta == 0) { // Avoid division by zero return OS_ERR; } - *pjvmUserLoad = normalize((double)(jvm_user_nanos - _jvm_user_nanos)/delta_nanos); - *pjvmKernelLoad = normalize((double)(jvm_system_nanos - _jvm_system_nanos)/delta_nanos); + *pjvmUserLoad = normalize((double)(jvm_user - _jvm_user) / delta); + *pjvmKernelLoad = normalize((double)(jvm_system - _jvm_system) / delta); } _active_processor_count = active_processor_count; - _total_cpu_nanos = total_cpu_nanos; - _jvm_user_nanos = jvm_user_nanos; - _jvm_system_nanos = jvm_system_nanos; + _jvm_real = jvm_real; + _jvm_user = jvm_user; + _jvm_system = jvm_system; return result; #else From c0b5fdf0f23edaa6f82be2ff813777883e1eebf4 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 11 Mar 2024 08:24:52 +0000 Subject: [PATCH 046/298] 8326140: src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp ReleaseStringChars might be missing in early returns Backport-of: d9ef16dbb6917a4fff7711b32f3dd87611560dd1 --- .../AccessBridgeJavaEntryPoints.cpp | 118 +++++++----------- 1 file changed, 42 insertions(+), 76 deletions(-) diff --git a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp index 5386e4afdd3..c16fd791e5b 100644 --- a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp +++ b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -82,6 +82,22 @@ AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() { return (returnVal); \ } +#define EXCEPTION_CHECK_WITH_RELEASE(situationDescription, returnVal, js, stringBytes) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to GetStringLength; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + return (returnVal); \ + } \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to ReleaseStringChars; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + #define EXCEPTION_CHECK_VOID(situationDescription) \ if (exception = jniEnv->ExceptionOccurred()) { \ PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription); \ @@ -1215,9 +1231,7 @@ AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(name, stringBytes, nameSize - 1); length = jniEnv->GetStringLength(js); - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); jniEnv->CallVoidMethod ( accessBridgeObject, decrementReferenceMethod, js); @@ -1380,9 +1394,7 @@ AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleCo length = jniEnv->GetStringLength(js); test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ? length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAttributesAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); @@ -1735,11 +1747,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ? length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); @@ -1767,11 +1777,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ? length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); @@ -1799,11 +1807,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE); wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRole", FALSE, js, stringBytes); info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ? length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE); @@ -1831,11 +1837,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE); wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRole_en_US", FALSE, js, stringBytes); info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ? length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE); @@ -1862,11 +1866,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE); wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleState", FALSE, js, stringBytes); info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ? length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE); @@ -1893,11 +1895,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE); wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleState_en_US", FALSE, js, stringBytes); info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ? length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE); @@ -2809,11 +2809,9 @@ AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE); wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRelation key", FALSE, js, stringBytes); relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ? length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE); @@ -2915,9 +2913,7 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext, length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2; } hypertext->links[i].text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3052,9 +3048,7 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleC length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2; } hypertext->links[bufIndex].text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3171,9 +3165,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, length = (sizeof(info->text) / sizeof(wchar_t)) - 2; } info->text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3300,9 +3292,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2; } icons->iconInfo[i].description[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleIcon description", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE); @@ -3379,9 +3369,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2; } actions->actionInfo[i].name [length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAction name - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAction name - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAction name", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleAction name - call to CallVoidMethod()", FALSE); @@ -3561,9 +3549,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, length = jniEnv->GetStringLength(js); textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ? length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleWordAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE); @@ -3597,9 +3583,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, } else { textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0; } - EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleSentenceAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE); @@ -3673,9 +3657,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleCo length = jniEnv->GetStringLength(js); selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ? length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleTextSelectedText", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE); @@ -3890,9 +3872,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ? length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting BackgroundColorFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3927,9 +3907,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ? length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting ForegroundColorFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3964,9 +3942,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ? length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting FontFamilyFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4170,9 +4146,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ? length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAttributesAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); @@ -4413,9 +4387,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext, PrintDebugString("[INFO]: Accessible Text stringBytes length = %d", length); text[length < len ? length : len - 2] = (wchar_t) 0; wPrintDebugString(L"[INFO]: Accessible Text 'text' after null termination = %ls", text); - EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleTextRange", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE); @@ -4458,9 +4430,7 @@ AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting CurrentAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE); @@ -4501,9 +4471,7 @@ AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting MaximumAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE); @@ -4544,9 +4512,7 @@ AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting MinimumAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE); From a75d19dea5272d58b5954ce8cd790c2038567865 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 Mar 2024 09:18:50 +0000 Subject: [PATCH 047/298] 8318455: Fix the compiler/sharedstubs/SharedTrampolineTest.java and SharedStubToInterpTest.java Reviewed-by: phh Backport-of: 4a16d111b16e556f904fb80075631b8439a9482e --- .../jtreg/compiler/sharedstubs/SharedStubToInterpTest.java | 5 +++-- .../jtreg/compiler/sharedstubs/SharedTrampolineTest.java | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index 682198672f7..5dd938442cc 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -51,9 +51,10 @@ public class SharedStubToInterpTest { private final static int ITERATIONS_TO_HEAT_LOOP = 20_000; - private static void runTest(String test) throws Exception { + private static void runTest(String compiler, String test) throws Exception { String testClassName = SharedStubToInterpTest.class.getName() + "$" + test; ArrayList command = new ArrayList(); + command.add(compiler); command.add("-XX:+UnlockDiagnosticVMOptions"); command.add("-Xbatch"); command.add("-XX:+PrintRelocations"); @@ -80,7 +81,7 @@ private static void runTest(String test) throws Exception { public static void main(String[] args) throws Exception { String[] methods = new String[] { "StaticMethodTest", "FinalClassTest", "FinalMethodTest"}; for (String methodName : methods) { - runTest(methodName); + runTest(args[0], methodName); } } diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java index 10af17de6cb..f1e4d18b93a 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java @@ -28,6 +28,7 @@ * @bug 8280152 * @library /test/lib * + * @requires vm.compiler2.enabled * @requires vm.opt.TieredCompilation == null * @requires os.arch=="aarch64" | os.arch=="riscv64" * @requires vm.debug @@ -46,9 +47,10 @@ public class SharedTrampolineTest { private final static int ITERATIONS_TO_HEAT_LOOP = 20_000; - private static void runTest(String test) throws Exception { + private static void runTest(String compiler, String test) throws Exception { String testClassName = SharedTrampolineTest.class.getName() + "$" + test; ArrayList command = new ArrayList(); + command.add(compiler); command.add("-XX:+UnlockDiagnosticVMOptions"); command.add("-Xbatch"); command.add("-XX:+PrintRelocations"); @@ -72,7 +74,7 @@ private static void runTest(String test) throws Exception { public static void main(String[] args) throws Exception { String[] tests = new String[] {"StaticMethodTest"}; for (String test : tests) { - runTest(test); + runTest(args[0], test); } } From 8f08066962e7f38d7303d4648c22a6aa210926f8 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Mon, 11 Mar 2024 09:21:38 +0000 Subject: [PATCH 048/298] 8266242: java/awt/GraphicsDevice/CheckDisplayModes.java failing on macOS 11 ARM Backport-of: f7d6d7a04faa704155ee8df33e7d344bb962566f --- .../native/libawt_lwawt/awt/CGraphicsDevice.m | 15 +++++++++++++-- test/jdk/ProblemList.txt | 1 - 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m index a93bfcb58c4..468c5f6dae0 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -35,6 +35,7 @@ #define DEFAULT_DEVICE_HEIGHT 768 #define DEFAULT_DEVICE_DPI 72 +static NSInteger architecture = -1; /* * Convert the mode string to the more convenient bits per pixel value */ @@ -58,7 +59,17 @@ static int getBPPFromModeString(CFStringRef mode) return 0; } -static BOOL isValidDisplayMode(CGDisplayModeRef mode){ +static BOOL isValidDisplayMode(CGDisplayModeRef mode) { + // Workaround for apple bug FB13261205, since it only affects arm based macs + // and arm support started with macOS 11 ignore the workaround for previous versions + if (@available(macOS 11, *)) { + if (architecture == -1) { + architecture = [[NSRunningApplication currentApplication] executableArchitecture]; + } + if (architecture == NSBundleExecutableArchitectureARM64) { + return (CGDisplayModeGetPixelWidth(mode) >= 800); + } + } return (1 < CGDisplayModeGetWidth(mode) && 1 < CGDisplayModeGetHeight(mode)); } diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 00ecd478b1f..1fd1d603fe9 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -459,7 +459,6 @@ java/awt/KeyboardFocusmanager/TypeAhead/MenuItemActivatedTest/MenuItemActivatedT java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 java/awt/dnd/BadSerializationTest/BadSerializationTest.java 8277817 linux-x64,windows-x64 -java/awt/GraphicsDevice/CheckDisplayModes.java 8266242 macosx-aarch64 java/awt/GraphicsDevice/DisplayModes/UnknownRefrshRateTest.java 8286436 macosx-aarch64 java/awt/image/multiresolution/MultiresolutionIconTest.java 8291979 linux-x64,windows-all java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 8305061 macosx-x64 From e2858b5c98797111cbfa4d4f5e9c7a5944b8175b Mon Sep 17 00:00:00 2001 From: Andrew Leonard Date: Mon, 11 Mar 2024 11:01:27 +0000 Subject: [PATCH 049/298] 8326685: Linux builds not reproducible if two builds configured in different build folders Backport-of: 3b90ddfefea36d9f7f08ff11cd0cb099aa32b02b --- make/autoconf/flags-cflags.m4 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 5037c65fb7d..d0b6aec4755 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -122,6 +122,11 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS], # Add debug prefix map gcc system include paths, as they cause # non-deterministic debug paths depending on gcc path location. DEBUG_PREFIX_MAP_GCC_INCLUDE_PATHS + + # Add debug prefix map for OUTPUTDIR to handle the scenario when + # it is not located within WORKSPACE_ROOT + outputdir_slash="${OUTPUTDIR%/}/" + DEBUG_PREFIX_CFLAGS="$DEBUG_PREFIX_CFLAGS -fdebug-prefix-map=${outputdir_slash}=" ] ) fi From d4e336d4b70de9a74c62ccde5d5eb447a3bd5d9a Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Mon, 11 Mar 2024 13:14:15 +0000 Subject: [PATCH 050/298] 8321075: RISC-V: UseSystemMemoryBarrier lacking proper OS support Reviewed-by: rehn, fyang Backport-of: 68eb5a1df5afdc011aa467f1c723a8792532dd3f --- src/hotspot/os/linux/os_linux.cpp | 25 +++++++++++++++++++ src/hotspot/os/linux/os_linux.hpp | 2 ++ .../os/linux/systemMemoryBarrier_linux.cpp | 14 ++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 9ffc43d87b8..fcd3bbff9d1 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -83,6 +83,8 @@ #endif // put OS-includes here +# include +# include # include # include # include @@ -309,6 +311,29 @@ static void next_line(FILE *f) { } while (c != '\n' && c != EOF); } +void os::Linux::kernel_version(long* major, long* minor) { + *major = -1; + *minor = -1; + + struct utsname buffer; + int ret = uname(&buffer); + if (ret != 0) { + log_warning(os)("uname(2) failed to get kernel version: %s", os::errno_name(ret)); + return; + } + + char* walker = buffer.release; + long* set_v = major; + while (*minor == -1 && walker != nullptr) { + if (isdigit(walker[0])) { + *set_v = strtol(walker, &walker, 10); + set_v = minor; + } else { + ++walker; + } + } +} + bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu) { FILE* fh; uint64_t userTicks, niceTicks, systemTicks, idleTicks; diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index ace7e4ab2dd..029f2aa7a52 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -109,6 +109,8 @@ class os::Linux { bool has_steal_ticks; }; + static void kernel_version(long* major, long* minor); + // which_logical_cpu=-1 returns accumulated ticks for all cpus. static bool get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu); static bool _stack_is_executable; diff --git a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp index 609967128fb..5135ffefc45 100644 --- a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp +++ b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" -#include "runtime/os.hpp" +#include "os_linux.hpp" #include "utilities/debug.hpp" #include "utilities/systemMemoryBarrier.hpp" @@ -70,6 +70,18 @@ static int membarrier(int cmd, unsigned int flags, int cpu_id) { } bool LinuxSystemMemoryBarrier::initialize() { +#if defined(RISCV) +// RISCV port was introduced in kernel 4.4. +// 4.4 also made membar private expedited mandatory. +// But RISCV actually don't support it until 6.9. + long major, minor; + os::Linux::kernel_version(&major, &minor); + if (!(major > 6 || (major == 6 && minor >= 9))) { + log_info(os)("Linux kernel %ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.", + major, minor); + return false; + } +#endif int ret = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); if (ret < 0) { log_info(os)("MEMBARRIER_CMD_QUERY unsupported"); From 779204c941225f76aa85299bacfae59deccef082 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 11 Mar 2024 22:22:14 +0000 Subject: [PATCH 051/298] 8320570: NegativeArraySizeException decoding >1G UTF8 bytes with non-ascii characters Reviewed-by: phh Backport-of: 82796bdebbf56b98ec97a6d572ed68c2842f60c6 --- .../share/classes/java/lang/String.java | 14 ++-- .../String/CompactString/NegativeSize.java | 75 +++++++++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 test/jdk/java/lang/String/CompactString/NegativeSize.java diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 9b19d7e2ac1..cd8995e18e4 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -574,7 +574,7 @@ private String(Charset charset, byte[] bytes, int offset, int length) { this.coder = LATIN1; return; } - byte[] buf = new byte[length << 1]; + byte[] buf = StringUTF16.newBytesFor(length); StringLatin1.inflate(dst, 0, buf, 0, dp); dst = buf; dp = decodeUTF8_UTF16(bytes, offset, sl, dst, dp, true); @@ -584,7 +584,7 @@ private String(Charset charset, byte[] bytes, int offset, int length) { this.value = dst; this.coder = UTF16; } else { // !COMPACT_STRINGS - byte[] dst = new byte[length << 1]; + byte[] dst = StringUTF16.newBytesFor(length); int dp = decodeUTF8_UTF16(bytes, offset, offset + length, dst, 0, true); if (dp != length) { dst = Arrays.copyOf(dst, dp << 1); @@ -605,7 +605,7 @@ private String(Charset charset, byte[] bytes, int offset, int length) { this.value = Arrays.copyOfRange(bytes, offset, offset + length); this.coder = LATIN1; } else { - byte[] dst = new byte[length << 1]; + byte[] dst = StringUTF16.newBytesFor(length); int dp = 0; while (dp < length) { int b = bytes[offset++]; @@ -750,15 +750,15 @@ static String newStringUTF8NoRepl(byte[] bytes, int offset, int length, boolean return new String(dst, LATIN1); } if (dp == 0) { - dst = new byte[length << 1]; + dst = StringUTF16.newBytesFor(length); } else { - byte[] buf = new byte[length << 1]; + byte[] buf = StringUTF16.newBytesFor(length); StringLatin1.inflate(dst, 0, buf, 0, dp); dst = buf; } dp = decodeUTF8_UTF16(bytes, offset, sl, dst, dp, false); } else { // !COMPACT_STRINGS - dst = new byte[length << 1]; + dst = StringUTF16.newBytesFor(length); dp = decodeUTF8_UTF16(bytes, offset, offset + length, dst, 0, false); } if (dp != length) { @@ -1304,7 +1304,7 @@ private static byte[] encodeUTF8(byte coder, byte[] val, boolean doReplace) { } int dp = 0; - byte[] dst = new byte[val.length << 1]; + byte[] dst = StringUTF16.newBytesFor(val.length); for (byte c : val) { if (c < 0) { dst[dp++] = (byte) (0xc0 | ((c & 0xff) >> 6)); diff --git a/test/jdk/java/lang/String/CompactString/NegativeSize.java b/test/jdk/java/lang/String/CompactString/NegativeSize.java new file mode 100644 index 00000000000..a218c5f18f8 --- /dev/null +++ b/test/jdk/java/lang/String/CompactString/NegativeSize.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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.nio.charset.StandardCharsets; + +/* + * @test + * @bug 8077559 + * @summary Tests Compact String for negative size. + * @requires vm.bits == 64 & os.maxMemory >= 4G + * @run main/othervm -XX:+CompactStrings -Xmx4g NegativeSize + * @run main/othervm -XX:-CompactStrings -Xmx4g NegativeSize + */ + +// In Java8: java.lang.OutOfMemoryError: Java heap space +// In Java9+: was java.lang.NegativeArraySizeException: -1894967266 +public class NegativeSize { + + static byte[] generateData() { + int asciisize = 1_200_000_000; + byte[] nonAscii = "非アスキー".getBytes(); + int nonAsciiSize = nonAscii.length; + // 1 GB + byte[] arr = new byte[asciisize + nonAsciiSize]; + for (int i=0; i Date: Tue, 12 Mar 2024 02:17:55 +0000 Subject: [PATCH 052/298] 8320342: Use PassFailJFrame for TruncatedPopupMenuTest.java Backport-of: 1f2922ad8526d378ee7b616e5423ce56f20340db --- .../awt/PopupMenu/TruncatedPopupMenuTest.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java diff --git a/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java b/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java new file mode 100644 index 00000000000..64d655aa351 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2004, 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.awt.Frame; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 5090643 + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Menus added to the popup menu are truncated on XToolkit + * @run main/manual TruncatedPopupMenuTest + */ + +public class TruncatedPopupMenuTest { + private static final String INSTRUCTIONS = + "1. Right-click on the Test Window.\n\n" + + "2. Look at the appeared popup menu.\n\n" + + "3. It should consist of one menu item (\"First simple menu item\")\n" + + "and one submenu (\"Just simple menu for the test\").\n\n" + + "4. The submenu should not be truncated. The submenu title text should\n" + + "be followed by a triangle. On the whole, menu should be good-looking.\n\n" + + "5. Left-click on the submenu (\"Just simple menu for the test\").\n" + + "After this operation, a submenu should popup. It should consist of\n"+ + "one menu item (\"Second simple menu item \") and one submenu (\"Other Menu\").\n\n" + + "6. The submenu should not be truncated. The \"Other Menu\" text should be followed by\n" + + "a triangle.\n\n" + + "On the whole, menu should be good-looking.\n"; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .rows(20) + .columns(55) + .testUI(TruncatedPopupMenuTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Menu subMenu = new Menu("Just simple menu for the test"); + subMenu.add(new MenuItem("Second simple menu item")); + subMenu.add(new Menu("Other Menu")); + + PopupMenu popup = new PopupMenu(); + popup.add(new MenuItem("First simple menu item")); + popup.add(subMenu); + + Frame testUI = new Frame("TruncatedPopupMenuTest"); + testUI.add(popup); + testUI.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + public void mouseReleased(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + }); + + testUI.setSize(400, 400); + return testUI; + } +} From 7f5afa186af28396f9b24c9b6a880cb57ab5dbbe Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Tue, 12 Mar 2024 09:23:28 +0000 Subject: [PATCH 053/298] 8326891: Prefer RPATH over RUNPATH for $ORIGIN rpaths in internal JDK binaries Backport-of: 721bfee53af5bc2e2d67eebc7b82f09a642d5309 --- make/autoconf/flags-cflags.m4 | 10 ++++++++-- test/jdk/tools/launcher/RunpathTest.java | 23 +++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index d0b6aec4755..f93d42f1634 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -28,7 +28,7 @@ # Setup flags for C/C++ compiler # -############################################################################### +################################################################################ # # How to compile shared libraries. # @@ -37,7 +37,10 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS], if test "x$TOOLCHAIN_TYPE" = xgcc; then # Default works for linux, might work on other platforms as well. SHARED_LIBRARY_FLAGS='-shared' - SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1' + # --disable-new-dtags forces use of RPATH instead of RUNPATH for rpaths. + # This protects internal library dependencies within the JDK from being + # overridden using LD_LIBRARY_PATH. See JDK-8326891 for more information. + SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1 -Wl,--disable-new-dtags' SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN" SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' @@ -63,6 +66,9 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS], # Default works for linux, might work on other platforms as well. SHARED_LIBRARY_FLAGS='-shared' SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1' + if test "x$OPENJDK_TARGET_OS" = xlinux; then + SET_EXECUTABLE_ORIGIN="$SET_EXECUTABLE_ORIGIN -Wl,--disable-new-dtags" + fi SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' diff --git a/test/jdk/tools/launcher/RunpathTest.java b/test/jdk/tools/launcher/RunpathTest.java index cc050c589c7..c83a43195db 100644 --- a/test/jdk/tools/launcher/RunpathTest.java +++ b/test/jdk/tools/launcher/RunpathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -24,7 +24,8 @@ /* * @test * @bug 7190813 8022719 - * @summary Check for extended RPATHs on *nixes + * @summary Check for extended RPATHs on Linux + * @requires os.family == "linux" * @compile -XDignore.symbol.file RunpathTest.java * @run main RunpathTest * @author ksrini @@ -57,25 +58,23 @@ void elfCheck(String javacmd, String expectedRpath) { final TestResult tr = doExec(elfreaderCmd, "-d", javacmd); if (!tr.matches(expectedRpath)) { System.out.println(tr); - throw new RuntimeException("FAILED: RPATH/RUNPATH strings " + + throw new RuntimeException("FAILED: RPATH strings " + expectedRpath + " not found in " + javaCmd); } - System.out.println(javacmd + " contains expected RPATHS/RUNPATH"); + System.out.println(javacmd + " contains expected RPATHS"); } void testRpath() { - String expectedRpath = ".*R(UN)?PATH.*\\$ORIGIN/../lib.*"; + String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib.*"; elfCheck(javaCmd, expectedRpath); } public static void main(String... args) throws Exception { - if (isLinux) { - RunpathTest rp = new RunpathTest(); - if (rp.elfreaderCmd == null) { - System.err.println("Warning: test passes vacuously"); - return; - } - rp.testRpath(); + RunpathTest rp = new RunpathTest(); + if (rp.elfreaderCmd == null) { + System.err.println("Warning: test passes vacuously"); + return; } + rp.testRpath(); } } From c8e9f1d5d375b4594537147df05e28dda3347871 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Tue, 12 Mar 2024 09:23:54 +0000 Subject: [PATCH 054/298] 8320113: [macos14] : ShapeNotSetSometimes.java fails intermittently on macOS 14 Backport-of: f1b73350c237021c04ceac2f29f1f378630bd651 --- .../ShapeNotSetSometimes.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java index 20ca18587ef..48a0e75ead0 100644 --- a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java +++ b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -21,45 +21,50 @@ * questions. */ -/* - @test - @key headful - @bug 6988428 - @summary Tests whether shape is always set - @author anthony.petrov@oracle.com: area=awt.toplevel - @run main ShapeNotSetSometimes -*/ import java.awt.Color; +import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +/* + * @test + * @key headful + * @bug 6988428 + * @summary Tests whether shape is always set + * @run main ShapeNotSetSometimes + */ public class ShapeNotSetSometimes { private Frame backgroundFrame; private Frame window; - private static final Color BACKGROUND_COLOR = Color.GREEN; - private static final Color SHAPE_COLOR = Color.WHITE; + private Point[] pointsOutsideToCheck; private Point[] shadedPointsToCheck; private Point innerPoint; - private final Rectangle bounds = new Rectangle(220, 400, 300, 300); private static Robot robot; + private static final Color BACKGROUND_COLOR = Color.GREEN; + private static final Color SHAPE_COLOR = Color.WHITE; public ShapeNotSetSometimes() throws Exception { EventQueue.invokeAndWait(this::initializeGUI); robot.waitForIdle(); + robot.delay(1000); } private void initializeGUI() { @@ -124,7 +129,7 @@ public void paint(Graphics g) { public static void main(String[] args) throws Exception { robot = new Robot(); - for(int i = 0; i < 50; i++) { + for (int i = 1; i <= 50; i++) { System.out.println("Attempt " + i); new ShapeNotSetSometimes().doTest(); } @@ -136,7 +141,6 @@ private void doTest() throws Exception { EventQueue.invokeAndWait(window::toFront); robot.waitForIdle(); - robot.delay(500); try { @@ -173,8 +177,8 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte ); if (mustBeExpectedColor != expectedColor.equals(actualColor)) { + captureScreen(); System.out.printf("window.getX() = %3d, window.getY() = %3d\n", window.getX(), window.getY()); - System.err.printf( "Checking for transparency failed: point: %3d, %3d\n\tactual %s\n\texpected %s%s\n", screenX, @@ -185,4 +189,18 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte throw new RuntimeException("Test failed. The shape has not been applied."); } } + + private static void captureScreen() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screenBounds = new Rectangle(0, 0, screenSize.width, screenSize.height); + try { + ImageIO.write( + robot.createScreenCapture(screenBounds), + "png", + new File("Screenshot.png") + ); + } catch (IOException e) { + e.printStackTrace(); + } + } } From 44fdfc7e91e66d16de89ba25e760e4e8a4deb871 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 12 Mar 2024 12:15:26 +0000 Subject: [PATCH 055/298] 8326101: [PPC64] Need to bailout cleanly if creation of stubs fails when code cache is out of space Backport-of: e3ae81eeeee8e2b0063a576a90624dd927b512f0 --- src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp | 3 +++ src/hotspot/cpu/ppc/ppc.ad | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp index 1a00c9ad268..dc70c73d4b3 100644 --- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp @@ -456,6 +456,9 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { __ extsw(R7_ARG5, length()->as_register()); ce->emit_static_call_stub(); + if (ce->compilation()->bailed_out()) { + return; // CodeCache is full + } bool success = ce->emit_trampoline_stub_for_call(SharedRuntime::get_resolve_static_call_stub()); if (!success) { return; } diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 582f19de09b..d6eaeb7c9af 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2062,7 +2062,10 @@ int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { C2_MacroAssembler _masm(&cbuf); address base = __ start_a_stub(size_exception_handler()); - if (base == NULL) return 0; // CodeBuffer::expand failed + if (base == nullptr) { + ciEnv::current()->record_failure("CodeCache is full"); + return 0; // CodeBuffer::expand failed + } int offset = __ offset(); __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), @@ -2079,7 +2082,10 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { C2_MacroAssembler _masm(&cbuf); address base = __ start_a_stub(size_deopt_handler()); - if (base == NULL) return 0; // CodeBuffer::expand failed + if (base == nullptr) { + ciEnv::current()->record_failure("CodeCache is full"); + return 0; // CodeBuffer::expand failed + } int offset = __ offset(); __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), From c80be84cdda88e83c32eae6e18f7dacc536e5383 Mon Sep 17 00:00:00 2001 From: Suchismith Roy Date: Tue, 12 Mar 2024 12:23:16 +0000 Subject: [PATCH 056/298] 8320005: Allow loading of shared objects with .a extension on AIX Backport-of: e85355ada4ac1061c49ee9f1247d37a437c7b5ab --- src/hotspot/os/aix/os_aix.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index b1339104c35..5ae890ca7ee 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1106,10 +1106,9 @@ bool os::dll_address_to_library_name(address addr, char* buf, return true; } -void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { +static void* dll_load_library(const char *filename, char *ebuf, int ebuflen) { log_info(os)("attempting shared library load of %s", filename); - if (ebuf && ebuflen > 0) { ebuf[0] = '\0'; ebuf[ebuflen - 1] = '\0'; @@ -1155,6 +1154,26 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { } return nullptr; } +// Load library named +// If filename matches .so, and loading fails, repeat with .a. +void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { + void* result = nullptr; + char* const file_path = strdup(filename); + char* const pointer_to_dot = strrchr(file_path, '.'); + const char old_extension[] = ".so"; + const char new_extension[] = ".a"; + STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension)); + // First try to load the existing file. + result = dll_load_library(filename, ebuf, ebuflen); + // If the load fails,we try to reload by changing the extension to .a for .so files only. + // Shared object in .so format dont have braces, hence they get removed for archives with members. + if (result == nullptr && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) { + snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension); + result = dll_load_library(file_path, ebuf, ebuflen); + } + FREE_C_HEAP_ARRAY(char, file_path); + return result; +} void os::print_dll_info(outputStream *st) { st->print_cr("Dynamic libraries:"); From da02da7dd34420f381ed2a9dea5672624033d0f4 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 13 Mar 2024 08:20:11 +0000 Subject: [PATCH 057/298] 8325432: enhance assert message "relocation addr must be in this section" Backport-of: 3d3a8f0ebfafab6e67eb697ff0ec545bd9a51814 --- src/hotspot/share/asm/codeBuffer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index b92bb24cea9..02a42fc0d82 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -209,7 +209,7 @@ class CodeSection { } void set_locs_point(address pc) { assert(pc >= locs_point(), "relocation addr may not decrease"); - assert(allocates2(pc), "relocation addr must be in this section"); + assert(allocates2(pc), "relocation addr " INTPTR_FORMAT " must be in this section from " INTPTR_FORMAT " to " INTPTR_FORMAT, p2i(pc), p2i(_start), p2i(_limit)); _locs_point = pc; } From 2a6688f6cef382e6e5a5ed593f146755fb108b12 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Wed, 13 Mar 2024 08:22:44 +0000 Subject: [PATCH 058/298] 8320129: "top" command during jtreg failure handler does not display CPU usage on OSX Backport-of: 8be3e39220cd64521f4e370011958e17e5fdeaf3 --- test/failure_handler/src/share/conf/mac.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/failure_handler/src/share/conf/mac.properties b/test/failure_handler/src/share/conf/mac.properties index f075178e7eb..1a5d48f2bdc 100644 --- a/test/failure_handler/src/share/conf/mac.properties +++ b/test/failure_handler/src/share/conf/mac.properties @@ -116,7 +116,7 @@ system.sysctl.args=-a process.ps.app=ps process.ps.args=-Meo pid,pcpu,cputime,start,pmem,vsz,rss,state,wchan,user,args process.top.app=top -process.top.args=-l 1 +process.top.args=-l 2 memory.vmstat.app=vm_stat memory.vmstat.args=-c 3 3 From d42da094612e1651f2afcd08d16786b2f3bbdf43 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 13 Mar 2024 08:53:04 +0000 Subject: [PATCH 059/298] 8325743: test/jdk/java/nio/channels/unixdomain/SocketOptions.java enhance user name output in error case Backport-of: d0039960c4fdaf7704d06e1233865ea2e27a5d39 --- test/jdk/java/nio/channels/unixdomain/SocketOptions.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/nio/channels/unixdomain/SocketOptions.java b/test/jdk/java/nio/channels/unixdomain/SocketOptions.java index f275b519394..95188ebcef1 100644 --- a/test/jdk/java/nio/channels/unixdomain/SocketOptions.java +++ b/test/jdk/java/nio/channels/unixdomain/SocketOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -72,7 +72,8 @@ static void testPeerCred() throws Exception { // Check returned user name if (!s1.equals(s2)) { - throw new RuntimeException("wrong username"); + throw new RuntimeException("wrong username, actual " + s1 + + " but expected value from property user.name is " + s2); } // Try setting the option: Read only From 608c98de87b0a2bce9e17395fe65f0f735ad0690 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 13 Mar 2024 10:31:27 +0000 Subject: [PATCH 060/298] 8326496: [test] checkHsErrFileContent support printing hserr in error case Backport-of: a065eba56de01f4492123c6663ec0c3108d907a1 --- .../runtime/ErrorHandling/HsErrFileUtils.java | 65 +++++++++++++++++-- .../ErrorHandling/SecondaryErrorTest.java | 6 +- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/HsErrFileUtils.java b/test/hotspot/jtreg/runtime/ErrorHandling/HsErrFileUtils.java index 306ab44d18d..d2ca4c9ff55 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/HsErrFileUtils.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/HsErrFileUtils.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022 SAP SE. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 SAP SE. 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 @@ -68,7 +68,7 @@ public static File openHsErrFileFromOutput(OutputAnalyzer output) { * @throws RuntimeException, {@link IOException} */ public static void checkHsErrFileContent(File f, Pattern[] patterns, boolean verbose) throws IOException { - checkHsErrFileContent(f, patterns, null, true, verbose); + checkHsErrFileContent(f, patterns, null, true, verbose, false); } /** @@ -80,11 +80,43 @@ public static void checkHsErrFileContent(File f, Pattern[] patterns, boolean ver * Order is irrelevant. * @param checkEndMarker If true, we check for the final "END" in an hs-err file; if it is missing it indicates * that hs-err file printing did not complete successfully. - * @param verbose If true, the content of the hs-err file is printed while matching. If false, only important - * information are printed. + * @param verbose If true, the content of the hs-err file is printed while matching. If false, only the matched patterns + * are printed. * @throws RuntimeException, {@link IOException} */ public static void checkHsErrFileContent(File f, Pattern[] positivePatterns, Pattern[] negativePatterns, boolean checkEndMarker, boolean verbose) throws IOException { + checkHsErrFileContent(f, positivePatterns, negativePatterns, checkEndMarker, verbose, false); + } + + /** + * Given an open hs-err file, read it line by line and check for existence of a set of patterns. Will fail + * if patterns are missing, or if the END marker is missing. + * @param f Input file + * @param patterns An array of patterns that need to match, in that order + * @param verbose If true, the content of the hs-err file is printed while matching. If false, only the matched patterns + * are printed. + * @param printHserrOnError If true, the content of the hs-err file is printed in case of a failing check + * @throws RuntimeException, {@link IOException} + */ + public static void checkHsErrFileContent(File f, Pattern[] patterns, boolean verbose, boolean printHserrOnError) throws IOException { + checkHsErrFileContent(f, patterns, null, true, verbose, printHserrOnError); + } + + /** + * Given an open hs-err file, read it line by line and check for various conditions. + * @param f input file + * @param positivePatterns Optional array of patterns that need to appear, in given order, in the file. Missing + * patterns cause the test to fail. + * @param negativePatterns Optional array of patterns that must not appear in the file; test fails if they do. + * Order is irrelevant. + * @param checkEndMarker If true, we check for the final "END" in an hs-err file; if it is missing it indicates + * that hs-err file printing did not complete successfully. + * @param verbose If true, the content of the hs-err file is printed while matching. If false, only the matched patterns + * are printed. + * @param printHserrOnError If true, the content of the hs-err file is printed in case of a failing check + * @throws RuntimeException, {@link IOException} + */ + public static void checkHsErrFileContent(File f, Pattern[] positivePatterns, Pattern[] negativePatterns, boolean checkEndMarker, boolean verbose, boolean printHserrOnError) throws IOException { try ( FileInputStream fis = new FileInputStream(f); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); @@ -123,6 +155,9 @@ public static void checkHsErrFileContent(File f, Pattern[] positivePatterns, Pat System.out.println(line); } System.out.println("^^^ Forbidden pattern found at line " + lineNo + ": " + negativePattern + "^^^"); + if (printHserrOnError) { + printHsErrFile(f); + } throw new RuntimeException("Forbidden pattern found at line " + lineNo + ": " + negativePattern); } } @@ -132,13 +167,33 @@ public static void checkHsErrFileContent(File f, Pattern[] positivePatterns, Pat } // If the current pattern is not null then it didn't match if (currentPositivePattern != null) { + if (printHserrOnError) { + printHsErrFile(f); + } throw new RuntimeException("hs-err file incomplete (first missing pattern: " + currentPositivePattern.pattern() + ")"); } if (checkEndMarker && !lastLine.equals("END.")) { + if (printHserrOnError) { + printHsErrFile(f); + } throw new RuntimeException("hs-err file incomplete (missing END marker.)"); } System.out.println("hs-err file " + f.getAbsolutePath() + " scanned successfully."); } } + private static void printHsErrFile(File f) throws IOException { + try ( + FileInputStream fis = new FileInputStream(f); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + ) { + String line; + System.out.println("------------------------ hs-err file ------------------------"); + while ((line = br.readLine()) != null) { + System.out.println(line); + } + System.out.println("-------------------------------------------------------------"); + } + } + } diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java index 012d5a5c16d..5b28e2a1d8b 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014, 2022 SAP SE. All rights reserved. - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024 SAP SE. All rights reserved. + * Copyright (c) 2014, 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 @@ -122,7 +122,7 @@ public static void main(String[] args) throws Exception { } Pattern[] pattern = patternlist.toArray(new Pattern[] {}); - HsErrFileUtils.checkHsErrFileContent(hs_err_file, pattern, false); + HsErrFileUtils.checkHsErrFileContent(hs_err_file, pattern, false, true); System.out.println("OK."); From ad5a0878db6145fe041ef47be3f06ad734556403 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 13 Mar 2024 16:08:48 +0000 Subject: [PATCH 061/298] 8321815: Shenandoah: gc state should be synchronized to java threads only once per safepoint Reviewed-by: phh Backport-of: 808a03927c153581cbece93a4f5a4f8242b61ef5 --- .../share/gc/shenandoah/shenandoahHeap.cpp | 16 +++++++++++----- .../share/gc/shenandoah/shenandoahHeap.hpp | 4 +++- .../gc/shenandoah/shenandoahVMOperations.cpp | 18 ++++++++++++++++++ .../gc/shenandoah/shenandoahVMOperations.hpp | 8 +++++--- .../share/gc/shenandoah/shenandoahVerifier.cpp | 2 ++ 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index f1dcbf5a8bc..329ea941eec 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -467,6 +467,7 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : _num_regions(0), _regions(nullptr), _update_refs_iterator(this), + _gc_state_changed(false), _control_thread(nullptr), _shenandoah_policy(policy), _gc_mode(nullptr), @@ -1681,16 +1682,21 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) { _update_refs_iterator.reset(); } -void ShenandoahHeap::set_gc_state_all_threads(char state) { - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - ShenandoahThreadLocalData::set_gc_state(t, state); +void ShenandoahHeap::set_gc_state_all_threads() { + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); + if (_gc_state_changed) { + _gc_state_changed = false; + char state = gc_state(); + for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { + ShenandoahThreadLocalData::set_gc_state(t, state); + } } } void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) { - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should really be Shenandoah safepoint"); + assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); _gc_state.set_cond(mask, value); - set_gc_state_all_threads(_gc_state.raw_value()); + _gc_state_changed = true; } void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 642faef807e..60db6e5776b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -281,6 +281,7 @@ class ShenandoahHeap : public CollectedHeap { }; private: + bool _gc_state_changed; ShenandoahSharedBitmap _gc_state; ShenandoahSharedFlag _degenerated_gc_in_progress; ShenandoahSharedFlag _full_gc_in_progress; @@ -288,11 +289,12 @@ class ShenandoahHeap : public CollectedHeap { ShenandoahSharedFlag _progress_last_gc; ShenandoahSharedFlag _concurrent_strong_root_in_progress; - void set_gc_state_all_threads(char state); void set_gc_state_mask(uint mask, bool value); public: char gc_state() const; + void set_gc_state_all_threads(); + bool has_gc_state_changed() { return _gc_state_changed; } void set_concurrent_mark_in_progress(bool in_progress); void set_evacuation_in_progress(bool in_progress); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp index 4a97e599f3e..970f99ad0f5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp @@ -35,12 +35,23 @@ #include "interpreter/oopMapCache.hpp" #include "memory/universe.hpp" +bool VM_ShenandoahOperation::doit_prologue() { + assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State can only be changed on a safepoint."); + return true; +} + +void VM_ShenandoahOperation::doit_epilogue() { + assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State was not synchronized to java threads."); +} + bool VM_ShenandoahReferenceOperation::doit_prologue() { + VM_ShenandoahOperation::doit_prologue(); Heap_lock->lock(); return true; } void VM_ShenandoahReferenceOperation::doit_epilogue() { + VM_ShenandoahOperation::doit_epilogue(); OopMapCache::cleanup_old_entries(); if (Universe::has_reference_pending_list()) { Heap_lock->notify_all(); @@ -51,34 +62,41 @@ void VM_ShenandoahReferenceOperation::doit_epilogue() { void VM_ShenandoahInitMark::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT); _gc->entry_init_mark(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahFinalMarkStartEvac::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT); _gc->entry_final_mark(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahFullGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL); _full_gc->entry_full(_gc_cause); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahDegeneratedGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT); _gc->entry_degenerated(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahInitUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_init_updaterefs(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahFinalUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_final_updaterefs(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } void VM_ShenandoahFinalRoots::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT); _gc->entry_final_roots(); + ShenandoahHeap::heap()->set_gc_state_all_threads(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp index 65ddd8b1f11..1b78766935f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp @@ -47,14 +47,16 @@ class VM_ShenandoahOperation : public VM_Operation { uint _gc_id; public: VM_ShenandoahOperation() : _gc_id(GCId::current()) {}; - virtual bool skip_thread_oop_barriers() const { return true; } + bool skip_thread_oop_barriers() const override { return true; } + bool doit_prologue() override; + void doit_epilogue() override; }; class VM_ShenandoahReferenceOperation : public VM_ShenandoahOperation { public: VM_ShenandoahReferenceOperation() : VM_ShenandoahOperation() {}; - bool doit_prologue(); - void doit_epilogue(); + bool doit_prologue() override; + void doit_epilogue() override; }; class VM_ShenandoahInitMark: public VM_ShenandoahOperation { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 1d5d962a4ec..6a977c2e4a4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -620,6 +620,8 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label, guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens"); guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize"); + ShenandoahHeap::heap()->set_gc_state_all_threads(); + // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/); From 93fd1a1d5c1e4627b28cf4cda931d1396a18c54b Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 14 Mar 2024 09:04:45 +0000 Subject: [PATCH 062/298] 8324238: [macOS] java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java fails with the shape has not been applied msg Backport-of: 62c9530c056dbaaf65be0f43295af3d225326a4c --- .../ShapeNotSetSometimes.java | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java index 48a0e75ead0..52a5754a9c3 100644 --- a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java +++ b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java @@ -21,8 +21,6 @@ * questions. */ - - import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; @@ -44,7 +42,7 @@ * @key headful * @bug 6988428 * @summary Tests whether shape is always set - * @run main ShapeNotSetSometimes + * @run main/othervm -Dsun.java2d.uiScale=1 ShapeNotSetSometimes */ public class ShapeNotSetSometimes { @@ -55,22 +53,24 @@ public class ShapeNotSetSometimes { private Point[] pointsOutsideToCheck; private Point[] shadedPointsToCheck; private Point innerPoint; - private final Rectangle bounds = new Rectangle(220, 400, 300, 300); private static Robot robot; private static final Color BACKGROUND_COLOR = Color.GREEN; private static final Color SHAPE_COLOR = Color.WHITE; + private static final int DIM = 300; + private static final int DELTA = 2; public ShapeNotSetSometimes() throws Exception { EventQueue.invokeAndWait(this::initializeGUI); robot.waitForIdle(); - robot.delay(1000); + robot.delay(500); } private void initializeGUI() { backgroundFrame = new BackgroundFrame(); backgroundFrame.setUndecorated(true); - backgroundFrame.setBounds(bounds); + backgroundFrame.setSize(DIM, DIM); + backgroundFrame.setLocationRelativeTo(null); backgroundFrame.setVisible(true); Area area = new Area(); @@ -81,8 +81,10 @@ private void initializeGUI() { area.add(new Area(new Ellipse2D.Float(150, 50, 100, 100))); area.add(new Area(new Ellipse2D.Float(150, 100, 100, 100))); - + // point at the center of white ellipse innerPoint = new Point(150, 130); + + // mid points on the 4 sides - on the green background frame pointsOutsideToCheck = new Point[] { new Point(150, 20), new Point(280, 120), @@ -90,6 +92,7 @@ private void initializeGUI() { new Point(20, 120) }; + // points just outside the ellipse (opposite side of diagonal) shadedPointsToCheck = new Point[] { new Point(62, 62), new Point(240, 185) @@ -97,7 +100,8 @@ private void initializeGUI() { window = new TestFrame(); window.setUndecorated(true); - window.setBounds(bounds); + window.setSize(DIM, DIM); + window.setLocationRelativeTo(null); window.setShape(area); window.setVisible(true); } @@ -108,7 +112,7 @@ static class BackgroundFrame extends Frame { public void paint(Graphics g) { g.setColor(BACKGROUND_COLOR); - g.fillRect(0, 0, 300, 300); + g.fillRect(0, 0, DIM, DIM); super.paint(g); } @@ -120,7 +124,7 @@ class TestFrame extends Frame { public void paint(Graphics g) { g.setColor(SHAPE_COLOR); - g.fillRect(0, 0, bounds.width, bounds.height); + g.fillRect(0, 0, DIM, DIM); super.paint(g); } @@ -155,17 +159,24 @@ private void doTest() throws Exception { } } finally { EventQueue.invokeAndWait(() -> { - backgroundFrame.dispose(); - window.dispose(); + if (backgroundFrame != null) { + backgroundFrame.dispose(); + } + if (window != null) { + window.dispose(); + } }); } } private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpectedColor) { - int screenX = window.getX() + x; int screenY = window.getY() + y; + robot.mouseMove(screenX, screenY); + robot.waitForIdle(); + robot.delay(50); + Color actualColor = robot.getPixelColor(screenX, screenY); System.out.printf( @@ -176,7 +187,7 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte expectedColor ); - if (mustBeExpectedColor != expectedColor.equals(actualColor)) { + if (mustBeExpectedColor != colorCompare(expectedColor, actualColor)) { captureScreen(); System.out.printf("window.getX() = %3d, window.getY() = %3d\n", window.getX(), window.getY()); System.err.printf( @@ -190,6 +201,15 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte } } + private static boolean colorCompare(Color expected, Color actual) { + if (Math.abs(expected.getRed() - actual.getRed()) <= DELTA + && Math.abs(expected.getGreen() - actual.getGreen()) <= DELTA + && Math.abs(expected.getBlue() - actual.getBlue()) <= DELTA) { + return true; + } + return false; + } + private static void captureScreen() { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle screenBounds = new Rectangle(0, 0, screenSize.width, screenSize.height); From e3b6098b4c97ca0f55ed1c160f6b7dc484cb3a12 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Thu, 14 Mar 2024 17:09:38 +0000 Subject: [PATCH 063/298] 8322503: Shenandoah: Clarify gc state usage Reviewed-by: shade Backport-of: 51238c4bdbce48f6b719f7dcfe5b7df8b8c6d85b --- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 14 +++++++------- src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp | 13 ++++++++++--- .../gc/shenandoah/shenandoahThreadLocalData.hpp | 1 + .../share/gc/shenandoah/shenandoahVMOperations.cpp | 14 +++++++------- .../share/gc/shenandoah/shenandoahVerifier.cpp | 2 +- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 329ea941eec..71f1747a760 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1682,7 +1682,7 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) { _update_refs_iterator.reset(); } -void ShenandoahHeap::set_gc_state_all_threads() { +void ShenandoahHeap::propagate_gc_state_to_java_threads() { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); if (_gc_state_changed) { _gc_state_changed = false; @@ -1693,7 +1693,7 @@ void ShenandoahHeap::set_gc_state_all_threads() { } } -void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) { +void ShenandoahHeap::set_gc_state(uint mask, bool value) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); _gc_state.set_cond(mask, value); _gc_state_changed = true; @@ -1701,13 +1701,13 @@ void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) { void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) { assert(!has_forwarded_objects(), "Not expected before/after mark phase"); - set_gc_state_mask(MARKING, in_progress); + set_gc_state(MARKING, in_progress); ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress); } void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint"); - set_gc_state_mask(EVACUATION, in_progress); + set_gc_state(EVACUATION, in_progress); } void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { @@ -1719,7 +1719,7 @@ void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { } void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool cond) { - set_gc_state_mask(WEAK_ROOTS, cond); + set_gc_state(WEAK_ROOTS, cond); } GCTracer* ShenandoahHeap::tracer() { @@ -1838,7 +1838,7 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) { } void ShenandoahHeap::set_has_forwarded_objects(bool cond) { - set_gc_state_mask(HAS_FORWARDED, cond); + set_gc_state(HAS_FORWARDED, cond); } void ShenandoahHeap::set_unload_classes(bool uc) { @@ -1877,7 +1877,7 @@ void ShenandoahHeap::set_full_gc_move_in_progress(bool in_progress) { } void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) { - set_gc_state_mask(UPDATEREFS, in_progress); + set_gc_state(UPDATEREFS, in_progress); } void ShenandoahHeap::register_nmethod(nmethod* nm) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 60db6e5776b..bc9a6eed701 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -289,12 +289,19 @@ class ShenandoahHeap : public CollectedHeap { ShenandoahSharedFlag _progress_last_gc; ShenandoahSharedFlag _concurrent_strong_root_in_progress; - void set_gc_state_mask(uint mask, bool value); + // This updates the singlular, global gc state. This must happen on a safepoint. + void set_gc_state(uint mask, bool value); public: char gc_state() const; - void set_gc_state_all_threads(); - bool has_gc_state_changed() { return _gc_state_changed; } + + // This copies the global gc state into a thread local variable for java threads. + // It is primarily intended to support quick access at barriers. + void propagate_gc_state_to_java_threads(); + + // This is public to support assertions that the state hasn't been changed off of + // a safepoint and that any changes were propagated to java threads after the safepoint. + bool has_gc_state_changed() const { return _gc_state_changed; } void set_concurrent_mark_in_progress(bool in_progress); void set_evacuation_in_progress(bool in_progress); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp index 422595e9313..9eec573cc56 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp @@ -89,6 +89,7 @@ class ShenandoahThreadLocalData { } static char gc_state(Thread* thread) { + assert(thread->is_Java_thread(), "GC state is only synchronized to java threads"); return data(thread)->_gc_state; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp index 970f99ad0f5..eeeb1dcad19 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp @@ -62,41 +62,41 @@ void VM_ShenandoahReferenceOperation::doit_epilogue() { void VM_ShenandoahInitMark::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT); _gc->entry_init_mark(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalMarkStartEvac::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT); _gc->entry_final_mark(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFullGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL); _full_gc->entry_full(_gc_cause); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahDegeneratedGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT); _gc->entry_degenerated(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahInitUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_init_updaterefs(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_final_updaterefs(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalRoots::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT); _gc->entry_final_roots(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 6a977c2e4a4..f67cafdb8fe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -620,7 +620,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label, guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens"); guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize"); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/); From 58b3403ada0610d0214db45c2d67e759db8de497 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:08:02 +0000 Subject: [PATCH 064/298] 8310234: Refactor Locale tests to use JUnit Backport-of: dad7bd9efc7ca2c245f7e35267479670f93a53a8 --- ...Locales.java => AvailableLocalesTest.java} | 59 ++++++-- test/jdk/java/util/Locale/Bug4316602.java | 45 ------- ...{Bug4210525.java => CaseCheckVariant.java} | 51 ++++--- ...54797.java => CompareProviderFormats.java} | 62 +++++---- ...8004240.java => GetAdapterPreference.java} | 28 ++-- .../java/util/Locale/GetInstanceCheck.java | 126 ++++++++++++++++++ .../java/util/Locale/LocaleConstructors.java | 79 +++++++++++ .../{bug6277243.java => RootLocale.java} | 21 ++- test/jdk/java/util/Locale/bug4122700.java | 60 --------- test/jdk/java/util/Locale/bug6312358.java | 83 ------------ 10 files changed, 356 insertions(+), 258 deletions(-) rename test/jdk/java/util/Locale/{StreamAvailableLocales.java => AvailableLocalesTest.java} (57%) delete mode 100644 test/jdk/java/util/Locale/Bug4316602.java rename test/jdk/java/util/Locale/{Bug4210525.java => CaseCheckVariant.java} (52%) rename test/jdk/java/util/Locale/{Bug8154797.java => CompareProviderFormats.java} (68%) rename test/jdk/java/util/Locale/{Bug8004240.java => GetAdapterPreference.java} (66%) create mode 100644 test/jdk/java/util/Locale/GetInstanceCheck.java create mode 100644 test/jdk/java/util/Locale/LocaleConstructors.java rename test/jdk/java/util/Locale/{bug6277243.java => RootLocale.java} (72%) delete mode 100644 test/jdk/java/util/Locale/bug4122700.java delete mode 100644 test/jdk/java/util/Locale/bug6312358.java diff --git a/test/jdk/java/util/Locale/StreamAvailableLocales.java b/test/jdk/java/util/Locale/AvailableLocalesTest.java similarity index 57% rename from test/jdk/java/util/Locale/StreamAvailableLocales.java rename to test/jdk/java/util/Locale/AvailableLocalesTest.java index ea7757f03f0..c0d141f6da7 100644 --- a/test/jdk/java/util/Locale/StreamAvailableLocales.java +++ b/test/jdk/java/util/Locale/AvailableLocalesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, 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 @@ -20,30 +20,45 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + /* * @test - * @summary Test the implementation - * of Locale.availableLocales() - * @bug 8282319 - * @run junit StreamAvailableLocales + * @bug 4122700 8282319 + * @summary Verify implementation of getAvailableLocales() and availableLocales() + * @run junit AvailableLocalesTest */ import java.util.Arrays; import java.util.Locale; import java.util.stream.Stream; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.Arguments; -public class StreamAvailableLocales { +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class AvailableLocalesTest { + + /** + * Test that Locale.getAvailableLocales() is non-empty and prints out + * the returned locales - 4122700. + */ + @Test + public void nonEmptyLocalesTest() { + Locale[] systemLocales = Locale.getAvailableLocales(); + assertNotEquals(systemLocales.length, 0, "Available locale list is empty!"); + System.out.println("Found " + systemLocales.length + " locales:"); + printLocales(systemLocales); + } /** * Test to validate that the methods: Locale.getAvailableLocales() * and Locale.availableLocales() contain the same underlying elements */ @Test - public void testStreamEqualsArray() { + public void streamEqualsArrayTest() { Locale[] arrayLocales = Locale.getAvailableLocales(); Stream streamedLocales = Locale.availableLocales(); Locale[] convertedLocales = streamedLocales.toArray(Locale[]::new); @@ -63,7 +78,7 @@ public void testStreamEqualsArray() { */ @ParameterizedTest @MethodSource("requiredLocaleProvider") - public void testStreamRequirements(Locale requiredLocale, String localeName) { + public void requiredLocalesTest(Locale requiredLocale, String localeName) { if (Locale.availableLocales().anyMatch(loc -> (loc.equals(requiredLocale)))) { System.out.printf("$$$ Passed: Stream has %s!%n", localeName); } else { @@ -72,6 +87,32 @@ public void testStreamRequirements(Locale requiredLocale, String localeName) { } } + // Helper method to print out all the system locales + private void printLocales(Locale[] systemLocales) { + Locale[] locales = new Locale[systemLocales.length]; + for (int i = 0; i < locales.length; i++) { + Locale lowest = null; + for (Locale systemLocale : systemLocales) { + if (i > 0 && locales[i - 1].toString().compareTo(systemLocale.toString()) >= 0) + continue; + if (lowest == null || systemLocale.toString().compareTo(lowest.toString()) < 0) + lowest = systemLocale; + } + locales[i] = lowest; + } + for (Locale locale : locales) { + if (locale.getCountry().length() == 0) + System.out.println(" " + locale.getDisplayLanguage() + ":"); + else { + if (locale.getVariant().length() == 0) + System.out.println(" " + locale.getDisplayCountry()); + else + System.out.println(" " + locale.getDisplayCountry() + ", " + + locale.getDisplayVariant()); + } + } + } + // Data provider for testStreamRequirements private static Stream requiredLocaleProvider() { return Stream.of( diff --git a/test/jdk/java/util/Locale/Bug4316602.java b/test/jdk/java/util/Locale/Bug4316602.java deleted file mode 100644 index 3f34128f74f..00000000000 --- a/test/jdk/java/util/Locale/Bug4316602.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - @test - @summary Locale constructor should allow language-only argument - @bug 4316602 - @author joconner -*/ - -import java.util.Locale; - -public class Bug4316602 { - - public static void main(String[] args) throws Exception { - String language = "ja"; - Locale aLocale = Locale.of(language); - if (aLocale.toString().equals(language)) { - System.out.println("passed"); - } else { - System.out.println("Bug4316602 failed"); - throw new Exception("Bug4316602 failed"); - } - } - -} diff --git a/test/jdk/java/util/Locale/Bug4210525.java b/test/jdk/java/util/Locale/CaseCheckVariant.java similarity index 52% rename from test/jdk/java/util/Locale/Bug4210525.java rename to test/jdk/java/util/Locale/CaseCheckVariant.java index bcd68ee890e..29ecdd0ea4c 100644 --- a/test/jdk/java/util/Locale/Bug4210525.java +++ b/test/jdk/java/util/Locale/CaseCheckVariant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, 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 @@ -20,30 +20,43 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/** - @test - @summary Locale variant should not be uppercased - @run main Bug4210525 - @bug 4210525 -*/ + +/* + * @test + * @bug 4210525 + * @summary Locale variant should not be case folded + * @run junit CaseCheckVariant + */ import java.util.Locale; +import java.util.stream.Stream; -public class Bug4210525 { +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; - public static void main(String[] args) throws Exception { - String language = "en"; - String country = "US"; - String variant = "socal"; +import static org.junit.jupiter.api.Assertions.assertEquals; - Locale aLocale = Locale.of(language, country, variant); +public class CaseCheckVariant { + static final String LANG = "en"; + static final String COUNTRY = "US"; + + /** + * When a locale is created with a given variant, ensure + * that the variant is not case normalized. + */ + @ParameterizedTest + @MethodSource("variants") + public void variantCaseTest(String variant) { + Locale aLocale = Locale.of(LANG, COUNTRY, variant); String localeVariant = aLocale.getVariant(); - if (localeVariant.equals(variant)) { - System.out.println("passed"); - } else { - System.out.println("failed"); - throw new Exception("Bug4210525 test failed."); - } + assertEquals(localeVariant, variant); + } + + private static Stream variants() { + return Stream.of( + "socal", + "Norcal" + ); } } diff --git a/test/jdk/java/util/Locale/Bug8154797.java b/test/jdk/java/util/Locale/CompareProviderFormats.java similarity index 68% rename from test/jdk/java/util/Locale/Bug8154797.java rename to test/jdk/java/util/Locale/CompareProviderFormats.java index 31d9593d447..225043624c7 100644 --- a/test/jdk/java/util/Locale/Bug8154797.java +++ b/test/jdk/java/util/Locale/CompareProviderFormats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -28,43 +28,65 @@ * java.base/sun.util.resources * jdk.localedata * @summary Test for checking HourFormat and GmtFormat resources are retrieved from - * COMPAT and CLDR Providers. + * COMPAT and CLDR Providers. + * @run junit CompareProviderFormats */ import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; +import java.util.stream.Stream; + import sun.util.locale.provider.LocaleProviderAdapter.Type; import sun.util.locale.provider.LocaleProviderAdapter; -public class Bug8154797 { +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class CompareProviderFormats { static Map expectedResourcesMap = new HashMap<>(); static final String GMT_RESOURCE_KEY = "timezone.gmtFormat"; static final String HMT_RESOURCE_KEY = "timezone.hourFormat"; static final String GMT = "Gmt"; static final String HMT = "Hmt"; - static void generateExpectedValues() { + /** + * Fill the expectedResourcesMap with the desired key / values + */ + @BeforeAll + static void populateResourcesMap() { expectedResourcesMap.put("FR" + GMT, "UTC{0}"); expectedResourcesMap.put("FR" + HMT, "+HH:mm;\u2212HH:mm"); expectedResourcesMap.put("FI" + HMT, "+H.mm;-H.mm"); expectedResourcesMap.put("FI" + GMT, "UTC{0}"); - /* For root locale, en_US, de_DE, hi_IN, ja_JP,Root locale resources - * should be returned. + /* For root locale, en_US, de_DE, hi_IN, ja_JP, Root locale resources + * should be returned. */ - expectedResourcesMap.put(GMT, "GMT{0}"); //Root locale resource - expectedResourcesMap.put(HMT, "+HH:mm;-HH:mm"); //Root locale resource + expectedResourcesMap.put(GMT, "GMT{0}"); // Root locale resource + expectedResourcesMap.put(HMT, "+HH:mm;-HH:mm"); // Root locale resource + } + + /** + * For each locale, ensure that the returned resources for gmt and hmt match + * the expected resources for both COMPAT and CLDR + */ + @ParameterizedTest + @MethodSource("localeProvider") + public void compareResourcesTest(Locale loc) { + compareResources(loc); } - static void compareResources(Locale loc) { + private void compareResources(Locale loc) { String mapKeyHourFormat = HMT, mapKeyGmtFormat = GMT; ResourceBundle compatBundle, cldrBundle; compatBundle = LocaleProviderAdapter.forJRE().getLocaleResources(loc) .getJavaTimeFormatData(); cldrBundle = LocaleProviderAdapter.forType(Type.CLDR) .getLocaleResources(loc).getJavaTimeFormatData(); - if (loc.getCountry() == "FR" || loc.getCountry() == "FI") { + + if (loc.getCountry().equals("FR") || loc.getCountry().equals("FI")) { mapKeyHourFormat = loc.getCountry() + HMT; mapKeyGmtFormat = loc.getCountry() + GMT; } @@ -77,23 +99,17 @@ static void compareResources(Locale loc) { .equals(cldrBundle.getString(GMT_RESOURCE_KEY)) && expectedResourcesMap.get(mapKeyHourFormat) .equals(cldrBundle.getString(HMT_RESOURCE_KEY)))) { - throw new RuntimeException("Retrieved resource does not match with " + " expected string for Locale " + compatBundle.getLocale()); - } - } - public static void main(String args[]) { - Bug8154797.generateExpectedValues(); - Locale[] locArr = {Locale.of("hi", "IN"), Locale.UK, Locale.of("fi", "FI"), - Locale.ROOT, Locale.GERMAN, Locale.JAPANESE, - Locale.ENGLISH, Locale.FRANCE}; - for (Locale loc : locArr) { - Bug8154797.compareResources(loc); - } + private static Stream localeProvider() { + return Stream.of( + Locale.of("hi", "IN"), + Locale.UK, Locale.of("fi", "FI"), + Locale.ROOT, Locale.GERMAN, Locale.JAPANESE, + Locale.ENGLISH, Locale.FRANCE + ); } - } - diff --git a/test/jdk/java/util/Locale/Bug8004240.java b/test/jdk/java/util/Locale/GetAdapterPreference.java similarity index 66% rename from test/jdk/java/util/Locale/Bug8004240.java rename to test/jdk/java/util/Locale/GetAdapterPreference.java index 6725c792cb7..fd21ac5fa60 100644 --- a/test/jdk/java/util/Locale/Bug8004240.java +++ b/test/jdk/java/util/Locale/GetAdapterPreference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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,25 +26,27 @@ * @bug 8004240 * @summary Verify that getAdapterPreference returns an unmodifiable list. * @modules java.base/sun.util.locale.provider - * @compile -XDignore.symbol.file Bug8004240.java - * @run main Bug8004240 + * @compile -XDignore.symbol.file GetAdapterPreference.java + * @run junit GetAdapterPreference */ import java.util.List; import sun.util.locale.provider.LocaleProviderAdapter; -public class Bug8004240 { +import org.junit.jupiter.api.Test; - public static void main(String[] args) { - List types = LocaleProviderAdapter.getAdapterPreference(); +import static org.junit.jupiter.api.Assertions.assertThrows; - try { - types.set(0, null); - } catch (UnsupportedOperationException e) { - // success - return; - } +public class GetAdapterPreference { - throw new RuntimeException("LocaleProviderAdapter.getAdapterPrefence() returned a modifiable list."); + /** + * Test that the list returned from getAdapterPreference() + * cannot be modified. + */ + @Test + public void immutableTest() { + List types = LocaleProviderAdapter.getAdapterPreference(); + assertThrows(UnsupportedOperationException.class, () -> types.set(0, null), + "Trying to modify list returned from LocaleProviderAdapter.getAdapterPreference() did not throw UOE"); } } diff --git a/test/jdk/java/util/Locale/GetInstanceCheck.java b/test/jdk/java/util/Locale/GetInstanceCheck.java new file mode 100644 index 00000000000..80dfb7d5d7b --- /dev/null +++ b/test/jdk/java/util/Locale/GetInstanceCheck.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6312358 + * @summary Verify that an NPE is thrown by invoking Locale.getInstance() with + * any argument being null. + * @modules java.base/java.util:open + * @run junit GetInstanceCheck + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Locale; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.fail; + +public class GetInstanceCheck { + + static Method getInstanceMethod; + static final String NAME = "getInstance"; + + /** + * Initialize the non-public Locale.getInstance() method. + */ + @BeforeAll + static void initializeMethod() { + try { + // Locale.getInstance is not directly accessible. + getInstanceMethod = Locale.class.getDeclaredMethod( + NAME, String.class, String.class, String.class + ); + getInstanceMethod.setAccessible(true); + } catch (java.lang.NoSuchMethodException exc) { + // The test should fail if we can not test the desired method + fail(String.format("Tried to get the method '%s' which was not found," + + " further testing is not possible, failing test", NAME)); + } + } + + /** + * Exists as sanity check that Locale.getInstance() will not throw + * an NPE if no arguments are null. + */ + @ParameterizedTest + @MethodSource("passingArguments") + public void noNPETest(String language, String country, String variant) + throws IllegalAccessException { + try { + getInstanceMethod.invoke(null, language, country, variant); + } catch (InvocationTargetException exc) { + // Determine underlying exception + Throwable cause = exc.getCause(); + if (exc.getCause() instanceof NullPointerException) { + fail(String.format("%s should not be thrown when no args are null", cause)); + } else { + fail(String.format("%s unexpectedly thrown, when no exception should be thrown", cause)); + } + } + } + + /** + * Make sure the Locale.getInstance() method throws an NPE + * if any given argument is null. + */ + @ParameterizedTest + @MethodSource("failingArguments") + public void throwNPETest(String language, String country, String variant) + throws IllegalAccessException { + try { + getInstanceMethod.invoke(null, language, country, variant); + fail("Should NPE with any argument set to null"); + } catch (InvocationTargetException exc) { + // Determine underlying exception + Throwable cause = exc.getCause(); + if (cause instanceof NullPointerException) { + System.out.println("NPE successfully thrown"); + } else { + fail(cause + " is thrown, when NPE should have been thrown"); + } + } + } + + private static Stream passingArguments() { + return Stream.of( + Arguments.of("null", "GB", ""), + Arguments.of("en", "null", ""), + Arguments.of("en", "GB", "null") + ); + } + + private static Stream failingArguments() { + return Stream.of( + Arguments.of(null, "GB", ""), + Arguments.of("en", null, ""), + Arguments.of("en", "GB", null) + ); + } +} diff --git a/test/jdk/java/util/Locale/LocaleConstructors.java b/test/jdk/java/util/Locale/LocaleConstructors.java new file mode 100644 index 00000000000..4ca754a1eab --- /dev/null +++ b/test/jdk/java/util/Locale/LocaleConstructors.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4316602 + * @author joconner + * @summary Verify all Locale constructors and of() methods + * @run junit LocaleConstructors + */ + +import java.util.Locale; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * This class tests to ensure that the language, language/country, and + * language/country/variant Locale constructors + of() method are all allowed. + */ +public class LocaleConstructors { + + static final String LANG = "en"; + static final String COUNTRY = "US"; + static final String VAR = "socal"; + + // Test Locale constructor and .of() allow (language) argument(s) + @Test + public void langTest() { + Locale aLocale = Locale.of(LANG); + Locale otherLocale = new Locale(LANG); + assertEquals(aLocale.toString(), LANG); + assertEquals(otherLocale.toString(), LANG); + } + + // Test Locale constructor and .of() allow (language, constructor) argument(s) + @Test + public void langCountryTest() { + Locale aLocale = Locale.of(LANG, COUNTRY); + Locale otherLocale = new Locale(LANG, COUNTRY); + assertEquals(aLocale.toString(), String.format("%s_%s", + LANG, COUNTRY)); + assertEquals(otherLocale.toString(), String.format("%s_%s", + LANG, COUNTRY)); + } + + // Test Locale constructor and .of() allow + // (language, constructor, variant) argument(s) + @Test + public void langCountryVariantTest() { + Locale aLocale = Locale.of(LANG, COUNTRY, VAR); + Locale otherLocale = new Locale(LANG, COUNTRY, VAR); + assertEquals(aLocale.toString(), String.format("%s_%s_%s", + LANG, COUNTRY, VAR)); + assertEquals(otherLocale.toString(), String.format("%s_%s_%s", + LANG, COUNTRY, VAR)); + } +} diff --git a/test/jdk/java/util/Locale/bug6277243.java b/test/jdk/java/util/Locale/RootLocale.java similarity index 72% rename from test/jdk/java/util/Locale/bug6277243.java rename to test/jdk/java/util/Locale/RootLocale.java index 00102184bb1..d05e3a14e5a 100644 --- a/test/jdk/java/util/Locale/bug6277243.java +++ b/test/jdk/java/util/Locale/RootLocale.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, 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 @@ -20,20 +20,29 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + /* * @test * @bug 6277243 * @summary Verify that there is Locale.ROOT constant, and it is equal to Locale("", "", "") + * @run junit RootLocale */ import java.util.Locale; -public class bug6277243 { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RootLocale { - public static void main(String[] args) throws Exception { + /** + * Locale.ROOT should exist and match an empty Locale given as + * Locale("", "", ""). + */ + @Test + public void rootTest() { Locale root = Locale.of("", "", ""); - if (!Locale.ROOT.equals(root)) { - throw new RuntimeException("Locale.ROOT is not equal to Locale(\"\", \"\", \"\")"); - } + assertEquals(Locale.ROOT, root, "Locale.ROOT is not equal to Locale(\"\", \"\", \"\")"); } } diff --git a/test/jdk/java/util/Locale/bug4122700.java b/test/jdk/java/util/Locale/bug4122700.java deleted file mode 100644 index 1406caba06e..00000000000 --- a/test/jdk/java/util/Locale/bug4122700.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - * @test - * @bug 4122700 - * @summary Verify that list of available locales is non-empty, and print the list - */ - -import java.util.Locale; - -public class bug4122700 { - public static void main(String[] args) throws Exception { - Locale[] systemLocales = Locale.getAvailableLocales(); - if (systemLocales.length == 0) - throw new Exception("Available locale list is empty!"); - System.out.println("Found " + systemLocales.length + " locales:"); - Locale[] locales = new Locale[systemLocales.length]; - for (int i = 0; i < locales.length; i++) { - Locale lowest = null; - for (int j = 0; j < systemLocales.length; j++) { - if (i > 0 && locales[i - 1].toString().compareTo(systemLocales[j].toString()) >= 0) - continue; - if (lowest == null || systemLocales[j].toString().compareTo(lowest.toString()) < 0) - lowest = systemLocales[j]; - } - locales[i] = lowest; - } - for (int i = 0; i < locales.length; i++) { - if (locales[i].getCountry().length() == 0) - System.out.println(" " + locales[i].getDisplayLanguage() + ":"); - else { - if (locales[i].getVariant().length() == 0) - System.out.println(" " + locales[i].getDisplayCountry()); - else - System.out.println(" " + locales[i].getDisplayCountry() + ", " - + locales[i].getDisplayVariant()); - } - } - } -} diff --git a/test/jdk/java/util/Locale/bug6312358.java b/test/jdk/java/util/Locale/bug6312358.java deleted file mode 100644 index ff2ad347f60..00000000000 --- a/test/jdk/java/util/Locale/bug6312358.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - * @test - * @bug 6312358 - * @summary Verify that an NPE is thrown by issueing Locale.getInstance() with - * any argument being null. - * @modules java.base/java.util:open - */ - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Locale; - -public class bug6312358 { - - - public static void main(String[] args) throws Exception { - - try { - // Locale.getInstance is not directly accessible. - Method getInstanceMethod = Locale.class.getDeclaredMethod( - "getInstance", String.class, String.class, String.class - ); - getInstanceMethod.setAccessible(true); - - getInstanceMethod.invoke(null, "null", "GB", ""); - try { - getInstanceMethod.invoke(null, null, "GB", ""); - throw new RuntimeException("Should NPE with language set to null"); - } catch (InvocationTargetException exc) { - Throwable cause = exc.getCause(); - if (!(cause instanceof NullPointerException)) { - throw new RuntimeException(cause+" is thrown with language set to null"); - } - } - - getInstanceMethod.invoke(null, "en", "null", ""); - try { - getInstanceMethod.invoke(null, "en", null, ""); - throw new RuntimeException("Should NPE with country set to null"); - } catch (InvocationTargetException exc) { - Throwable cause = exc.getCause(); - if (!(cause instanceof NullPointerException)) { - throw new RuntimeException(cause+" is thrown with country set to null"); - } - } - - getInstanceMethod.invoke(null, "en", "GB", "null"); - try { - getInstanceMethod.invoke(null, "en", "GB", null); - throw new RuntimeException("Should NPE with variant set to null"); - } catch (InvocationTargetException exc) { - Throwable cause = exc.getCause(); - if (!(cause instanceof NullPointerException)) { - throw new RuntimeException(cause+" is thrown with variant set to null"); - } - } - } catch (java.lang.NoSuchMethodException exc) { - // method is not found. consider it as a success - } - } -} From 166aad07e09a971073529ad52eb217f92ccf01c3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:09:15 +0000 Subject: [PATCH 065/298] 8310731: Configure a javax.net.ssl.SNIMatcher for the HTTP/1.1 test servers in java/net/httpclient tests Backport-of: 05e9c41eddf8961d1384c88ccedf993d86822a6b --- .../net/httpclient/AsFileDownloadTest.java | 5 +- .../net/httpclient/AuthFilterCacheTest.java | 5 +- .../net/httpclient/ConcurrentResponses.java | 6 +- .../httpclient/CustomResponseSubscriber.java | 6 +- .../java/net/httpclient/ExpectContinue.java | 11 +- .../java/net/httpclient/HttpRedirectTest.java | 7 +- .../net/httpclient/HttpSlowServerTest.java | 7 +- .../net/httpclient/ImmutableFlowItems.java | 6 +- .../net/httpclient/LargeHandshakeTest.java | 7 +- .../net/httpclient/LargeResponseTest.java | 8 +- .../net/httpclient/LightWeightHttpServer.java | 5 +- .../httpclient/MappingResponseSubscriber.java | 5 +- .../java/net/httpclient/RequestBodyTest.java | 6 +- .../net/httpclient/RequestBodyTest.policy | 7 + .../test/lib/common/HttpServerAdapters.java | 7 +- .../test/lib/common/ServerNameMatcher.java | 152 ++++++++++++++++++ .../lib/common/TestServerConfigurator.java | 75 +++++++++ .../websocket/HandshakeUrlEncodingTest.java | 10 +- .../websocket/WSHandshakeExceptionTest.java | 11 +- 19 files changed, 293 insertions(+), 53 deletions(-) create mode 100644 test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java create mode 100644 test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java index efccdc0e470..d191c8f4d4a 100644 --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java @@ -24,7 +24,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.InputStream; @@ -53,6 +52,7 @@ import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.util.FileUtils; import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2Handler; @@ -75,6 +75,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * jdk.test.lib.Platform jdk.test.lib.util.FileUtils + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm AsFileDownloadTest * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest */ @@ -327,7 +328,7 @@ public void setup() throws Exception { httpURI = "http://" + serverAuthority(httpTestServer) + "/http1/afdt"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/afdt", new Http1FileDispoHandler()); httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1/afdt"; diff --git a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java index 2284d8cd81f..5c322940ea5 100644 --- a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java +++ b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java @@ -35,6 +35,7 @@ import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -51,7 +52,7 @@ * @summary AuthenticationFilter.Cache::remove may throw ConcurrentModificationException * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext - * DigestEchoServer + * DigestEchoServer jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm -Dtest.requiresHost=true * -Djdk.tracePinnedThreads=full * -Djdk.httpclient.HttpClient.log=headers @@ -133,7 +134,7 @@ public void setUp() throws Exception { // HTTPS/1.1 HttpsServer sserver1 = HttpsServer.create(sa, 100); sserver1.setExecutor(serverExecutor); - sserver1.setHttpsConfigurator(new HttpsConfigurator(context)); + sserver1.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), context)); https1Server = HttpTestServer.of(sserver1); https1Server.addHandler(new TestHandler(), "/AuthFilterCacheTest/https1/"); https1Server.start(); diff --git a/test/jdk/java/net/httpclient/ConcurrentResponses.java b/test/jdk/java/net/httpclient/ConcurrentResponses.java index bc3419c1e93..40ee984d09b 100644 --- a/test/jdk/java/net/httpclient/ConcurrentResponses.java +++ b/test/jdk/java/net/httpclient/ConcurrentResponses.java @@ -28,6 +28,7 @@ * unprocessed HTTP data * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm * -Djdk.tracePinnedThreads=full * -Djdk.httpclient.HttpClient.log=headers,errors,channel @@ -55,7 +56,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -64,6 +64,8 @@ import java.net.http.HttpResponse.BodyHandlers; import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2Handler; @@ -291,7 +293,7 @@ public void setup() throws Exception { httpChunkedURI = "http://" + serverAuthority(httpTestServer) + "/http1/chunked"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/fixed", new Http1FixedHandler()); httpsFixedURI = "https://" + serverAuthority(httpsTestServer) + "/https1/fixed"; httpsTestServer.createContext("/https1/chunked", new Http1ChunkedHandler()); diff --git a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java index e0bee8cc74f..be71278a450 100644 --- a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java +++ b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java @@ -26,6 +26,7 @@ * @summary Tests response body subscribers's onComplete is not invoked before onSubscribe * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm CustomResponseSubscriber */ @@ -43,7 +44,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.net.http.HttpClient; import java.net.http.HttpHeaders; @@ -52,6 +52,8 @@ import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2Handler; @@ -200,7 +202,7 @@ public void setup() throws Exception { httpURI_chunk = "http://" + serverAuthority(httpTestServer) + "/http1/chunk"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/fixed", h1_fixedLengthHandler); httpsTestServer.createContext("/https1/chunk", h1_chunkHandler); httpsURI_fixed = "https://" + serverAuthority(httpsTestServer) + "/https1/fixed"; diff --git a/test/jdk/java/net/httpclient/ExpectContinue.java b/test/jdk/java/net/httpclient/ExpectContinue.java index f3bed36c75c..43c65781413 100644 --- a/test/jdk/java/net/httpclient/ExpectContinue.java +++ b/test/jdk/java/net/httpclient/ExpectContinue.java @@ -24,17 +24,16 @@ /* * @test * @summary Basic test for Expect 100-Continue ( HTTP/1.1 only ) - * @modules java.net.http + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestServerConfigurator + * @modules java.net.http/jdk.internal.net.http.common * jdk.httpserver - * @library /test/lib - * @build jdk.test.lib.net.SimpleSSLContext * @run testng/othervm ExpectContinue */ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.InputStream; @@ -49,6 +48,8 @@ import java.net.http.HttpResponse.BodyHandlers; import java.util.List; import javax.net.ssl.SSLContext; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -148,7 +149,7 @@ public void setup() throws Exception { httpURI = "http://" + serverAuthority(httpTestServer) + "/http1/ec"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/ec", new Http1ExpectContinueHandler()); httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1/ec"; diff --git a/test/jdk/java/net/httpclient/HttpRedirectTest.java b/test/jdk/java/net/httpclient/HttpRedirectTest.java index 0cfb009adbf..dedcc36dda7 100644 --- a/test/jdk/java/net/httpclient/HttpRedirectTest.java +++ b/test/jdk/java/net/httpclient/HttpRedirectTest.java @@ -20,9 +20,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; @@ -60,7 +59,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; /** * @test @@ -69,6 +67,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer HttpRedirectTest * jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=false @@ -175,7 +174,7 @@ public void setUp() throws Exception { // HTTPS/1.1 HttpsServer sserver1 = HttpsServer.create(sa, 100); sserver1.setExecutor(executor); - sserver1.setHttpsConfigurator(new HttpsConfigurator(context)); + sserver1.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), context)); https1Server = HttpTestServer.of(sserver1); https1Server.addHandler(new HttpTestRedirectHandler("https", https1Server), "/HttpRedirectTest/https1/"); diff --git a/test/jdk/java/net/httpclient/HttpSlowServerTest.java b/test/jdk/java/net/httpclient/HttpSlowServerTest.java index a1c36e9dc16..85db9bba563 100644 --- a/test/jdk/java/net/httpclient/HttpSlowServerTest.java +++ b/test/jdk/java/net/httpclient/HttpSlowServerTest.java @@ -20,9 +20,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import javax.net.ssl.SSLContext; @@ -51,7 +50,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; @@ -62,6 +60,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * DigestEchoServer HttpSlowServerTest + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=false @@ -138,7 +137,7 @@ public void setUp() throws Exception { // HTTPS/1.1 HttpsServer sserver1 = HttpsServer.create(sa, 100); sserver1.setExecutor(executor); - sserver1.setHttpsConfigurator(new HttpsConfigurator(context)); + sserver1.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), context)); https1Server = HttpTestServer.of(sserver1); https1Server.addHandler(new HttpTestSlowHandler(), "/HttpSlowServerTest/https1/"); https1Server.start(); diff --git a/test/jdk/java/net/httpclient/ImmutableFlowItems.java b/test/jdk/java/net/httpclient/ImmutableFlowItems.java index d917d178538..b440ad646e8 100644 --- a/test/jdk/java/net/httpclient/ImmutableFlowItems.java +++ b/test/jdk/java/net/httpclient/ImmutableFlowItems.java @@ -27,6 +27,7 @@ * and that the buffers are read-only * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm ImmutableFlowItems */ @@ -43,7 +44,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.net.http.HttpClient; import java.net.http.HttpHeaders; @@ -53,6 +53,8 @@ import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; import javax.net.ssl.SSLContext; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2Handler; @@ -189,7 +191,7 @@ public void setup() throws Exception { httpURI_chunk = "http://" + serverAuthority(httpTestServer) + "/http1/chunk"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/fixed", h1_fixedLengthHandler); httpsTestServer.createContext("/https1/chunk", h1_chunkHandler); httpsURI_fixed = "https://" + serverAuthority(httpsTestServer) + "/https1/fixed"; diff --git a/test/jdk/java/net/httpclient/LargeHandshakeTest.java b/test/jdk/java/net/httpclient/LargeHandshakeTest.java index b5c3dfefe8c..1f4c85b361e 100644 --- a/test/jdk/java/net/httpclient/LargeHandshakeTest.java +++ b/test/jdk/java/net/httpclient/LargeHandshakeTest.java @@ -20,8 +20,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import javax.net.ssl.KeyManagerFactory; @@ -61,7 +59,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; @@ -82,6 +80,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * DigestEchoServer + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=true @@ -1011,7 +1010,7 @@ public void setUp() throws Exception { // HTTPS/1.1 HttpsServer sserver1 = HttpsServer.create(sa, 100); sserver1.setExecutor(executor); - sserver1.setHttpsConfigurator(new HttpsConfigurator(context)); + sserver1.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), context)); https1Server = HttpTestServer.of(sserver1); https1Server.addHandler(new HttpTestLargeHandler(), "/LargeHandshakeTest/https1/"); https1Server.start(); diff --git a/test/jdk/java/net/httpclient/LargeResponseTest.java b/test/jdk/java/net/httpclient/LargeResponseTest.java index 1d788f62f4c..bfc7c9ca5db 100644 --- a/test/jdk/java/net/httpclient/LargeResponseTest.java +++ b/test/jdk/java/net/httpclient/LargeResponseTest.java @@ -20,9 +20,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import javax.net.ssl.SSLContext; @@ -38,7 +37,6 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.List; import java.util.Set; @@ -51,7 +49,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; @@ -64,6 +61,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters * jdk.test.lib.net.SimpleSSLContext DigestEchoServer + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=true @@ -136,7 +134,7 @@ public void setUp() throws Exception { // HTTPS/1.1 HttpsServer sserver1 = HttpsServer.create(sa, 100); sserver1.setExecutor(executor); - sserver1.setHttpsConfigurator(new HttpsConfigurator(context)); + sserver1.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), context)); https1Server = HttpTestServer.of(sserver1); https1Server.addHandler(new HttpTestLargeHandler(), "/LargeResponseTest/https1/"); https1Server.start(); diff --git a/test/jdk/java/net/httpclient/LightWeightHttpServer.java b/test/jdk/java/net/httpclient/LightWeightHttpServer.java index 92603d55d0a..c226b845527 100644 --- a/test/jdk/java/net/httpclient/LightWeightHttpServer.java +++ b/test/jdk/java/net/httpclient/LightWeightHttpServer.java @@ -33,7 +33,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.InputStream; @@ -50,6 +49,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLContext; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; public class LightWeightHttpServer { @@ -111,7 +112,7 @@ public static void initServer() throws IOException { httpServer.setExecutor(executor); httpsServer.setExecutor(executor); ctx = new SimpleSSLContext().get(); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(ctx)); + httpsServer.setHttpsConfigurator(new TestServerConfigurator(addr.getAddress(), ctx)); httpServer.start(); httpsServer.start(); diff --git a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java index 8ae7b5d85dc..6f5964970cc 100644 --- a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java +++ b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java @@ -26,6 +26,7 @@ * @summary Tests mapped response subscriber * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.common.TestServerConfigurator * @run testng/othervm * -Djdk.internal.httpclient.debug=true * MappingResponseSubscriber @@ -46,7 +47,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import java.net.http.HttpClient; import java.net.http.HttpHeaders; @@ -59,6 +59,7 @@ import java.util.function.Function; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.internal.net.http.common.OperationTrackers.Tracker; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; @@ -230,7 +231,7 @@ public void setup() throws Exception { httpURI_chunk = "http://" + serverAuthority(httpTestServer) + "/http1/chunk"; httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsTestServer.createContext("/https1/fixed", h1_fixedLengthHandler); httpsTestServer.createContext("/https1/chunk", h1_chunkHandler); httpsURI_fixed = "https://" + serverAuthority(httpsTestServer) + "/https1/fixed"; diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.java b/test/jdk/java/net/httpclient/RequestBodyTest.java index 805a5b490db..771192564b0 100644 --- a/test/jdk/java/net/httpclient/RequestBodyTest.java +++ b/test/jdk/java/net/httpclient/RequestBodyTest.java @@ -59,14 +59,14 @@ /* * @test * @bug 8087112 - * @modules java.net.http + * @modules java.net.http/jdk.internal.net.http.common * java.logging * jdk.httpserver - * @library /test/lib + * @library /test/lib /test/jdk/java/net/httpclient/lib * @compile ../../../com/sun/net/httpserver/LogFilter.java * @compile ../../../com/sun/net/httpserver/EchoHandler.java * @compile ../../../com/sun/net/httpserver/FileServerHandler.java - * @build jdk.test.lib.net.SimpleSSLContext + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestServerConfigurator * @build LightWeightHttpServer * @build jdk.test.lib.Platform * @build jdk.test.lib.util.FileUtils diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.policy b/test/jdk/java/net/httpclient/RequestBodyTest.policy index 0bfedf22b84..d1ff89cbcd5 100644 --- a/test/jdk/java/net/httpclient/RequestBodyTest.policy +++ b/test/jdk/java/net/httpclient/RequestBodyTest.policy @@ -33,6 +33,11 @@ grant codeBase "file:${test.classes}/../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../lib/jdk/test/lib/net/testkeys", "read"; }; +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../test/jdk/java/net/httpclient/lib/-" { + permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; +}; + grant codeBase "file:${test.classes}/*" { permission java.io.FilePermission "${test.src}${/}docs${/}files${/}smallfile.txt", "read"; permission java.io.FilePermission "${test.src}${/}docs${/}files${/}notsobigfile.txt", "read"; @@ -52,4 +57,6 @@ grant codeBase "file:${test.classes}/*" { permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; + + permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; }; diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java index 623644df5a6..e18dd87a507 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java @@ -30,7 +30,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.httpclient.test.lib.http2.Http2TestExchange; @@ -798,14 +797,14 @@ public static HttpTestServer create(Version serverVersion, SSLContext sslContext return HttpTestServer.of(underlying); } case HTTP_1_1 -> { - InetSocketAddress sa = new InetSocketAddress( - InetAddress.getLoopbackAddress(), 0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress sa = new InetSocketAddress(loopback, 0); HttpServer underlying; if (sslContext == null) { underlying = HttpServer.create(sa, 0); // HTTP } else { HttpsServer https = HttpsServer.create(sa, 0); // HTTPS - https.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + https.setHttpsConfigurator(new TestServerConfigurator(loopback, sslContext)); underlying = https; } if (executor != null) { 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 new file mode 100644 index 00000000000..5e7a5790807 --- /dev/null +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2023, 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. + */ +package jdk.httpclient.test.lib.common; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Objects; +import java.util.Set; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.StandardConstants; + +import jdk.internal.net.http.common.Logger; +import jdk.internal.net.http.common.Utils; + +/** + * A (server side) SNI host name matcher. Implementation is based on the expectations set in + * section 3 of RFC-6066. + * A server can be configured with an instance of this class. + *

    + * The RFC states: + * {@code + * Currently, the only server names supported are DNS hostnames; however, this does not imply + * any dependency of TLS on DNS, + * .... + * TLS MAY treat provided server names as opaque data and pass the names and types to the application. + * } + *

    + * The implementation in this class doesn't mandate the configured/recognized SNI host name as DNS + * resolvable. However, the {@code ServerNameMatcher} can be configured to treat the SNI host name + * as DNS resolvable by passing {@code true} to the {@code attemptDNSResolution} parameter of + * the {@link #ServerNameMatcher(boolean, String) constructor} + */ +public class ServerNameMatcher extends SNIMatcher { + + private final Logger debug; + private final boolean attemptDNSResolution; + private final Set recognizedSNINames; + + /** + * Creates a ServerNameMatcher which recognizes the passed {@code recognizedSNIName} + * + * @param recognizedSNIName The SNI host name + */ + public ServerNameMatcher(final String recognizedSNIName) { + this(false, recognizedSNIName); + } + + /** + * Creates a ServerNameMatcher which recognizes the passed SNI host name + * If {@code attemptDNSResolution} is {@code true}, then when + * {@link #matches(SNIServerName) matching} a client requested SNI name against the server + * recognized SNI name, the implementation will, as a last resort do a DNS resolution of the + * client requested SNI name and the server recognized SNI name and compare them to + * try and find a match. If {@code attemptDNSResolution} is false, then no DNS resolution is + * attempted and instead the SNI names are literally compared. + * + * @param attemptDNSResolution If true then a DNS resolution will be attempted during + * {@link #matches(SNIServerName) SNI matching} + * @param recognizedSNIName SNI host name + */ + public ServerNameMatcher(final boolean attemptDNSResolution, + final String recognizedSNIName) { + super(StandardConstants.SNI_HOST_NAME); + Objects.requireNonNull(recognizedSNIName); + this.debug = Utils.getDebugLogger(() -> "SNIMatcher"); + this.recognizedSNINames = Set.of(recognizedSNIName); + this.attemptDNSResolution = attemptDNSResolution; + } + + /** + * @param clientRequestedSNI the SNI name requested by the client + * {@return true if the {@code clientRequestedSNI} is recognized by + * the server. false otherwise} + */ + @Override + public boolean matches(final SNIServerName clientRequestedSNI) { + Objects.requireNonNull(clientRequestedSNI); + if (!SNIHostName.class.isInstance(clientRequestedSNI)) { + if (debug.on()) { + debug.log("SNI match (against " + recognizedSNINames + ")" + + " failed - not a SNIHostName: " + clientRequestedSNI); + } + // we only support SNIHostName type + return false; + } + final String requestedName = ((SNIHostName) clientRequestedSNI).getAsciiName(); + if (recognizedSNINames.contains(requestedName)) { + if (debug.on()) { + debug.log("SNI match (against " + recognizedSNINames + ") passed: " + + clientRequestedSNI); + } + return true; + } + if (attemptDNSResolution) { + final boolean res = matchesAfterDNSResolution(requestedName); + if (debug.on()) { + debug.log("SNI match (against " + recognizedSNINames + ") " + + (res ? "passed" : "failed") + ": " + clientRequestedSNI); + } + return res; + } + if (debug.on()) { + debug.log("SNI match (against " + recognizedSNINames + ") failed: " + clientRequestedSNI); + } + return false; + } + + private boolean matchesAfterDNSResolution(final String clientRequestedSNI) { + final InetAddress clientRequestedAddr; + try { + clientRequestedAddr = InetAddress.getByName(clientRequestedSNI); + } catch (IOException e) { + return false; + } + for (final String recognizedSNIName : recognizedSNINames) { + final InetAddress serverRecognizedAddr; + try { + serverRecognizedAddr = InetAddress.getByName(recognizedSNIName); + } catch (IOException e) { + // try next + continue; + } + if (serverRecognizedAddr.equals(clientRequestedAddr)) { + return true; + } + } + return false; + } +} diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java new file mode 100644 index 00000000000..5d16ac24155 --- /dev/null +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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. + */ +package jdk.httpclient.test.lib.common; + +import java.net.InetAddress; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.List; + +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; + +/** + * A {@link HttpsConfigurator} that can be used with the HTTP1 test server over HTTPS. + * This configurator {@link #configure(HttpsParameters) configures} the server's + * {@link HttpsParameters} with the necessary {@link SSLParameters} including a + * {@link SNIMatcher} + */ +public final class TestServerConfigurator extends HttpsConfigurator { + + private final InetAddress serverAddr; + + /** + * Creates a Https configuration, with the given {@link SSLContext}. + * + * @param serverAddr the address to which the server is bound + * @param context the {@code SSLContext} to use for this configurator + * @throws NullPointerException if no {@code SSLContext} supplied + */ + public TestServerConfigurator(final InetAddress serverAddr, final SSLContext context) { + super(context); + this.serverAddr = serverAddr; + } + + @Override + public void configure(final HttpsParameters params) { + final SSLParameters sslParams = getSSLContext().getDefaultSSLParameters(); + @SuppressWarnings("removal") final SecurityManager sm = System.getSecurityManager(); + final String hostname; + if (sm == null) { + hostname = serverAddr.getHostName(); + } else { + final PrivilegedAction action = () -> serverAddr.getHostName(); + hostname = AccessController.doPrivileged(action); + } + final List sniMatchers = List.of(new ServerNameMatcher(hostname)); + sslParams.setSNIMatchers(sniMatchers); + // configure the server with these custom SSLParameters + params.setSSLParameters(sslParams); + } +} diff --git a/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java b/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java index 969ab72be55..5065563c9ec 100644 --- a/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java +++ b/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java @@ -25,18 +25,18 @@ * @test * @bug 8245245 * @summary Test for Websocket URI encoding during HandShake - * @library /test/lib - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.net.http + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestServerConfigurator + * @modules java.net.http/jdk.internal.net.http.common * jdk.httpserver * @run testng/othervm -Djdk.internal.httpclient.debug=true HandshakeUrlEncodingTest */ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import com.sun.net.httpserver.HttpExchange; +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.URIBuilder; import org.testng.annotations.AfterTest; @@ -154,7 +154,7 @@ public void setup() throws Exception { httpTestServer.createContext("/", new UrlHandler()); httpsTestServer = HttpsServer.create(sa, 10); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsURI = URIBuilder.newBuilder() .scheme("wss") .host("localhost") diff --git a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java index a3ca4e2b439..6a02b774929 100644 --- a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java +++ b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java @@ -25,16 +25,15 @@ * @test * @bug 8240666 * @summary Basic test for WebSocketHandshakeException - * @library /test/lib - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.net.http + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestServerConfigurator + * @modules java.net.http/jdk.internal.net.http.common * jdk.httpserver * @run testng/othervm -Djdk.internal.httpclient.debug=true WSHandshakeExceptionTest */ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import com.sun.net.httpserver.HttpExchange; @@ -47,6 +46,8 @@ import java.net.http.HttpClient; import java.net.http.WebSocket; import java.net.http.WebSocketHandshakeException; + +import jdk.httpclient.test.lib.common.TestServerConfigurator; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -172,7 +173,7 @@ public void setup() throws Exception { httpTestServer.createContext("/nonutf8body", new BodyHandler()); httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.setHttpsConfigurator(new TestServerConfigurator(sa.getAddress(), sslContext)); httpsURI = "wss://localhost:" + httpsTestServer.getAddress().getPort() + "/"; httpsNonUtf8URI = "wss://localhost:" + httpsTestServer.getAddress().getPort() + "/nonutf8body"; httpsTestServer.createContext("/nonutf8body", new BodyHandler()); From 0d3a4e294af98e0cb909f4b001aed50d518ce6d3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:10:46 +0000 Subject: [PATCH 066/298] 8310818: Refactor more Locale tests to use JUnit Backport-of: 12e943091071b02b5756b57527a5f86a3d881cb8 --- test/jdk/java/util/Locale/Bug4175998Test.java | 291 ----------------- test/jdk/java/util/Locale/Bug8025703.java | 71 ----- test/jdk/java/util/Locale/Bug8032842.java | 99 ------ ...8008577.java => ExpectedAdapterTypes.java} | 29 +- .../Locale/{Bug8071929.java => ISO3166.java} | 27 +- test/jdk/java/util/Locale/ISO639.java | 297 ++++++++++++++++++ ...01562.java => JDK7LocaleServiceDiffs.java} | 56 ++-- .../{Bug8026766.java => LRToString.java} | 39 ++- .../Locale/LanguageSubtagRegistryTest.java | 18 +- .../jdk/java/util/Locale/PreserveTagCase.java | 114 +++++++ 10 files changed, 518 insertions(+), 523 deletions(-) delete mode 100644 test/jdk/java/util/Locale/Bug4175998Test.java delete mode 100644 test/jdk/java/util/Locale/Bug8025703.java delete mode 100644 test/jdk/java/util/Locale/Bug8032842.java rename test/jdk/java/util/Locale/{Bug8008577.java => ExpectedAdapterTypes.java} (59%) rename test/jdk/java/util/Locale/{Bug8071929.java => ISO3166.java} (93%) create mode 100644 test/jdk/java/util/Locale/ISO639.java rename test/jdk/java/util/Locale/{Bug8001562.java => JDK7LocaleServiceDiffs.java} (71%) rename test/jdk/java/util/Locale/{Bug8026766.java => LRToString.java} (50%) create mode 100644 test/jdk/java/util/Locale/PreserveTagCase.java diff --git a/test/jdk/java/util/Locale/Bug4175998Test.java b/test/jdk/java/util/Locale/Bug4175998Test.java deleted file mode 100644 index e62d8396de9..00000000000 --- a/test/jdk/java/util/Locale/Bug4175998Test.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary test ISO639-2 language codes - * @library /java/text/testlib - * @compile -encoding ascii Bug4175998Test.java - * @run main Bug4175998Test - * @bug 4175998 8303917 - */ - -/* - * - * - * (C) Copyright IBM Corp. 1998 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.util.*; - -/** - * Bug4175998Test verifies that the following bug has been fixed: - * Bug 4175998 - The java.util.Locale.getISO3Language() returns wrong result for a locale with - * language code 'ta'(Tamil). - */ -public class Bug4175998Test extends IntlTest { - public static void main(String[] args) throws Exception { - new Bug4175998Test().run(args); - //generateTables(); //uncomment this to regenerate data tables - } - - public void testIt() throws Exception { - boolean bad = false; - for (final String[] localeCodes : CODES) { - final Locale l = Locale.of(localeCodes[0]); - final String iso3 = l.getISO3Language(); - if (!iso3.equals(localeCodes[1])) { - logln("Locale(" + l + ") returned bad ISO3 language code." - + " Got '" + iso3 + "' instead of '" + localeCodes[1] + "'"); - bad = true; - } - } - if (bad) { - errln("Bad ISO3 language codes detected."); - } - } - - private static final String[][] CODES = { - {"aa","aar","aar"}, - {"ab","abk","abk"}, - {"af","afr","afr"}, - {"ak","aka","aka"}, - {"sq","sqi","alb"}, - {"am","amh","amh"}, - {"ar","ara","ara"}, - {"an","arg","arg"}, - {"hy","hye","arm"}, - {"as","asm","asm"}, - {"av","ava","ava"}, - {"ae","ave","ave"}, - {"ay","aym","aym"}, - {"az","aze","aze"}, - {"ba","bak","bak"}, - {"bm","bam","bam"}, - {"eu","eus","baq"}, - {"be","bel","bel"}, - {"bn","ben","ben"}, - {"bh","bih","bih"}, - {"bi","bis","bis"}, - {"bs","bos","bos"}, - {"br","bre","bre"}, - {"bg","bul","bul"}, - {"my","mya","bur"}, - {"ca","cat","cat"}, - {"ch","cha","cha"}, - {"ce","che","che"}, - {"zh","zho","chi"}, - {"cu","chu","chu"}, - {"cv","chv","chv"}, - {"kw","cor","cor"}, - {"co","cos","cos"}, - {"cr","cre","cre"}, - {"cs","ces","cze"}, - {"da","dan","dan"}, - {"dv","div","div"}, - {"nl","nld","dut"}, - {"dz","dzo","dzo"}, - {"en","eng","eng"}, - {"eo","epo","epo"}, - {"et","est","est"}, - {"ee","ewe","ewe"}, - {"fo","fao","fao"}, - {"fj","fij","fij"}, - {"fi","fin","fin"}, - {"fr","fra","fre"}, - {"fy","fry","fry"}, - {"ff","ful","ful"}, - {"ka","kat","geo"}, - {"de","deu","ger"}, - {"gd","gla","gla"}, - {"ga","gle","gle"}, - {"gl","glg","glg"}, - {"gv","glv","glv"}, - {"el","ell","gre"}, - {"gn","grn","grn"}, - {"gu","guj","guj"}, - {"ht","hat","hat"}, - {"ha","hau","hau"}, - {"he","heb","heb"}, - {"hz","her","her"}, - {"hi","hin","hin"}, - {"ho","hmo","hmo"}, - {"hr","hrv","hrv"}, - {"hu","hun","hun"}, - {"ig","ibo","ibo"}, - {"is","isl","ice"}, - {"io","ido","ido"}, - {"ii","iii","iii"}, - {"iu","iku","iku"}, - {"ie","ile","ile"}, - {"ia","ina","ina"}, - {"id","ind","ind"}, - {"ik","ipk","ipk"}, - {"it","ita","ita"}, - {"jv","jav","jav"}, - {"ja","jpn","jpn"}, - {"kl","kal","kal"}, - {"kn","kan","kan"}, - {"ks","kas","kas"}, - {"kr","kau","kau"}, - {"kk","kaz","kaz"}, - {"km","khm","khm"}, - {"ki","kik","kik"}, - {"rw","kin","kin"}, - {"ky","kir","kir"}, - {"kv","kom","kom"}, - {"kg","kon","kon"}, - {"ko","kor","kor"}, - {"kj","kua","kua"}, - {"ku","kur","kur"}, - {"lo","lao","lao"}, - {"la","lat","lat"}, - {"lv","lav","lav"}, - {"li","lim","lim"}, - {"ln","lin","lin"}, - {"lt","lit","lit"}, - {"lb","ltz","ltz"}, - {"lu","lub","lub"}, - {"lg","lug","lug"}, - {"mk","mkd","mac"}, - {"mh","mah","mah"}, - {"ml","mal","mal"}, - {"mi","mri","mao"}, - {"mr","mar","mar"}, - {"ms","msa","may"}, - {"mg","mlg","mlg"}, - {"mt","mlt","mlt"}, - {"mn","mon","mon"}, - {"na","nau","nau"}, - {"nv","nav","nav"}, - {"nr","nbl","nbl"}, - {"nd","nde","nde"}, - {"ng","ndo","ndo"}, - {"ne","nep","nep"}, - {"nn","nno","nno"}, - {"nb","nob","nob"}, - {"no","nor","nor"}, - {"ny","nya","nya"}, - {"oc","oci","oci"}, - {"oj","oji","oji"}, - {"or","ori","ori"}, - {"om","orm","orm"}, - {"os","oss","oss"}, - {"pa","pan","pan"}, - {"fa","fas","per"}, - {"pi","pli","pli"}, - {"pl","pol","pol"}, - {"pt","por","por"}, - {"ps","pus","pus"}, - {"qu","que","que"}, - {"rm","roh","roh"}, - {"ro","ron","rum"}, - {"rn","run","run"}, - {"ru","rus","rus"}, - {"sg","sag","sag"}, - {"sa","san","san"}, - {"si","sin","sin"}, - {"sk","slk","slo"}, - {"sl","slv","slv"}, - {"se","sme","sme"}, - {"sm","smo","smo"}, - {"sn","sna","sna"}, - {"sd","snd","snd"}, - {"so","som","som"}, - {"st","sot","sot"}, - {"es","spa","spa"}, - {"sc","srd","srd"}, - {"sr","srp","srp"}, - {"ss","ssw","ssw"}, - {"su","sun","sun"}, - {"sw","swa","swa"}, - {"sv","swe","swe"}, - {"ty","tah","tah"}, - {"ta","tam","tam"}, - {"tt","tat","tat"}, - {"te","tel","tel"}, - {"tg","tgk","tgk"}, - {"tl","tgl","tgl"}, - {"th","tha","tha"}, - {"bo","bod","tib"}, - {"ti","tir","tir"}, - {"to","ton","ton"}, - {"tn","tsn","tsn"}, - {"ts","tso","tso"}, - {"tk","tuk","tuk"}, - {"tr","tur","tur"}, - {"tw","twi","twi"}, - {"ug","uig","uig"}, - {"uk","ukr","ukr"}, - {"ur","urd","urd"}, - {"uz","uzb","uzb"}, - {"ve","ven","ven"}, - {"vi","vie","vie"}, - {"vo","vol","vol"}, - {"cy","cym","wel"}, - {"wa","wln","wln"}, - {"wo","wol","wol"}, - {"xh","xho","xho"}, - {"yi","yid","yid"}, - {"yo","yor","yor"}, - {"za","zha","zha"}, - {"zu","zul","zul"}, - }; - - // The following code was used to generate the table above from the two ISO standards. - private static final String ISO639 = "ISO-639-2_utf-8.txt"; - private static void generateTables() { - try { - BufferedReader ISO639File = new BufferedReader(new FileReader(ISO639)); - for (String line = ISO639File.readLine(); line != null; line = ISO639File.readLine()) { - String[] tokens= line.split("\\|"); - String iso639_1 = tokens[2]; - String iso639_2B = tokens[1]; - String iso639_2T = tokens[0]; - if (iso639_1.isEmpty()){ - continue; // Skip if not both a 639-1 and 639-2 code - } - if (iso639_2B.isEmpty()){ - iso639_2B = iso639_2T; // Default 639/B to 639/T if empty - } - System.out.printf(""" - {"%s","%s","%s"}, - """, iso639_1, iso639_2B, iso639_2T); - } - } catch (Exception e) { - System.out.println(e); - } - } -} - -// CODES generated from https://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt -// on March 9th, 2023. diff --git a/test/jdk/java/util/Locale/Bug8025703.java b/test/jdk/java/util/Locale/Bug8025703.java deleted file mode 100644 index 8a694aecb7b..00000000000 --- a/test/jdk/java/util/Locale/Bug8025703.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8025703 - * @summary Verify implementation for Locale matching. - * @run main Bug8025703 - */ - -import java.util.*; -import java.util.Locale.LanguageRange; - -public class Bug8025703 { - - public static void main(String[] args) { - boolean err = false; - - String[][] mappings = {{"ilw", "gal"}, - {"meg", "cir"}, - {"pcr", "adx"}, - {"xia", "acn"}, - {"yos", "zom"}}; - - for (int i = 0; i < mappings.length; i++) { - List got = LanguageRange.parse(mappings[i][0]); - ArrayList expected = new ArrayList<>(); - expected.add(new LanguageRange(mappings[i][0], 1.0)); - expected.add(new LanguageRange(mappings[i][1], 1.0)); - - if (!expected.equals(got)) { - err = true; - System.err.println("Incorrect language ranges. "); - for (LanguageRange lr : expected) { - System.err.println(" Expected: range=" - + lr.getRange() + ", weight=" + lr.getWeight()); - } - for (LanguageRange lr : got) { - System.err.println(" Got: range=" - + lr.getRange() + ", weight=" + lr.getWeight()); - } - } - } - - if (err) { - throw new RuntimeException("Failed."); - } - } - -} - diff --git a/test/jdk/java/util/Locale/Bug8032842.java b/test/jdk/java/util/Locale/Bug8032842.java deleted file mode 100644 index 92f36a6dcfd..00000000000 --- a/test/jdk/java/util/Locale/Bug8032842.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - * @test - * @bug 8032842 8175539 - * @summary Checks that the filterTags() and lookup() methods - * preserve the case of matching language tag(s). - * Before 8032842 fix these methods return the matching - * language tag(s) in lowercase. - * Also, checks the filterTags() to return only unique - * (ignoring case considerations) matching tags. - * - */ - -import java.util.List; -import java.util.Locale; -import java.util.Locale.FilteringMode; -import java.util.Locale.LanguageRange; - -public class Bug8032842 { - - public static void main(String[] args) { - - // test filterBasic() for preserving the case of matching tags for - // the language range '*', with no duplicates in the matching tags - testFilter("*", List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", - "JA-JP", "en-GB"), - List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), - FilteringMode.AUTOSELECT_FILTERING); - - // test filterBasic() for preserving the case of matching tags for - // basic ranges other than *, with no duplicates in the matching tags - testFilter("mtm-RU, en-GB", List.of("En-Gb", "mTm-RU", "en-US", - "en-latn", "en-GB"), - List.of("mTm-RU", "En-Gb"), FilteringMode.AUTOSELECT_FILTERING); - - // test filterExtended() for preserving the case of matching tags for - // the language range '*', with no duplicates in the matching tags - testFilter("*", List.of("de-CH", "hi-in", "En-GB", "hi-IN", - "ja-Latn-JP", "JA-JP"), - List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), - FilteringMode.EXTENDED_FILTERING); - - // test filterExtended() for preserving the case of matching tags for - // extended ranges other than *, with no duplicates in the matching tags - testFilter("*-ch;q=0.5, *-Latn;q=0.4", List.of("fr-CH", "de-Ch", - "en-latn", "en-US", "en-Latn"), - List.of("fr-CH", "de-Ch", "en-latn"), - FilteringMode.EXTENDED_FILTERING); - - // test lookupTag() for preserving the case of matching tag - testLookup("*-ch;q=0.5", List.of("en", "fR-cH"), "fR-cH"); - - } - - public static void testFilter(String ranges, List tags, - List expected, FilteringMode mode) { - List priorityList = LanguageRange.parse(ranges); - List actual = Locale.filterTags(priorityList, tags, mode); - if (!actual.equals(expected)) { - throw new RuntimeException("[filterTags() failed for the language" - + " range: " + ranges + ", Expected: " + expected - + ", Found: " + actual + "]"); - } - } - - public static void testLookup(String ranges, List tags, - String expected) { - List priorityList = LanguageRange.parse(ranges); - String actual = Locale.lookupTag(priorityList, tags); - if (!actual.equals(expected)) { - throw new RuntimeException("[lookupTag() failed for the language" - + " range: " + ranges + ", Expected: " + expected - + ", Found: " + actual + "]"); - } - } - -} - diff --git a/test/jdk/java/util/Locale/Bug8008577.java b/test/jdk/java/util/Locale/ExpectedAdapterTypes.java similarity index 59% rename from test/jdk/java/util/Locale/Bug8008577.java rename to test/jdk/java/util/Locale/ExpectedAdapterTypes.java index ee267ecfa06..60c24b01fb5 100644 --- a/test/jdk/java/util/Locale/Bug8008577.java +++ b/test/jdk/java/util/Locale/ExpectedAdapterTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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,27 +25,36 @@ * @test * @bug 8008577 8138613 * @summary Check whether CLDR locale provider adapter is enabled by default - * @compile -XDignore.symbol.file Bug8008577.java + * @compile -XDignore.symbol.file ExpectedAdapterTypes.java * @modules java.base/sun.util.locale.provider - * @run main Bug8008577 + * @run junit ExpectedAdapterTypes */ import java.util.Arrays; import java.util.List; import sun.util.locale.provider.LocaleProviderAdapter; -public class Bug8008577 { +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ExpectedAdapterTypes { static final LocaleProviderAdapter.Type[] expected = { LocaleProviderAdapter.Type.CLDR, LocaleProviderAdapter.Type.JRE, }; - public static void main(String[] args) { - List types = LocaleProviderAdapter.getAdapterPreference(); - List expectedList = Arrays.asList(expected); - if (!types.equals(expectedList)) { - throw new RuntimeException("Default locale provider adapter list is incorrect"); - } + /** + * This test ensures LocaleProviderAdapter.getAdapterPreference() returns + * the correct preferred adapter types. This test should fail whenever a change is made + * to the implementation and the expected list is not updated accordingly. + */ + @Test + public void correctAdapterListTest() { + List actualTypes = LocaleProviderAdapter.getAdapterPreference(); + List expectedTypes = Arrays.asList(expected); + assertEquals(actualTypes, expectedTypes, String.format("getAdapterPreference() " + + "returns: %s, but the expected adapter list returns: %s", actualTypes, expectedTypes)); } } diff --git a/test/jdk/java/util/Locale/Bug8071929.java b/test/jdk/java/util/Locale/ISO3166.java similarity index 93% rename from test/jdk/java/util/Locale/Bug8071929.java rename to test/jdk/java/util/Locale/ISO3166.java index 19a316ac217..7472ea1a4a4 100644 --- a/test/jdk/java/util/Locale/Bug8071929.java +++ b/test/jdk/java/util/Locale/ISO3166.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -27,7 +27,9 @@ * @summary Test obsolete ISO3166-1 alpha-2 country codes should not be retrieved. * ISO3166-1 alpha-2, ISO3166-1 alpha-3, ISO3166-3 country codes * from overloaded getISOCountries(Iso3166 type) are retrieved correctly. + * @run junit ISO3166 */ + import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -35,7 +37,9 @@ import java.util.Set; import java.util.stream.Collectors; -public class Bug8071929 { +import org.junit.jupiter.api.Test; + +public class ISO3166 { private static final List ISO3166_1_ALPHA2_OBSOLETE_CODES = List.of("AN", "BU", "CS", "NT", "SF", "TP", "YU", "ZR"); @@ -78,7 +82,8 @@ public class Bug8071929 { * This method checks that obsolete ISO3166-1 alpha-2 country codes are not * retrieved in output of getISOCountries() method. */ - private static void checkISO3166_1_Alpha2ObsoleteCodes() { + @Test + public void checkISO3166_1_Alpha2ObsoleteCodes() { Set unexpectedCodes = ISO3166_1_ALPHA2_OBSOLETE_CODES.stream(). filter(Set.of(Locale.getISOCountries())::contains).collect(Collectors.toSet()); if (!unexpectedCodes.isEmpty()) { @@ -91,7 +96,8 @@ private static void checkISO3166_1_Alpha2ObsoleteCodes() { * This method checks that ISO3166-3 country codes which are PART3 of * IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_3Codes() { + @Test + public void checkISO3166_3Codes() { Set iso3166_3Codes = Locale.getISOCountries(IsoCountryCode.PART3); if (!iso3166_3Codes.equals(ISO3166_3EXPECTED)) { reportDifference(iso3166_3Codes, ISO3166_3EXPECTED); @@ -102,7 +108,8 @@ private static void checkISO3166_3Codes() { * This method checks that ISO3166-1 alpha-3 country codes which are * PART1_ALPHA3 of IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_1_Alpha3Codes() { + @Test + public void checkISO3166_1_Alpha3Codes() { Set iso3166_1_Alpha3Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA3); if (!iso3166_1_Alpha3Codes.equals(ISO3166_1_ALPHA3_EXPECTED)) { reportDifference(iso3166_1_Alpha3Codes, ISO3166_1_ALPHA3_EXPECTED); @@ -113,7 +120,8 @@ private static void checkISO3166_1_Alpha3Codes() { * This method checks that ISO3166-1 alpha-2 country codes, which are * PART1_ALPHA2 of IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_1_Alpha2Codes() { + @Test + public void checkISO3166_1_Alpha2Codes() { Set iso3166_1_Alpha2Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA2); Set ISO3166_1_ALPHA2_EXPECTED = Set.of(Locale.getISOCountries()); if (!iso3166_1_Alpha2Codes.equals(ISO3166_1_ALPHA2_EXPECTED)) { @@ -139,11 +147,4 @@ private static void reportDifference(Set retrievedCountrySet, Set expectedISO639Codes() { + return Stream.of( + Arguments.of("aa","aar","aar"), + Arguments.of("ab","abk","abk"), + Arguments.of("af","afr","afr"), + Arguments.of("ak","aka","aka"), + Arguments.of("sq","sqi","alb"), + Arguments.of("am","amh","amh"), + Arguments.of("ar","ara","ara"), + Arguments.of("an","arg","arg"), + Arguments.of("hy","hye","arm"), + Arguments.of("as","asm","asm"), + Arguments.of("av","ava","ava"), + Arguments.of("ae","ave","ave"), + Arguments.of("ay","aym","aym"), + Arguments.of("az","aze","aze"), + Arguments.of("ba","bak","bak"), + Arguments.of("bm","bam","bam"), + Arguments.of("eu","eus","baq"), + Arguments.of("be","bel","bel"), + Arguments.of("bn","ben","ben"), + Arguments.of("bh","bih","bih"), + Arguments.of("bi","bis","bis"), + Arguments.of("bs","bos","bos"), + Arguments.of("br","bre","bre"), + Arguments.of("bg","bul","bul"), + Arguments.of("my","mya","bur"), + Arguments.of("ca","cat","cat"), + Arguments.of("ch","cha","cha"), + Arguments.of("ce","che","che"), + Arguments.of("zh","zho","chi"), + Arguments.of("cu","chu","chu"), + Arguments.of("cv","chv","chv"), + Arguments.of("kw","cor","cor"), + Arguments.of("co","cos","cos"), + Arguments.of("cr","cre","cre"), + Arguments.of("cs","ces","cze"), + Arguments.of("da","dan","dan"), + Arguments.of("dv","div","div"), + Arguments.of("nl","nld","dut"), + Arguments.of("dz","dzo","dzo"), + Arguments.of("en","eng","eng"), + Arguments.of("eo","epo","epo"), + Arguments.of("et","est","est"), + Arguments.of("ee","ewe","ewe"), + Arguments.of("fo","fao","fao"), + Arguments.of("fj","fij","fij"), + Arguments.of("fi","fin","fin"), + Arguments.of("fr","fra","fre"), + Arguments.of("fy","fry","fry"), + Arguments.of("ff","ful","ful"), + Arguments.of("ka","kat","geo"), + Arguments.of("de","deu","ger"), + Arguments.of("gd","gla","gla"), + Arguments.of("ga","gle","gle"), + Arguments.of("gl","glg","glg"), + Arguments.of("gv","glv","glv"), + Arguments.of("el","ell","gre"), + Arguments.of("gn","grn","grn"), + Arguments.of("gu","guj","guj"), + Arguments.of("ht","hat","hat"), + Arguments.of("ha","hau","hau"), + Arguments.of("he","heb","heb"), + Arguments.of("hz","her","her"), + Arguments.of("hi","hin","hin"), + Arguments.of("ho","hmo","hmo"), + Arguments.of("hr","hrv","hrv"), + Arguments.of("hu","hun","hun"), + Arguments.of("ig","ibo","ibo"), + Arguments.of("is","isl","ice"), + Arguments.of("io","ido","ido"), + Arguments.of("ii","iii","iii"), + Arguments.of("iu","iku","iku"), + Arguments.of("ie","ile","ile"), + Arguments.of("ia","ina","ina"), + Arguments.of("id","ind","ind"), + Arguments.of("ik","ipk","ipk"), + Arguments.of("it","ita","ita"), + Arguments.of("jv","jav","jav"), + Arguments.of("ja","jpn","jpn"), + Arguments.of("kl","kal","kal"), + Arguments.of("kn","kan","kan"), + Arguments.of("ks","kas","kas"), + Arguments.of("kr","kau","kau"), + Arguments.of("kk","kaz","kaz"), + Arguments.of("km","khm","khm"), + Arguments.of("ki","kik","kik"), + Arguments.of("rw","kin","kin"), + Arguments.of("ky","kir","kir"), + Arguments.of("kv","kom","kom"), + Arguments.of("kg","kon","kon"), + Arguments.of("ko","kor","kor"), + Arguments.of("kj","kua","kua"), + Arguments.of("ku","kur","kur"), + Arguments.of("lo","lao","lao"), + Arguments.of("la","lat","lat"), + Arguments.of("lv","lav","lav"), + Arguments.of("li","lim","lim"), + Arguments.of("ln","lin","lin"), + Arguments.of("lt","lit","lit"), + Arguments.of("lb","ltz","ltz"), + Arguments.of("lu","lub","lub"), + Arguments.of("lg","lug","lug"), + Arguments.of("mk","mkd","mac"), + Arguments.of("mh","mah","mah"), + Arguments.of("ml","mal","mal"), + Arguments.of("mi","mri","mao"), + Arguments.of("mr","mar","mar"), + Arguments.of("ms","msa","may"), + Arguments.of("mg","mlg","mlg"), + Arguments.of("mt","mlt","mlt"), + Arguments.of("mn","mon","mon"), + Arguments.of("na","nau","nau"), + Arguments.of("nv","nav","nav"), + Arguments.of("nr","nbl","nbl"), + Arguments.of("nd","nde","nde"), + Arguments.of("ng","ndo","ndo"), + Arguments.of("ne","nep","nep"), + Arguments.of("nn","nno","nno"), + Arguments.of("nb","nob","nob"), + Arguments.of("no","nor","nor"), + Arguments.of("ny","nya","nya"), + Arguments.of("oc","oci","oci"), + Arguments.of("oj","oji","oji"), + Arguments.of("or","ori","ori"), + Arguments.of("om","orm","orm"), + Arguments.of("os","oss","oss"), + Arguments.of("pa","pan","pan"), + Arguments.of("fa","fas","per"), + Arguments.of("pi","pli","pli"), + Arguments.of("pl","pol","pol"), + Arguments.of("pt","por","por"), + Arguments.of("ps","pus","pus"), + Arguments.of("qu","que","que"), + Arguments.of("rm","roh","roh"), + Arguments.of("ro","ron","rum"), + Arguments.of("rn","run","run"), + Arguments.of("ru","rus","rus"), + Arguments.of("sg","sag","sag"), + Arguments.of("sa","san","san"), + Arguments.of("si","sin","sin"), + Arguments.of("sk","slk","slo"), + Arguments.of("sl","slv","slv"), + Arguments.of("se","sme","sme"), + Arguments.of("sm","smo","smo"), + Arguments.of("sn","sna","sna"), + Arguments.of("sd","snd","snd"), + Arguments.of("so","som","som"), + Arguments.of("st","sot","sot"), + Arguments.of("es","spa","spa"), + Arguments.of("sc","srd","srd"), + Arguments.of("sr","srp","srp"), + Arguments.of("ss","ssw","ssw"), + Arguments.of("su","sun","sun"), + Arguments.of("sw","swa","swa"), + Arguments.of("sv","swe","swe"), + Arguments.of("ty","tah","tah"), + Arguments.of("ta","tam","tam"), + Arguments.of("tt","tat","tat"), + Arguments.of("te","tel","tel"), + Arguments.of("tg","tgk","tgk"), + Arguments.of("tl","tgl","tgl"), + Arguments.of("th","tha","tha"), + Arguments.of("bo","bod","tib"), + Arguments.of("ti","tir","tir"), + Arguments.of("to","ton","ton"), + Arguments.of("tn","tsn","tsn"), + Arguments.of("ts","tso","tso"), + Arguments.of("tk","tuk","tuk"), + Arguments.of("tr","tur","tur"), + Arguments.of("tw","twi","twi"), + Arguments.of("ug","uig","uig"), + Arguments.of("uk","ukr","ukr"), + Arguments.of("ur","urd","urd"), + Arguments.of("uz","uzb","uzb"), + Arguments.of("ve","ven","ven"), + Arguments.of("vi","vie","vie"), + Arguments.of("vo","vol","vol"), + Arguments.of("cy","cym","wel"), + Arguments.of("wa","wln","wln"), + Arguments.of("wo","wol","wol"), + Arguments.of("xh","xho","xho"), + Arguments.of("yi","yid","yid"), + Arguments.of("yo","yor","yor"), + Arguments.of("za","zha","zha"), + Arguments.of("zu","zul","zul") + ); + } + + @Test + @Disabled("For updating expected ISO data, NOT an actual test") + public void getISOData() { + // Remove @Disabled to generate new ISO Data + generateTables(); + } + + private static final String ISO639 = "ISO-639-2_utf-8.txt"; + private static void generateTables() { + try { + BufferedReader ISO639File = new BufferedReader(new FileReader(ISO639)); + for (String line = ISO639File.readLine(); line != null; line = ISO639File.readLine()) { + String[] tokens= line.split("\\|"); + String iso639_1 = tokens[2]; + String iso639_2B = tokens[1]; + String iso639_2T = tokens[0]; + if (iso639_1.isEmpty()){ + continue; // Skip if not both a 639-1 and 639-2 code + } + if (iso639_2B.isEmpty()){ + iso639_2B = iso639_2T; // Default 639/B to 639/T if empty + } + System.out.printf(""" + Arguments.of("%s","%s","%s"), + """, iso639_1, iso639_2B, iso639_2T); + } + } catch (Exception e) { + System.out.println(e); + } + } +} diff --git a/test/jdk/java/util/Locale/Bug8001562.java b/test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java similarity index 71% rename from test/jdk/java/util/Locale/Bug8001562.java rename to test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java index be53600a84d..a9acb23d10f 100644 --- a/test/jdk/java/util/Locale/Bug8001562.java +++ b/test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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,9 +25,9 @@ * @test * @bug 8001562 * @summary Verify that getAvailableLocales() in locale sensitive services - * classes return compatible set of locales as in JDK7. + * classes return compatible set of locales as in JDK7. * @modules jdk.localedata - * @run main Bug8001562 + * @run junit JDK7LocaleServiceDiffs */ import java.text.BreakIterator; @@ -40,8 +40,13 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import java.util.stream.Stream; -public class Bug8001562 { +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class JDK7LocaleServiceDiffs { static final List jdk7availTags = List.of( "ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", @@ -72,27 +77,16 @@ public class Bug8001562 { .collect(Collectors.toList()); } - public static void main(String[] args) { - List avail = Arrays.asList(BreakIterator.getAvailableLocales()); - diffLocale(BreakIterator.class, avail); - - avail = Arrays.asList(Collator.getAvailableLocales()); - diffLocale(Collator.class, avail); - - avail = Arrays.asList(DateFormat.getAvailableLocales()); - diffLocale(DateFormat.class, avail); - - avail = Arrays.asList(DateFormatSymbols.getAvailableLocales()); - diffLocale(DateFormatSymbols.class, avail); - - avail = Arrays.asList(DecimalFormatSymbols.getAvailableLocales()); - diffLocale(DecimalFormatSymbols.class, avail); - - avail = Arrays.asList(NumberFormat.getAvailableLocales()); - diffLocale(NumberFormat.class, avail); - - avail = Arrays.asList(Locale.getAvailableLocales()); - diffLocale(Locale.class, avail); + /** + * This test compares the locales returned by getAvailableLocales() from a + * locale sensitive service to the available JDK7 locales. If the locales from + * a locale sensitive service are found to not contain a JDK7 available tag, + * the test will fail. + */ + @ParameterizedTest + @MethodSource("serviceProvider") + public void compatibleLocalesTest(Class c, List locs) { + diffLocale(c, locs); } static void diffLocale(Class c, List locs) { @@ -119,4 +113,16 @@ static void diffLocale(Class c, List locs) { throw new RuntimeException("Above locale(s) were not included in the target available locales"); } } + + private static Stream serviceProvider() { + return Stream.of( + Arguments.of(BreakIterator.class, Arrays.asList(BreakIterator.getAvailableLocales())), + Arguments.of(Collator.class, Arrays.asList(Collator.getAvailableLocales())), + Arguments.of(DateFormat.class, Arrays.asList(DateFormat.getAvailableLocales())), + Arguments.of(DateFormatSymbols.class, Arrays.asList(DateFormatSymbols.getAvailableLocales())), + Arguments.of(DecimalFormatSymbols.class, Arrays.asList(DecimalFormatSymbols.getAvailableLocales())), + Arguments.of(NumberFormat.class, Arrays.asList(NumberFormat.getAvailableLocales())), + Arguments.of(Locale.class, Arrays.asList(Locale.getAvailableLocales())) + ); + } } diff --git a/test/jdk/java/util/Locale/Bug8026766.java b/test/jdk/java/util/Locale/LRToString.java similarity index 50% rename from test/jdk/java/util/Locale/Bug8026766.java rename to test/jdk/java/util/Locale/LRToString.java index 630737fdf99..229507b71b3 100644 --- a/test/jdk/java/util/Locale/Bug8026766.java +++ b/test/jdk/java/util/Locale/LRToString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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,21 +25,40 @@ * @test * @bug 8026766 * @summary Confirm that LanguageRange.toString() returns an expected result. - * @run main Bug8026766 + * @run junit LRToString */ import java.util.Locale.LanguageRange; +import java.util.stream.Stream; -public class Bug8026766 { +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; - public static void main(String[] args) { - LanguageRange lr1 = new LanguageRange("ja", 1.0); - LanguageRange lr2 = new LanguageRange("fr", 0.0); +import static org.junit.jupiter.api.Assertions.assertEquals; - if (!lr1.toString().equals("ja") || - !lr2.toString().equals("fr;q=0.0")) { - throw new RuntimeException("LanguageRange.toString() returned an unexpected result."); - } +public class LRToString { + + /** + * This test ensures that the output of LanguageRange.toString() + * returns an expected result, that is, the weight is hidden if it is + * equal to 1.0. + */ + @ParameterizedTest + @MethodSource("ranges") + public void toStringTest(String range, double weight) { + LanguageRange lr = new LanguageRange(range, weight); + String expected = weight == 1.0 + ? range + : range+";q="+weight; + assertEquals(lr.toString(), expected); } + private static Stream ranges() { + return Stream.of( + Arguments.of("ja", 1.0), + Arguments.of("de", 0.5), + Arguments.of("fr", 0.0) + ); + } } diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index 009be2ad847..dc792f9f72a 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 + * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 * @summary Checks the IANA language subtag registry data update * (LSR Revision: 2023-05-11) with Locale and Locale.LanguageRange @@ -45,9 +45,9 @@ public class LanguageSubtagRegistryTest { private static final String ACCEPT_LANGUAGE = "Accept-Language: aam, adp, aeb, ajs, aog, apc, ajp, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, ema," - + " en-gb-oed, gti, iba, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, mtm," - + " ngv, nns, ola, oyb, pat, phr, plu, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," - + " umi, uss, uth, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; + + " en-gb-oed, gti, iba, ilw, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, meg, mtm," + + " ngv, nns, ola, oyb, pat, pcr, phr, plu, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," + + " umi, uss, uth, xia, yos, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; private static final List EXPECTED_RANGE_LIST = List.of( new LanguageRange("aam", 1.0), new LanguageRange("aas", 1.0), @@ -102,6 +102,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("iba", 1.0), new LanguageRange("snb", 1.0), new LanguageRange("blg", 1.0), + new LanguageRange("ilw", 1.0), + new LanguageRange("gal", 1.0), new LanguageRange("jks", 1.0), new LanguageRange("sgn-jks", 1.0), new LanguageRange("kdz", 1.0), @@ -140,6 +142,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("lsw", 1.0), new LanguageRange("sgn-lsw", 1.0), new LanguageRange("lvi", 1.0), + new LanguageRange("meg", 1.0), + new LanguageRange("cir", 1.0), new LanguageRange("mtm", 1.0), new LanguageRange("ymt", 1.0), new LanguageRange("ngv", 1.0), @@ -154,6 +158,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("jeg", 1.0), new LanguageRange("pat", 1.0), new LanguageRange("kxr", 1.0), + new LanguageRange("pcr", 1.0), + new LanguageRange("adx", 1.0), new LanguageRange("phr", 1.0), new LanguageRange("pmu", 1.0), new LanguageRange("plu", 1.0), @@ -188,6 +194,10 @@ public class LanguageSubtagRegistryTest { new LanguageRange("szd", 1.0), new LanguageRange("uss", 1.0), new LanguageRange("uth", 1.0), + new LanguageRange("xia", 1.0), + new LanguageRange("acn", 1.0), + new LanguageRange("yos", 1.0), + new LanguageRange("zom", 1.0), new LanguageRange("ysm", 1.0), new LanguageRange("sgn-ysm", 1.0), new LanguageRange("zko", 1.0), diff --git a/test/jdk/java/util/Locale/PreserveTagCase.java b/test/jdk/java/util/Locale/PreserveTagCase.java new file mode 100644 index 00000000000..c5535e3a89f --- /dev/null +++ b/test/jdk/java/util/Locale/PreserveTagCase.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8032842 8175539 + * @summary Checks that the filterTags() and lookup() methods + * preserve the case of matching language tag(s). + * Before 8032842 fix these methods return the matching + * language tag(s) in lowercase. + * Also, checks the filterTags() to return only unique + * (ignoring case considerations) matching tags. + * @run junit PreserveTagCase + */ + +import java.util.List; +import java.util.Locale; +import java.util.Locale.FilteringMode; +import java.util.Locale.LanguageRange; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PreserveTagCase { + + /** + * This test ensures that Locale.filterTags() preserves the case of matching + * language tag(s). + */ + @ParameterizedTest + @MethodSource("filterProvider") + public static void testFilterTags(String ranges, List tags, + List expected, FilteringMode mode) { + List priorityList = LanguageRange.parse(ranges); + List actual = Locale.filterTags(priorityList, tags, mode); + assertEquals(actual, expected, String.format("[filterTags() failed for " + + "the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual)); + } + + /** + * This test ensures that Locale.lookupTag() preserves the case of matching + * language tag(s). + */ + @ParameterizedTest + @MethodSource("lookupProvider") + public static void testLookupTag(String ranges, List tags, + String expected) { + List priorityList = LanguageRange.parse(ranges); + String actual = Locale.lookupTag(priorityList, tags); + assertEquals(actual, expected, String.format("[lookupTags() failed for " + + "the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual)); + } + + private static Stream filterProvider() { + return Stream.of( + // test filterBasic() for preserving the case of matching tags for + // the language range '*', with no duplicates in the matching tags + Arguments.of("*", + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP", "en-GB"), + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), + FilteringMode.AUTOSELECT_FILTERING), + // test filterBasic() for preserving the case of matching tags for + // basic ranges other than *, with no duplicates in the matching tags + Arguments.of("mtm-RU, en-GB", + List.of("En-Gb", "mTm-RU", "en-US", "en-latn", "en-GB"), + List.of("mTm-RU", "En-Gb"), + FilteringMode.AUTOSELECT_FILTERING), + // test filterExtended() for preserving the case of matching tags for + // the language range '*', with no duplicates in the matching tags + Arguments.of("*", + List.of("de-CH", "hi-in", "En-GB", "hi-IN", "ja-Latn-JP", "JA-JP"), + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), + FilteringMode.EXTENDED_FILTERING), + // test filterExtended() for preserving the case of matching tags for + // extended ranges other than *, with no duplicates in the matching tags + Arguments.of("*-ch;q=0.5, *-Latn;q=0.4", + List.of("fr-CH", "de-Ch", "en-latn", "en-US", "en-Latn"), + List.of("fr-CH", "de-Ch", "en-latn"), + FilteringMode.EXTENDED_FILTERING) + ); + } + + private static Stream lookupProvider() { + return Stream.of( + // test lookupTag() for preserving the case of matching tag + Arguments.of("*-ch;q=0.5", List.of("en", "fR-cH"), "fR-cH"), + Arguments.of("*-Latn;q=0.4", List.of("en", "fR-LATn"), "fR-LATn") + ); + } +} From 539b04edc43a19c49c7f9f52296c14ec26988350 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:12:15 +0000 Subject: [PATCH 067/298] 8314832: Few runtime/os tests ignore vm flags Backport-of: fc3e8266929826f8e58bc76fe97423d76bc7be87 --- .../jtreg/runtime/os/THPsInThreadStackPreventionTest.java | 2 ++ test/hotspot/jtreg/runtime/os/TestHugePageDetection.java | 1 + test/hotspot/jtreg/runtime/os/TestTrimNative.java | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java index fd9fea9e5a5..519bcc94b01 100644 --- a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java +++ b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java @@ -27,6 +27,7 @@ * @bug 8303215 8312182 * @summary On THP=always systems, we prevent THPs from forming within thread stacks * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @requires vm.debug * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" @@ -40,6 +41,7 @@ * @bug 8303215 8312182 * @summary On THP=always systems, we prevent THPs from forming within thread stacks (negative test) * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @requires vm.debug * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java index ba318da0a0b..2e2d9092c74 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java @@ -26,6 +26,7 @@ * @test * @summary Test that the JVM detects the OS hugepage/THP settings correctly. * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/os/TestTrimNative.java b/test/hotspot/jtreg/runtime/os/TestTrimNative.java index 33df4f06d56..e8645a91479 100644 --- a/test/hotspot/jtreg/runtime/os/TestTrimNative.java +++ b/test/hotspot/jtreg/runtime/os/TestTrimNative.java @@ -26,6 +26,7 @@ /* * @test id=trimNative + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -36,6 +37,7 @@ /* * @test id=trimNativeStrict + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -47,6 +49,7 @@ /* * @test id=trimNativeHighInterval * @summary High interval trimming should not even kick in for short program runtimes + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -58,6 +61,7 @@ /* * @test id=trimNativeLowInterval * @summary Very low (sub-second) interval, nothing should explode + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -69,6 +73,7 @@ /* * @test id=trimNativeLowIntervalStrict * @summary Very low (sub-second) interval, nothing should explode (stricter test, manual mode) + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -80,6 +85,7 @@ /* * @test id=testOffByDefault * @summary Test that trimming is disabled by default + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -91,6 +97,7 @@ /* * @test id=testOffExplicit * @summary Test that trimming can be disabled explicitly + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -102,6 +109,7 @@ /* * @test id=testOffOnNonCompliantPlatforms * @summary Test that trimming is correctly reported as unavailable if unavailable + * @requires vm.flagless * @requires (os.family!="linux") | vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib From 390e647d4127f8c0f6ab0d271ec207318271c425 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:13:46 +0000 Subject: [PATCH 068/298] 8313612: Use JUnit in lib-test/jdk tests Backport-of: a35e96a3fae8722eea1d266beab22556c784241d --- .../jdk/test/lib/format/ArrayDiffTest.java | 74 +++--- .../test/lib/hexdump/ASN1FormatterTest.java | 52 ++-- .../jdk/test/lib/hexdump/HexPrinterTest.java | 251 ++++++++++-------- .../lib/hexdump/ObjectStreamPrinterTest.java | 87 +++--- .../jdk/test/lib/hexdump/StreamDumpTest.java | 65 ++--- 5 files changed, 273 insertions(+), 256 deletions(-) diff --git a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java index c52fcd78f93..c8ac5e7e8a0 100644 --- a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java +++ b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,22 +23,20 @@ package jdk.test.lib.format; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.*; /* * @test * @summary Check ArrayDiff formatting * @library /test/lib - * @run testng jdk.test.lib.format.ArrayDiffTest + * @run junit jdk.test.lib.format.ArrayDiffTest */ -public class ArrayDiffTest { +class ArrayDiffTest { @Test - public void testEqualArrays() { + void testEqualArrays() { char[] first = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; char[] second = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; @@ -46,7 +44,7 @@ public void testEqualArrays() { } @Test - public void testOutputFitsWidth() { + void testOutputFitsWidth() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -62,7 +60,7 @@ public void testOutputFitsWidth() { } @Test - public void testIntegers() { + void testIntegers() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -78,7 +76,7 @@ public void testIntegers() { } @Test - public void testLongs() { + void testLongs() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -94,7 +92,7 @@ public void testLongs() { } @Test - public void testFirstElementIsWrong() { + void testFirstElementIsWrong() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -110,7 +108,7 @@ public void testFirstElementIsWrong() { } @Test - public void testOneElementIsEmpty() { + void testOneElementIsEmpty() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -126,7 +124,7 @@ public void testOneElementIsEmpty() { } @Test - public void testOutputDoesntFitWidth() { + void testOutputDoesntFitWidth() { new AssertBuilder() .withParams(20, Integer.MAX_VALUE) .withArrays( @@ -142,7 +140,7 @@ public void testOutputDoesntFitWidth() { } @Test - public void testVariableElementWidthOutputDoesntFitWidth() { + void testVariableElementWidthOutputDoesntFitWidth() { new AssertBuilder() .withParams(20, Integer.MAX_VALUE) .withArrays( @@ -158,7 +156,7 @@ public void testVariableElementWidthOutputDoesntFitWidth() { } @Test - public void testContextBefore() { + void testContextBefore() { new AssertBuilder() .withParams(20, 2) .withArrays( @@ -174,7 +172,7 @@ public void testContextBefore() { } @Test - public void testBoundedBytesWithDifferentWidth() { + void testBoundedBytesWithDifferentWidth() { new AssertBuilder() .withParams(24, 2) .withArrays( @@ -190,7 +188,7 @@ public void testBoundedBytesWithDifferentWidth() { } @Test - public void testBoundedFirstElementIsWrong() { + void testBoundedFirstElementIsWrong() { new AssertBuilder() .withParams(25, 2) .withArrays( @@ -206,7 +204,7 @@ public void testBoundedFirstElementIsWrong() { } @Test - public void testBoundedOneArchiveIsEmpty() { + void testBoundedOneArchiveIsEmpty() { new AssertBuilder() .withParams(10, 2) .withArrays( @@ -222,7 +220,7 @@ public void testBoundedOneArchiveIsEmpty() { } @Test - public void testUnboundedOneArchiveIsEmpty() { + void testUnboundedOneArchiveIsEmpty() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -238,7 +236,7 @@ public void testUnboundedOneArchiveIsEmpty() { } @Test - public void testUnprintableCharFormatting() { + void testUnprintableCharFormatting() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -254,7 +252,7 @@ public void testUnprintableCharFormatting() { } @Test - public void testStringElements() { + void testStringElements() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -270,7 +268,7 @@ public void testStringElements() { } @Test - public void testToStringableObjects() { + void testToStringableObjects() { class StrObj { private final String value; public boolean equals(Object another) { return ((StrObj)another).value.equals(value); } @@ -294,7 +292,7 @@ class StrObj { } @Test - public void testNullElements() { + void testNullElements() { new AssertBuilder() .withDefaultParams() .withArrays( @@ -309,14 +307,14 @@ public void testNullElements() { .assertTwoWay(); } - @Test (expectedExceptions = NullPointerException.class) - public void testFirstArrayIsNull() { - var diff = ArrayDiff.of(null, new String[] {"a", "b"}); + @Test + void testFirstArrayIsNull() { + assertThrows(NullPointerException.class, () -> ArrayDiff.of(null, new String[] {"a", "b"})); } - @Test (expectedExceptions = NullPointerException.class) - public void testSecondArrayIsNull() { - var diff = ArrayDiff.of(null, new String[] {"a", "b"}); + @Test + void testSecondArrayIsNull() { + assertThrows(NullPointerException.class, () -> ArrayDiff.of(new String[] {"a", "b"}, null)); } class AssertBuilder { @@ -331,30 +329,30 @@ class AssertBuilder { private String secondFormattedArray; private String failureMark; - public AssertBuilder withDefaultParams() { + AssertBuilder withDefaultParams() { defaultParameters = true; return this; } - public AssertBuilder withParams(int width, int contextBefore) { + AssertBuilder withParams(int width, int contextBefore) { defaultParameters = false; this.width = width; this.contextBefore = contextBefore; return this; } - public AssertBuilder withArrays(Object first, Object second) { + AssertBuilder withArrays(Object first, Object second) { firstArray = first; secondArray = second; return this; } - public AssertBuilder thatResultIs(boolean result) { + AssertBuilder thatResultIs(boolean result) { expectedResult = result; return this; } - public AssertBuilder thatFormattedValuesAre( + AssertBuilder thatFormattedValuesAre( int idx, String first, String second, String mark) { expectedIndex = idx; firstFormattedArray = first; @@ -363,7 +361,7 @@ public AssertBuilder thatFormattedValuesAre( return this; } - public void assertTwoWay() { + void assertTwoWay() { ArrayDiff diff; // Direct @@ -382,7 +380,7 @@ public void assertTwoWay() { expectedIndex, firstFormattedArray, secondFormattedArray, failureMark); assertFalse(diff.areEqual()); - assertEquals(diff.format(), expected); + assertEquals(expected, diff.format()); } // Reversed @@ -401,7 +399,7 @@ public void assertTwoWay() { expectedIndex, secondFormattedArray, firstFormattedArray, failureMark); assertFalse(diff.areEqual()); - assertEquals(diff.format(), expected); + assertEquals(expected, diff.format()); } } diff --git a/test/lib-test/jdk/test/lib/hexdump/ASN1FormatterTest.java b/test/lib-test/jdk/test/lib/hexdump/ASN1FormatterTest.java index c7622d4b9b4..6bcd9dc2a9a 100644 --- a/test/lib-test/jdk/test/lib/hexdump/ASN1FormatterTest.java +++ b/test/lib-test/jdk/test/lib/hexdump/ASN1FormatterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,8 +23,7 @@ package jdk.test.lib.hexdump; -import org.testng.Assert; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; import java.io.DataInputStream; import java.io.EOFException; @@ -34,7 +33,7 @@ import java.nio.file.Path; import java.util.Base64; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; /* * @test @@ -42,14 +41,13 @@ * @modules java.base/sun.security.util * @library /test/lib * @compile ASN1FormatterTest.java - * @run testng jdk.test.lib.hexdump.ASN1FormatterTest + * @run junit jdk.test.lib.hexdump.ASN1FormatterTest */ -@Test -public class ASN1FormatterTest { +class ASN1FormatterTest { private static final String DIR = System.getProperty("test.src", "."); @Test - static void testPEM() throws IOException { + void testPEM() throws IOException { String certFile = "openssl.p12.pem"; Path certPath = Path.of(DIR, certFile); System.out.println("certPath: " + certPath); @@ -64,18 +62,18 @@ static void testPEM() throws IOException { String result = ASN1Formatter.formatter().annotate(is); System.out.println(result); - Assert.assertEquals(result.lines().count(), 76, "Lines"); - Assert.assertEquals(result.lines().filter(s -> s.contains("SEQUENCE")).count(),24, "Sequences"); - Assert.assertEquals(result.lines().filter(s -> s.contains("OBJECT ID")).count(), 17, "ObjectIDs"); - Assert.assertEquals(result.lines().filter(s -> s.contains("UTCTIME")).count(), 2, "UTCTIME"); - Assert.assertEquals(result.lines().filter(s -> s.contains("BIT STRING")).count(), 3, "BitStrings"); + assertEquals(76, result.lines().count(), "Lines"); + assertEquals(24, result.lines().filter(s -> s.contains("SEQUENCE")).count(),"Sequences"); + assertEquals(17, result.lines().filter(s -> s.contains("OBJECT ID")).count(), "ObjectIDs"); + assertEquals(2, result.lines().filter(s -> s.contains("UTCTIME")).count(), "UTCTIME"); + assertEquals(3, result.lines().filter(s -> s.contains("BIT STRING")).count(), "BitStrings"); } catch (EOFException eof) { // done } } @Test - static void dumpPEM() throws IOException { + void dumpPEM() throws IOException { String file = "openssl.p12.pem"; Path path = Path.of(DIR, file); System.out.println("path: " + path); @@ -92,34 +90,34 @@ static void dumpPEM() throws IOException { String result = p.toString(wis); System.out.println(result); - Assert.assertEquals(result.lines().count(), 126, "Lines"); - Assert.assertEquals(result.lines().filter(s -> s.contains("SEQUENCE")).count(), 24, "Sequences"); - Assert.assertEquals(result.lines().filter(s -> s.contains("OBJECT ID")).count(), 17, "ObjectIDs"); - Assert.assertEquals(result.lines().filter(s -> s.contains("UTCTIME")).count(), 2, "UTCTIME"); - Assert.assertEquals(result.lines().filter(s -> s.contains("BIT STRING")).count(), 3, "BitStrings"); + assertEquals(126, result.lines().count(), "Lines"); + assertEquals(24, result.lines().filter(s -> s.contains("SEQUENCE")).count(), "Sequences"); + assertEquals(17, result.lines().filter(s -> s.contains("OBJECT ID")).count(), "ObjectIDs"); + assertEquals(2, result.lines().filter(s -> s.contains("UTCTIME")).count(), "UTCTIME"); + assertEquals(3, result.lines().filter(s -> s.contains("BIT STRING")).count(), "BitStrings"); } catch (EOFException eof) { // done } } @Test - static void testIndefinite() { + void testIndefinite() { byte[] bytes = {0x24, (byte) 0x80, 4, 2, 'a', 'b', 4, 2, 'c', 'd', 0, 0}; HexPrinter p = HexPrinter.simple() .formatter(ASN1Formatter.formatter(), "; ", 100); String result = p.toString(bytes); System.out.println(result); - Assert.assertEquals(result.lines().filter(s -> s.contains("OCTET STRING [INDEFINITE]")).count(), - 1, "Indefinite length"); - Assert.assertEquals(result.lines().filter(s -> s.contains("; OCTET STRING [2]")).count(), - 2, "Octet Sequences"); - Assert.assertEquals(result.lines().filter(s -> s.contains("; END-OF-CONTENT")).count(), - 1, "end of content"); + assertEquals(1, result.lines().filter(s -> s.contains("OCTET STRING [INDEFINITE]")).count(), + "Indefinite length"); + assertEquals(2, result.lines().filter(s -> s.contains("; OCTET STRING [2]")).count(), + "Octet Sequences"); + assertEquals(1, result.lines().filter(s -> s.contains("; END-OF-CONTENT")).count(), + "end of content"); } @Test - static void testMain() { + void testMain() { String file = "openssl.p12.pem"; Path path = Path.of(DIR, file); String[] args = { path.toString() }; diff --git a/test/lib-test/jdk/test/lib/hexdump/HexPrinterTest.java b/test/lib-test/jdk/test/lib/hexdump/HexPrinterTest.java index 2351a85beda..c36f55c58fc 100644 --- a/test/lib-test/jdk/test/lib/hexdump/HexPrinterTest.java +++ b/test/lib-test/jdk/test/lib/hexdump/HexPrinterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,9 +25,10 @@ import jdk.test.lib.hexdump.HexPrinter; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.Arguments; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -36,6 +37,9 @@ import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; /* @@ -43,12 +47,12 @@ * @summary Check HexPrinter formatting * @library /test/lib * @compile HexPrinterTest.java - * @run testng jdk.test.lib.hexdump.HexPrinterTest + * @run junit jdk.test.lib.hexdump.HexPrinterTest */ -public class HexPrinterTest { +class HexPrinterTest { @Test - static void testMinimalToStringByteArray() { + void testMinimalToStringByteArray() { int len = 16; byte[] bytes = genData(len); StringBuilder expected = new StringBuilder(bytes.length * 2); @@ -56,35 +60,34 @@ static void testMinimalToStringByteArray() { expected.append(String.format("%02x", bytes[i])); String actual = HexPrinter.minimal().toString(bytes); System.out.println(actual); - Assert.assertEquals(actual, expected.toString(), "Minimal format incorrect"); - } - - @DataProvider(name = "ColumnParams") - Object[][] columnParams() { - return new Object[][]{ - {"%4d: ", "%d ", 10, " ; ", 50, HexPrinter.Formatters.PRINTABLE, "\n"}, - {"%03o: ", "%d ", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"}, - {"%5d: ", "%02x:", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"}, - {"%5d: ", "%3d", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"}, - {"%05o: ", "%3o", 8, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"}, - {"%6x: ", "%02x", 8, " | ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, "%d "), "\n"}, - {"%2x: ", "%02x", 8, " | ", 50, HexPrinter.Formatters.PRINTABLE, "\n"}, - {"%5d: ", "%02x", 16, " | ", 50, HexPrinter.Formatters.ofPrimitive(short.class, "%d "), "\n"}, - }; + assertEquals(expected.toString(), actual, "Minimal format incorrect"); } - @DataProvider(name = "BuiltinParams") - Object[][] builtinParams() { - return new Object[][]{ - {"minimal", "", "%02x", 16, "", 64, HexPrinter.Formatters.NONE, ""}, - {"canonical", "%08x ", "%02x ", 16, "|", 31, HexPrinter.Formatters.PRINTABLE, "|" + System.lineSeparator()}, - {"simple", "%04x: ", "%02x ", 16, " // ", 64, HexPrinter.Formatters.ASCII, System.lineSeparator()}, - {"source", " ", "(byte)%3d, ", 8, " // ", 64, HexPrinter.Formatters.PRINTABLE, System.lineSeparator()}, - }; + static Stream columnParams() { + return Stream.of( + Arguments.of("%4d: ", "%d ", 10, " ; ", 50, HexPrinter.Formatters.PRINTABLE, "\n"), + Arguments.of("%03o: ", "%d ", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"), + Arguments.of("%5d: ", "%02x:", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"), + Arguments.of("%5d: ", "%3d", 16, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"), + Arguments.of("%05o: ", "%3o", 8, " ; ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, ""), "\n"), + Arguments.of("%6x: ", "%02x", 8, " | ", 50, HexPrinter.Formatters.ofPrimitive(byte.class, "%d "), "\n"), + Arguments.of("%2x: ", "%02x", 8, " | ", 50, HexPrinter.Formatters.PRINTABLE, "\n"), + Arguments.of("%5d: ", "%02x", 16, " | ", 50, HexPrinter.Formatters.ofPrimitive(short.class, "%d "), "\n") + ); + } + + static Stream builtinParams() { + return Stream.of( + Arguments.of("minimal", "", "%02x", 16, "", 64, HexPrinter.Formatters.NONE, ""), + Arguments.of("canonical", "%08x ", "%02x ", 16, "|", 31, HexPrinter.Formatters.PRINTABLE, "|" + System.lineSeparator()), + Arguments.of("simple", "%04x: ", "%02x ", 16, " // ", 64, HexPrinter.Formatters.ASCII, System.lineSeparator()), + Arguments.of("source", " ", "(byte)%3d, ", 8, " // ", 64, HexPrinter.Formatters.PRINTABLE, System.lineSeparator()) + ); } - @Test(dataProvider = "BuiltinParams") - public void testBuiltins(String name, String offsetFormat, String binFormat, int colWidth, + @ParameterizedTest + @MethodSource("builtinParams") + void testBuiltins(String name, String offsetFormat, String binFormat, int colWidth, String annoDelim, int annoWidth, HexPrinter.Formatter mapper, String lineSep) { HexPrinter f = switch (name) { @@ -104,11 +107,12 @@ public void testBuiltins(String name, String offsetFormat, String binFormat, int .formatter(mapper, annoDelim, annoWidth) .withLineSeparator(lineSep); String expected = f2.toString(); - Assert.assertEquals(actual, expected, "toString of " + name + " does not match"); + assertEquals(expected, actual, "toString of " + name + " does not match"); } - @Test(dataProvider = "ColumnParams") - public void testToStringTwoLines(String offsetFormat, String binFormat, int colWidth, + @ParameterizedTest + @MethodSource("columnParams") + void testToStringTwoLines(String offsetFormat, String binFormat, int colWidth, String annoDelim, int annoWidth, HexPrinter.Formatter mapper, String lineSep) { HexPrinter f = HexPrinter.simple() @@ -119,7 +123,7 @@ public void testToStringTwoLines(String offsetFormat, String binFormat, int colW testParams(f, offsetFormat, binFormat, colWidth, annoDelim, annoWidth, mapper, lineSep); } - public static void testParams(HexPrinter printer, String offsetFormat, String binFormat, int colWidth, + static void testParams(HexPrinter printer, String offsetFormat, String binFormat, int colWidth, String annoDelim, int annoWidth, HexPrinter.Formatter mapper, String lineSep) { byte[] bytes = genData(colWidth * 2); @@ -136,22 +140,22 @@ public static void testParams(HexPrinter printer, String offsetFormat, String bi if (i % colWidth == 0) { String offset = String.format(offsetFormat, i); l = offset.length(); - Assert.assertEquals(out.substring(ndx, ndx + l), offset, + assertEquals(offset, out.substring(ndx, ndx + l), "offset format mismatch: " + ndx); ndx += l; valuesStart = ndx; } String value = String.format(binFormat, (0xff & bytes[i])); l = value.length(); - Assert.assertEquals(out.substring(ndx, ndx + l), value, + assertEquals(value, out.substring(ndx, ndx + l), "value format mismatch: " + ndx + ", i: " + i); ndx += l; if (((i + 1) % colWidth) == 0) { // Rest of line is for padding, delimiter, formatter String padding = " ".repeat(padToWidth - (ndx - valuesStart)); - Assert.assertEquals(out.substring(ndx, ndx + padding.length()), padding, "padding"); + assertEquals(padding, out.substring(ndx, ndx + padding.length()), "padding"); ndx += padding.length(); - Assert.assertEquals(out.substring(ndx, ndx + annoDelim.length()), annoDelim, + assertEquals(annoDelim, out.substring(ndx, ndx + annoDelim.length()), "delimiter mismatch"); ndx += annoDelim.length(); @@ -162,7 +166,7 @@ public static void testParams(HexPrinter printer, String offsetFormat, String bi } @Test - static void testPrintable() { + void testPrintable() { String expected = "................................" + " !\"#$%&'()*+,-./0123456789:;<=>?" + @@ -179,11 +183,11 @@ static void testPrintable() { .withBytesFormat("", 256) .formatter(HexPrinter.Formatters.PRINTABLE, "", 512); String actual = p.toString(bytes); - Assert.assertEquals(actual, expected, "Formatters.Printable mismatch"); + assertEquals(expected, actual, "Formatters.Printable mismatch"); } @Test - static void testASCII() { + void testASCII() { String expected = "\\nul\\soh\\stx\\etx\\eot\\enq\\ack\\bel\\b\\t\\n\\vt\\f\\r\\so\\si\\dle" + "\\dc1\\dc2\\dc3\\dc4\\nak\\syn\\etb\\can\\em\\sub\\esc\\fs\\gs\\rs\\us" + " !\"#$%&'()*+,-./0123456789:;<=>?" + @@ -204,25 +208,25 @@ static void testASCII() { .withBytesFormat("", 256) .formatter(HexPrinter.Formatters.ASCII, "", 256); String actual = p.toString(bytes); - Assert.assertEquals(actual, expected, "Formatters.ASCII mismatch"); - } - - @DataProvider(name = "PrimitiveFormatters") - Object[][] formatterParams() { - return new Object[][]{ - {byte.class, ""}, - {byte.class, "%02x: "}, - {short.class, "%d "}, - {int.class, "%08x, "}, - {long.class, "%16x "}, - {float.class, "%3.4f "}, - {double.class, "%6.3g "}, - {boolean.class, "%b "}, - }; + assertEquals(expected, actual, "Formatters.ASCII mismatch"); + } + + static Stream formatterParams() { + return Stream.of( + Arguments.of(byte.class, ""), + Arguments.of(byte.class, "%02x: "), + Arguments.of(short.class, "%d "), + Arguments.of(int.class, "%08x, "), + Arguments.of(long.class, "%16x "), + Arguments.of(float.class, "%3.4f "), + Arguments.of(double.class, "%6.3g "), + Arguments.of(boolean.class, "%b ") + ); } - @Test(dataProvider = "PrimitiveFormatters") - public void testFormatter(Class primClass, String fmtString) { + @ParameterizedTest + @MethodSource("formatterParams") + void testFormatter(Class primClass, String fmtString) { HexPrinter.Formatter formatter = HexPrinter.Formatters.ofPrimitive(primClass, fmtString); // Create a byte array with data for two lines int colWidth = 8; @@ -235,22 +239,23 @@ public void testFormatter(Class primClass, String fmtString) { formatter.annotate(in, sb); Object n = readPrimitive(primClass, in2); String expected = String.format(fmtString, n); - Assert.assertEquals(sb.toString(), expected, "mismatch"); + assertEquals(expected, sb.toString(), "mismatch"); sb.setLength(0); } } catch (IOException ioe) { // EOF is done } try { - Assert.assertEquals(in.available(), 0, "not all input consumed"); - Assert.assertEquals(in2.available(), 0, "not all 2nd stream input consumed"); + assertEquals(0, in.available(), "not all input consumed"); + assertEquals(0, in2.available(), "not all 2nd stream input consumed"); } catch (IOException ioe) { // } } - @Test(dataProvider = "PrimitiveFormatters") - static void testHexPrinterPrimFormatter(Class primClass, String fmtString) { + @ParameterizedTest + @MethodSource("formatterParams") + void testHexPrinterPrimFormatter(Class primClass, String fmtString) { // Create a byte array with data for two lines int colWidth = 8; byte[] bytes = genData(colWidth); @@ -264,7 +269,7 @@ static void testHexPrinterPrimFormatter(Class primClass, String fmtString) { String expected = HexPrinter.simple() .formatter(HexPrinter.Formatters.ofPrimitive(primClass, fmtString)) .toString(bytes); - Assert.assertEquals(actual, expected, "mismatch"); + assertEquals(expected, actual, "mismatch"); } private static Object readPrimitive(Class primClass, DataInputStream in) throws IOException { @@ -289,22 +294,20 @@ private static Object readPrimitive(Class primClass, DataInputStream in) thro } } - @DataProvider(name = "sources") - Object[][] sources() { - return new Object[][]{ - {genBytes(21), 0, -1}, - {genBytes(21), 5, 12}, - }; + static Stream sources() { + return Stream.of( + Arguments.of(genBytes(21), 0, -1), + Arguments.of(genBytes(21), 5, 12) + ); } - @DataProvider(name = "badsources") - Object[][] badSources() { - return new Object[][]{ - {genBytes(21), 5, 22}, - }; + static Stream badSources() { + return Stream.of( + Arguments.of(genBytes(21), 5, 22) + ); } - public static byte[] genData(int len) { + static byte[] genData(int len) { // Create a byte array with data for two lines byte[] bytes = new byte[len]; for (int i = 0; i < len / 2; i++) { @@ -314,7 +317,7 @@ public static byte[] genData(int len) { return bytes; } - public static byte[] genFloat(int len) { + static byte[] genFloat(int len) { byte[] bytes = null; try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(baos)) { @@ -327,7 +330,7 @@ public static byte[] genFloat(int len) { return bytes; } - public static byte[] genDouble(int len) { + static byte[] genDouble(int len) { byte[] bytes = null; try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(baos)) { @@ -340,33 +343,38 @@ public static byte[] genDouble(int len) { return bytes; } - public static byte[] genBytes(int len) { + static byte[] genBytes(int len) { byte[] bytes = new byte[len]; for (int i = 0; i < len; i++) bytes[i] = (byte) ('A' + i); return bytes; } - public ByteBuffer genByteBuffer(int len) { + ByteBuffer genByteBuffer(int len) { return ByteBuffer.wrap(genBytes(len)); } - public InputStream genInputStream(int len) { + InputStream genInputStream(int len) { return new ByteArrayInputStream(genBytes(len)); } @Test - public void testNilPrinterBigBuffer() { + void testNilPrinterBigBuffer() { byte[] bytes = new byte[1024]; HexPrinter p = HexPrinter.minimal(); String r = p.toString(bytes); - Assert.assertEquals(r.length(), bytes.length * 2, "encoded byte wrong size"); - Assert.assertEquals(r.replace("00", "").length(), 0, "contents not all zeros"); + assertEquals(bytes.length * 2, r.length(), "encoded byte wrong size"); + assertEquals(0, r.replace("00", "").length(), "contents not all zeros"); + } + + @ParameterizedTest + @MethodSource("badSources") + void testBadToStringByteBuffer(byte[] bytes, int offset, int length) { + assertThrows(java.lang.IndexOutOfBoundsException.class, + () -> testThrowsForBadToStringByteBuffer(bytes, offset, length)); } - @Test(dataProvider = "badsources", - expectedExceptions = java.lang.IndexOutOfBoundsException.class) - public void testBadToStringByteBuffer(byte[] bytes, int offset, int length) { + void testThrowsForBadToStringByteBuffer(byte[] bytes, int offset, int length) { if (length < 0) length = bytes.length - offset; ByteBuffer bb = ByteBuffer.wrap(bytes, 0, bytes.length); @@ -381,11 +389,12 @@ public void testBadToStringByteBuffer(byte[] bytes, int offset, int length) { actual = HexPrinter.simple().toString(bb, offset, length); System.out.println(actual); String expected = HexPrinter.simple().toString(bytes, offset, length); - Assert.assertEquals(actual, expected, "mismatch in format()"); + assertEquals(expected, actual, "mismatch in format()"); } - @Test(dataProvider = "sources") - public void testToStringByteBuffer(byte[] bytes, int offset, int length) { + @ParameterizedTest + @MethodSource("sources") + void testToStringByteBuffer(byte[] bytes, int offset, int length) { if (length < 0) length = bytes.length - offset; ByteBuffer bb = ByteBuffer.wrap(bytes, 0, bytes.length); @@ -400,11 +409,12 @@ public void testToStringByteBuffer(byte[] bytes, int offset, int length) { actual = HexPrinter.simple().toString(bb, offset, length); System.out.println(actual); String expected = HexPrinter.simple().toString(bytes, offset, length); - Assert.assertEquals(actual, expected, "mismatch in format()"); + assertEquals(expected, actual, "mismatch in format()"); } - @Test(dataProvider = "sources") - public void testFormatBytes(byte[] bytes, int offset, int length) { + @ParameterizedTest + @MethodSource("sources") + void testFormatBytes(byte[] bytes, int offset, int length) { int len = length >= 0 ? length : bytes.length; System.out.printf("Source: %s, off: %d, len: %d%n", "bytes", offset, len); @@ -416,11 +426,12 @@ public void testFormatBytes(byte[] bytes, int offset, int length) { String actual = sb.toString(); System.out.println(actual); String expected = HexPrinter.simple().toString(bytes, offset, len); - Assert.assertEquals(actual, expected, "mismatch in format()"); + assertEquals(expected, actual, "mismatch in format()"); } - @Test(dataProvider = "sources") - public void testFormatByteBuffer(byte[] bytes, int offset, int length) { + @ParameterizedTest + @MethodSource("sources") + void testFormatByteBuffer(byte[] bytes, int offset, int length) { if (length < 0) length = bytes.length - offset; ByteBuffer bb = ByteBuffer.wrap(bytes, 0, bytes.length); @@ -436,11 +447,12 @@ public void testFormatByteBuffer(byte[] bytes, int offset, int length) { String actual = sb.toString(); System.out.println(actual); String expected = HexPrinter.simple().toString(bytes, offset, length); - Assert.assertEquals(actual, expected, "mismatch in format()"); + assertEquals(expected, actual, "mismatch in format()"); } - @Test(dataProvider = "sources") - public void testFormatInputStream(byte[] bytes, int offset, int length) { + @ParameterizedTest + @MethodSource("sources") + void testFormatInputStream(byte[] bytes, int offset, int length) { // Offset is ignored InputStream is = new ByteArrayInputStream(bytes, 0, length); StringBuilder sb = new StringBuilder(); @@ -450,32 +462,37 @@ public void testFormatInputStream(byte[] bytes, int offset, int length) { String actual = sb.toString(); System.out.println(actual); String expected = HexPrinter.simple().toString(bytes, 0, length); - Assert.assertEquals(actual, expected, "mismatch in format()"); + assertEquals(expected, actual, "mismatch in format()"); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullByteArray() { - HexPrinter.simple().dest(System.out).format((byte[]) null); + @Test + void testNullByteArray() { + assertThrows(NullPointerException.class, + () -> HexPrinter.simple().dest(System.out).format((byte[]) null)); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullByteArrayOff() { - HexPrinter.simple().dest(System.out).format((byte[]) null, 0, 1); + @Test + void testNullByteArrayOff() { + assertThrows(NullPointerException.class, + () -> HexPrinter.simple().dest(System.out).format((byte[]) null, 0, 1)); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullByteBuffer() { - HexPrinter.simple().dest(System.out).format((ByteBuffer) null); + @Test + void testNullByteBuffer() { + assertThrows(NullPointerException.class, + () -> HexPrinter.simple().dest(System.out).format((ByteBuffer) null)); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullByteBufferOff() { - HexPrinter.simple().dest(System.out).format((ByteBuffer) null, 0, 1); + @Test + void testNullByteBufferOff() { + assertThrows(NullPointerException.class, + () -> HexPrinter.simple().dest(System.out).format((ByteBuffer) null, 0, 1)); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullInputStream() { - HexPrinter.simple().dest(System.out).format((InputStream) null); + @Test + void testNullInputStream() { + assertThrows(NullPointerException.class, () -> + HexPrinter.simple().dest(System.out).format((InputStream) null)); } } diff --git a/test/lib-test/jdk/test/lib/hexdump/ObjectStreamPrinterTest.java b/test/lib-test/jdk/test/lib/hexdump/ObjectStreamPrinterTest.java index 02bb492a968..9d73fbcb6b1 100644 --- a/test/lib-test/jdk/test/lib/hexdump/ObjectStreamPrinterTest.java +++ b/test/lib-test/jdk/test/lib/hexdump/ObjectStreamPrinterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,8 +23,10 @@ package jdk.test.lib.hexdump; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.Arguments; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -47,54 +49,52 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; /* * @test * @summary Check ObjectStreamPrinter formatting * @library /test/lib - * @run testng/othervm -DDEBUG=true jdk.test.lib.hexdump.ObjectStreamPrinterTest + * @run junit/othervm -DDEBUG=true jdk.test.lib.hexdump.ObjectStreamPrinterTest */ /** * Test of the formatter is fairly coarse, formatting several * sample classes and spot checking the result string for key strings. */ -@Test -public class ObjectStreamPrinterTest { +class ObjectStreamPrinterTest { // Override with (-DDEBUG=true) to see all the output private static boolean DEBUG = Boolean.getBoolean("DEBUG"); - @DataProvider(name = "serializables") - Object[][] serializables() { - return new Object[][]{ - {new Object[]{"abc", "def"}, 0, 0, 2}, - {new Object[]{0, 1}, 2, 2, 0}, - {new Object[]{TimeUnit.DAYS, TimeUnit.SECONDS}, 2, 0, 2}, - {new Object[]{List.of("one", "two", "three")}, 1, 1, 3}, - {new Object[]{genList()}, 1, 1, 2}, - {new Object[]{genMap()}, 1, 1, 5}, - {new Object[]{genProxy()}, 5, 2, 9}, - {new Object[]{new char[]{'x', 'y', 'z'}, + static Stream serializables() { + return Stream.of( + Arguments.of(new Object[]{"abc", "def"}, 0, 0, 2), + Arguments.of(new Object[]{0, 1}, 2, 2, 0), + Arguments.of(new Object[]{TimeUnit.DAYS, TimeUnit.SECONDS}, 2, 0, 2), + Arguments.of(new Object[]{List.of("one", "two", "three")}, 1, 1, 3), + Arguments.of(new Object[]{genList()}, 1, 1, 2), + Arguments.of(new Object[]{genMap()}, 1, 1, 5), + Arguments.of(new Object[]{genProxy()}, 5, 2, 9), + Arguments.of(new Object[]{new char[]{'x', 'y', 'z'}, new byte[]{0x61, 0x62, 0x63}, new int[]{4, 5, 6}, new float[]{1.0f, 2.0f, 3.1415927f}, new boolean[]{true, false, true}, - new Object[]{"first", 3, 3.14159f}}, 9, 2, 1}, - { new Object[] {new XYPair(3, 5)}, 1, 1, 0}, - }; + new Object[]{"first", 3, 3.14159f}}, 9, 2, 1), + Arguments.of(new Object[] {new XYPair(3, 5)}, 1, 1, 0) + ); } - @DataProvider(name = "SingleObjects") - Object[][] sources() { - return new Object[][]{ - {"A Simple", new A(), 1, 1, 0}, - {"BNoDefaultRO has no call to defaultReadObject", new BNoDefaultRO(), 2, 1, 1}, - {"BDefaultRO has call to defaultReadObject", new BDefaultRO(), 2, 1, 1}, - {"CNoDefaultRO extends BNoDefaultRO with no fields", new CNoDefaultRO(), 3, 1, 3}, - {"CDefaultRO extends BDefaultRO with no fields", new CDefaultRO(), 3, 1, 3}, - }; + static Stream sources(){ + return Stream.of( + Arguments.of("A Simple", new A(), 1, 1, 0), + Arguments.of("BNoDefaultRO has no call to defaultReadObject", new BNoDefaultRO(), 2, 1, 1), + Arguments.of("BDefaultRO has call to defaultReadObject", new BDefaultRO(), 2, 1, 1), + Arguments.of("CNoDefaultRO extends BNoDefaultRO with no fields", new CNoDefaultRO(), 3, 1, 3), + Arguments.of("CDefaultRO extends BDefaultRO with no fields", new CDefaultRO(), 3, 1, 3) + ); } @@ -109,8 +109,9 @@ Object[][] sources() { * @param strings the expected count of strings * @throws IOException if any I/O exception occurs */ - @Test(dataProvider = "serializables") - public void testFormat(Object[] objs, int descriptors, int objects, int strings) throws IOException { + @ParameterizedTest + @MethodSource("serializables") + void testFormat(Object[] objs, int descriptors, int objects, int strings) throws IOException { byte[] bytes = serializeObjects(objs); String result = HexPrinter.simple() @@ -133,8 +134,9 @@ public void testFormat(Object[] objs, int descriptors, int objects, int strings) * @param strings the expected count of strings * @throws IOException if any I/O exception occurs */ - @Test(dataProvider = "serializables", enabled=true) - static void standAlonePrinter(Object[] objs, int descriptors, int objects, int strings) throws IOException{ + @ParameterizedTest + @MethodSource("serializables") + void standAlonePrinter(Object[] objs, int descriptors, int objects, int strings) throws IOException{ byte[] bytes = serializeObjects(objs); StringBuilder sb = new StringBuilder(); @@ -170,8 +172,9 @@ static void standAlonePrinter(Object[] objs, int descriptors, int objects, int s * @param strings the expected count of strings * @throws IOException if any I/O exception occurs */ - @Test(dataProvider = "SingleObjects") - static void singleObjects(String label, Object o, int descriptors, int objects, int strings) throws IOException { + @ParameterizedTest + @MethodSource("sources") + void singleObjects(String label, Object o, int descriptors, int objects, int strings) throws IOException { if (DEBUG) System.out.println("Case: " + label); ByteArrayOutputStream boas = new ByteArrayOutputStream(); @@ -198,7 +201,7 @@ static void singleObjects(String label, Object o, int descriptors, int objects, * @throws IOException if any I/O exception occurs */ @Test - static void longString() throws IOException { + void longString() throws IOException { String large = " 123456789abcedf".repeat(0x1000); ByteArrayOutputStream boas = new ByteArrayOutputStream(); @@ -230,7 +233,7 @@ static void longString() throws IOException { * @throws IOException if an I/O exception occurs */ @Test - static void testMain() throws IOException { + void testMain() throws IOException { Object[] objs = {genList()}; byte[] bytes = serializeObjects(objs); // A serialized List Path p = Path.of("scratch.tmp"); @@ -269,17 +272,17 @@ static void expectStrings(String result, String key, int expectedCount) { for (int i = result.indexOf(key); i >= 0; i = result.indexOf(key, i + 1)) { count++; } - assertEquals(count, expectedCount, "Occurrences of " + key); + assertEquals(expectedCount, count, "Occurrences of " + key); } - public static List genList() { + static List genList() { List l = new ArrayList<>(); l.add("abc"); l.add("def"); return l; } - public static Map genMap() { + static Map genMap() { Map map = new HashMap<>(); map.put("1", "One"); map.put("2", "Two"); @@ -287,7 +290,7 @@ public static Map genMap() { return map; } - public static Object genProxy() { + static Object genProxy() { InvocationHandler h = (InvocationHandler & Serializable) (Object proxy, Method method, Object[] args) -> null; Class[] intf = new Class[]{Serializable.class, DataInput.class, DataOutput.class}; return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), intf, h); diff --git a/test/lib-test/jdk/test/lib/hexdump/StreamDumpTest.java b/test/lib-test/jdk/test/lib/hexdump/StreamDumpTest.java index c0273786d92..37fee9d5254 100644 --- a/test/lib-test/jdk/test/lib/hexdump/StreamDumpTest.java +++ b/test/lib-test/jdk/test/lib/hexdump/StreamDumpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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,9 +23,10 @@ package jdk.test.lib.hexdump; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.Arguments; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -50,23 +51,23 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; /* * @test * @summary Test StreamDump utility * @library /test/lib * @build jdk.test.lib.hexdump.StreamDump - * @run testng jdk.test.lib.hexdump.StreamDumpTest + * @run junit jdk.test.lib.hexdump.StreamDumpTest */ /** * Test of the formatter is fairly coarse, formatting several * sample classes and spot checking the result string for key strings. */ -@Test -public class StreamDumpTest { +class StreamDumpTest { private final static Path workDir = Path.of("."); @@ -99,24 +100,23 @@ private static String createTmpSer() { * Arg list and the expected exit status, stdout line count, and stderr line count. * @return array of argument list arrays. */ - @DataProvider(name = "serializables") - Object[][] serializables() { - return new Object[][] { - {new String[]{testSRC + "/openssl.p12.pem"}, - 0, 126, 0}, - {new String[]{"--formatter", "jdk.test.lib.hexdump.ASN1Formatter", testSRC + "/openssl.p12.pem"}, - 0, 126, 0}, - {new String[]{serializedListPath}, - 0, 19, 0}, - {new String[]{"--formatter", "jdk.test.lib.hexdump.ObjectStreamPrinter", serializedListPath}, - 0, 19, 0}, - {new String[]{}, - 1, 2, 0}, // no file arguments - {new String[]{"--formatter"}, - 1, 2, 0}, // --formatter option requires a class name - {new String[]{"-formatter", "jdk.test.lib.hexdump.ObjectStreamPrinter"}, - 1, 2, 0}, // options start with double "--" - }; + static Stream serializables() { + return Stream.of( + Arguments.of(new String[]{testSRC + "/openssl.p12.pem"}, + 0, 126, 0), + Arguments.of(new String[]{"--formatter", "jdk.test.lib.hexdump.ASN1Formatter", testSRC + "/openssl.p12.pem"}, + 0, 126, 0), + Arguments.of(new String[]{serializedListPath}, + 0, 19, 0), + Arguments.of(new String[]{"--formatter", "jdk.test.lib.hexdump.ObjectStreamPrinter", serializedListPath}, + 0, 19, 0), + Arguments.of(new String[]{}, + 1, 2, 0), // no file arguments + Arguments.of(new String[]{"--formatter"}, + 1, 2, 0), // --formatter option requires a class name + Arguments.of(new String[]{"-formatter", "jdk.test.lib.hexdump.ObjectStreamPrinter"}, + 1, 2, 0) // options start with double "--" + ); } @@ -126,8 +126,9 @@ Object[][] serializables() { * Each file should be formatted to stdout with no exceptions * @throws IOException if an I/O exception occurs */ - @Test(dataProvider="serializables") - static void testStreamDump(String[] args, int expectedStatus, int expectedStdout, int expectedStderr) throws IOException { + @ParameterizedTest + @MethodSource("serializables") + void testStreamDump(String[] args, int expectedStatus, int expectedStdout, int expectedStderr) throws IOException { List argList = new ArrayList<>(); argList.add(testJDK + "/bin/" + "java"); argList.add("-classpath"); @@ -148,7 +149,7 @@ static void testStreamDump(String[] args, int expectedStatus, int expectedStdout int actualStatus = p.waitFor(); fileCheck(stdoutPath, expectedStdout); fileCheck(stderrPath, expectedStderr); - assertEquals(actualStatus, expectedStatus, "Unexpected exit status"); + assertEquals(expectedStatus, actualStatus, "Unexpected exit status"); } catch (InterruptedException ie) { ie.printStackTrace(); } @@ -168,7 +169,7 @@ static void fileCheck(Path path, int expectedLines) throws IOException { Files.newBufferedReader(path).lines().forEach(s -> System.out.println(s)); System.out.println("----End----"); } - assertEquals(actualLines, expectedLines, "Unexpected line count"); + assertEquals(expectedLines, actualLines, "Unexpected line count"); } /** @@ -190,14 +191,14 @@ private static byte[] serializeObjects(Object[] obj) throws IOException { return bytes; } - public static List genList() { + static List genList() { List l = new ArrayList<>(); l.add("abc"); l.add("def"); return l; } - public static Map genMap() { + static Map genMap() { Map map = new HashMap<>(); map.put("1", "One"); map.put("2", "Two"); From a69c4370a7b0f98c507dafe1621a17b4190f9e6a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:14:53 +0000 Subject: [PATCH 069/298] 8316559: Refactor some util/Calendar tests to JUnit Backport-of: 355811a996544c54cde9ff232450f5e5c8e1e632 --- .../util/Calendar/BuddhistCalendarTest.java | 349 +++++++++--------- test/jdk/java/util/Calendar/Bug4302966.java | 14 +- test/jdk/java/util/Calendar/Bug4766302.java | 21 +- test/jdk/java/util/Calendar/bug4028518.java | 39 +- test/jdk/java/util/Calendar/bug4100311.java | 25 +- test/jdk/java/util/Calendar/bug4243802.java | 116 +++--- test/jdk/java/util/Calendar/bug4316678.java | 83 +++-- test/jdk/java/util/Calendar/bug4372743.java | 157 ++++---- test/jdk/java/util/Calendar/bug4401223.java | 88 ++--- test/jdk/java/util/Calendar/bug4514831.java | 136 ++++--- 10 files changed, 554 insertions(+), 474 deletions(-) diff --git a/test/jdk/java/util/Calendar/BuddhistCalendarTest.java b/test/jdk/java/util/Calendar/BuddhistCalendarTest.java index a94685eb78d..0ce59c66c2c 100644 --- a/test/jdk/java/util/Calendar/BuddhistCalendarTest.java +++ b/test/jdk/java/util/Calendar/BuddhistCalendarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -24,191 +24,200 @@ /* * @test * @bug 4817812 4847186 4956227 4956479 - * @summary Confirm that BuddhistCalendar's add(), roll() and toString() work correctly with Buddhist Era years. + * @summary Confirm that BuddhistCalendar's add(), roll(), set(), and toString() + * work correctly with Buddhist Era years. + * @run junit BuddhistCalendarTest */ import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Locale; -import static java.util.Calendar.*; +import java.util.stream.Stream; + +import static java.util.Calendar.APRIL; +import static java.util.Calendar.DATE; +import static java.util.Calendar.DECEMBER; +import static java.util.Calendar.ERA; +import static java.util.Calendar.FEBRUARY; +import static java.util.Calendar.JANUARY; +import static java.util.Calendar.MAY; +import static java.util.Calendar.MONTH; +import static java.util.Calendar.WEEK_OF_YEAR; +import static java.util.Calendar.YEAR; + + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class BuddhistCalendarTest { private static final Locale THAI_LOCALE = Locale.of("th", "TH"); - public static void main(String[] args) { - testAddRoll(); - testToString(); - testException(); - testLeastMax(); + /* + * Test some add values for the BuddhistCalendar. This test compares the same field + * as the one added. + */ + @ParameterizedTest + @MethodSource("addDataProvider") + public void buddhistAddTest(Calendar cal, int amount, int fieldToAdd) { + int base = cal.get(YEAR); + cal.add(fieldToAdd, amount); + int yearAfterRoll = cal.get(YEAR); + assertEquals(yearAfterRoll, base+amount, String.format( + "Added: %s to field: %s", amount, fieldToAdd)); + } + + /* + * Given in the format: Calendar, amount to add, and field to add. + * Test adding of positive and negative year values. + */ + private static Stream addDataProvider() { + return Stream.of( + Arguments.of(getBuddhistCalendar(), 1, YEAR), + Arguments.of(getBuddhistCalendar(), -3, YEAR) + ); + } + + /* + * Test some add values for the BuddhistCalendar. Compare a bigger field + * (year) than the one added (month). Larger field should roll over. + */ + @ParameterizedTest + @MethodSource("alternateAddDataProvider") + public void buddhistAlternateAddTest(Calendar cal, int amount, int fieldToAdd) { + int base = cal.get(YEAR); + cal.add(fieldToAdd, amount); + int yearAfterRoll = cal.get(YEAR); + assertEquals(yearAfterRoll, (amount>0) ? (base+1): (base-1), String.format( + "Added: %s to field: %s", amount, fieldToAdd)); + } + + /* + * Given in the format: Calendar, amount to add, and field to add. + * Test adding of positive and negative month values. + */ + private static Stream alternateAddDataProvider() { + return Stream.of( + Arguments.of(getBuddhistCalendarBuilder().set(MONTH, DECEMBER).build(), 2, MONTH), + Arguments.of(getBuddhistCalendarBuilder().set(MONTH, FEBRUARY).build(), -4, MONTH) + ); + } + + /* + * Test some roll values for the BuddhistCalendar. Compare same field + * that was rolled, value should change. + */ + @ParameterizedTest + @MethodSource("rollProvider") + public void buddhistRollTest(Calendar cal, int amount, int fieldToRoll) { + int base = cal.get(YEAR); + cal.roll(fieldToRoll, amount); + int year = cal.get(YEAR); + assertEquals(year, base+amount, "Rolling field should change value"); + } + + /* + * Given in the format: Calendar, amount to roll, and field to roll. + * Test rolling of positive and negative year values. + */ + private static Stream rollProvider() { + return Stream.of( + Arguments.of(getBuddhistCalendar(), 2, YEAR), + Arguments.of(getBuddhistCalendar(), -4, YEAR) + ); + } + + /* + * Set some calendar values and roll, however, measure a different + * field than the field that was rolled. Rolling should not change the + * larger field. + */ + @ParameterizedTest + @MethodSource("alternateRollProvider") + public void buddhistAlternateRollTest(Calendar cal, int amount, int fieldToRoll) { + int base = cal.get(YEAR); + cal.roll(fieldToRoll, amount); + int year = cal.get(YEAR); + assertEquals(year, base, "Rolling smaller field should not change bigger field"); } - /** - * 4817812 + /* + * Given in the format: Calendar, amount to roll, and field to roll. + * Test rolling of positive and negative week_of_year values. */ - static void testAddRoll() { - Calendar cal; - int base, year; - - /* - * Test: BuddhistCalendar.add(YEAR) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.add(YEAR, 1); - year = cal.get(YEAR); - check(year, base+1, "add(+YEAR)"); - - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.add(YEAR, -3); - year = cal.get(YEAR); - check(year, base-3, "add(-YEAR)"); - - /* - * Test BuddhistCalendar.add(MONTH) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.set(MONTH, DECEMBER); - cal.add(MONTH, 2); - year = cal.get(YEAR); - check(year, base+1, "add(+MONTH)"); - - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.set(MONTH, FEBRUARY); - cal.add(MONTH, -4); - year = cal.get(YEAR); - check(year, base-1, "add(-MONTH)"); - - /* - * Test BuddhistCalendar.roll(YEAR) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.roll(YEAR, 2); - year = cal.get(YEAR); - check(year, base+2, "roll(+YEAR)"); - - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.roll(YEAR, -4); - year = cal.get(YEAR); - check(year, base-4, "roll(-YEAR)"); - - /* - * Test BuddhistCalendar.roll(WEEK_OF_YEAR) - */ - cal = getBuddhistCalendar(); - cal.set(YEAR, 2543); // A.D.2000 - cal.set(MONTH, DECEMBER); - cal.set(DATE, 31); - base = cal.get(YEAR); - check(base, 2543, "roll(+WEEK_OF_YEAR)"); - cal.roll(WEEK_OF_YEAR, 10); - year = cal.get(YEAR); - check(year, base, "roll(+WEEK_OF_YEAR)"); - - cal = getBuddhistCalendar(); - cal.set(YEAR, 2543); // A.D.2000 - cal.set(MONTH, JANUARY); - cal.set(DATE, 1); - base = cal.get(YEAR); - check(base, 2543, "roll(+WEEK_OF_YEAR)"); - cal.roll(WEEK_OF_YEAR, -10); - year = cal.get(YEAR); - check(year, base, "roll(-WEEK_OF_YEAR)"); - - /* - * Test Calendar.set(year, month, date) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); + private static Stream alternateRollProvider() { + return Stream.of( + Arguments.of(getBuddhistCalendarBuilder().set(YEAR, 2543) + .set(MONTH, DECEMBER).set(DATE, 31).build(), 10, WEEK_OF_YEAR), + Arguments.of(getBuddhistCalendarBuilder().set(YEAR, 2543) + .set(MONTH, JANUARY).set(DATE, 1).build(), -10, WEEK_OF_YEAR) + ); + } + + // Test the overloaded set() methods. Check year value. + @Test + public void buddhistSetTest() { + Calendar cal = getBuddhistCalendar(); cal.set(3001, APRIL, 10); - year = cal.get(YEAR); - check(year, 3001, "set(year, month, date)"); - - /* - * Test Calendar.set(year, month, date, hour, minute) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); + assertEquals(cal.get(YEAR), 3001); cal.set(3020, MAY, 20, 9, 10); - year = cal.get(YEAR); - check(year, 3020, "set(year, month, date, hour, minute)"); - - /* - * Test Calendar.set(year, month, date, hour, minute, second) - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - cal.set(3120, MAY, 20, 9, 10, 52); - year = cal.get(YEAR); - check(year, 3120, "set(year, month, date, hour, minute, second)"); - - /* - * Test BuddhistCalendar.getActualMaximum(YEAR); - * set(YEAR)/get(YEAR) in this method doesn't affect the real - * YEAR value because a clone is used with set()&get(). - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - int limit = cal.getActualMaximum(YEAR); - year = cal.get(YEAR); - check(year, base, "BuddhistCalendar.getActualMaximum(YEAR)"); - - /* - * Test BuddhistCalendar.getActualMinimum(YEAR); - * This doesn't call set(YEAR) nor get(YEAR), though. - */ - cal = getBuddhistCalendar(); - base = cal.get(YEAR); - limit = cal.getActualMinimum(YEAR); - year = cal.get(YEAR); - check(year, base, "BuddhistCalendar.getActualMinimum(YEAR)"); - } - - /** - * 4847186: BuddhistCalendar: toString() returns Gregorian year + assertEquals(cal.get(YEAR), 3020); + cal.set(3120, MAY, 20, 9, 10, 52 ); + assertEquals(cal.get(YEAR), 3120); + } + + /* + * Test BuddhistCalendar.getActualMaximum(YEAR); + * set(YEAR)/get(YEAR) in this method doesn't affect the real + * YEAR value because a clone is used with set() and get(). */ - static void testToString() { + @Test + public void buddhistActualMaximumTest() { + Calendar cal = getBuddhistCalendar(); + int base = cal.get(YEAR); + int ignored = cal.getActualMaximum(YEAR); + int year = cal.get(YEAR); + assertEquals(year, base, "BuddhistCalendar.getActualMaximum(YEAR)"); + } + + // Test BuddhistCalendar.getActualMinimum(YEAR), doesn't call set(YEAR) nor get(YEAR). + @Test + public void buddhistActualMinimumTest() { + Calendar cal = getBuddhistCalendar(); + int base = cal.get(YEAR); + int ignored = cal.getActualMinimum(YEAR); + int year = cal.get(YEAR); + assertEquals(year, base, "BuddhistCalendar.getActualMinimum(YEAR)"); + } + + // 4847186: BuddhistCalendar: toString() returns Gregorian year + @Test + public void buddhistToStringTest() { Calendar cal = getBuddhistCalendar(); int year = cal.get(YEAR); String s = cal.toString(); String y = s.replaceAll(".+,YEAR=(\\d+),.+", "$1"); - if (Integer.parseInt(y) != year) { - throw new RuntimeException("toString(): wrong year value: got " + y - + ", expected " + year); - } + assertEquals(year, Integer.parseInt(y), "Wrong year value"); } - /** - * 4956479: BuddhistCalendar methods may return wrong values after exception - */ - static void testException() { + // 4956479: BuddhistCalendar methods may return wrong values after exception + @Test + public void buddhistValuesAfterExceptionTest() { Calendar cal = getBuddhistCalendar(); int year = cal.get(YEAR); - boolean exceptionOccurred = false; - try { - cal.add(100, +1); // cause exception - } catch (Exception e) { - exceptionOccurred = true; - } - if (!exceptionOccurred) { - throw new RuntimeException("testException: test case failed: no exception thrown"); - } + assertThrows(IllegalArgumentException.class, ()-> cal.add(100, +1)); int year2 = cal.get(YEAR); - if (year2 != year) { - throw new RuntimeException("wrong year value after exception: got " + year2 - + ", expected " + year); - } + assertEquals(year2, year, "Wrong year value after exception thrown"); } - /** - * 4956227: getLeastMaximum(WEEK_OF_MONTH) return diff. val. for Greg. and Buddhist Calendar - */ - static void testLeastMax() { + // 4956227: getLeastMaximum(WEEK_OF_MONTH) return diff. val. for Greg. and Buddhist Calendar + @Test + public void buddhistLeastMaximumTest() { Calendar bc = getBuddhistCalendar(); // Specify THAI_LOCALE to get the same params for WEEK // calculations (6904680). @@ -219,25 +228,17 @@ static void testLeastMax() { } int bn = bc.getLeastMaximum(f); int gn = gc.getLeastMaximum(f); - if (bn != gn) { - throw new RuntimeException("inconsistent Least Max value for " + Koyomi.getFieldName(f) - + ": Buddhist=" + bn - + ": Gregorian=" + gn); - } + assertEquals(bn, gn, "Inconsistent Least Max value for " + Koyomi.getFieldName(f)); } } - /** - * @return a BuddhistCalendar - */ - static Calendar getBuddhistCalendar() { - return Calendar.getInstance(THAI_LOCALE); + // Utility to get a new Buddhist Calendar Builder (to allow setting of other values) + private static Calendar.Builder getBuddhistCalendarBuilder() { + return new Calendar.Builder().setLocale(THAI_LOCALE); } - static void check(int got, int expected, String s) { - if (got != expected) { - throw new RuntimeException("Failed: " + - s + ": got:" + got + ", expected:" + expected); - } + // Utility to get a new Buddhist calendar + private static Calendar getBuddhistCalendar() { + return Calendar.getInstance(THAI_LOCALE); } } diff --git a/test/jdk/java/util/Calendar/Bug4302966.java b/test/jdk/java/util/Calendar/Bug4302966.java index aa4afe6de45..95425a94615 100644 --- a/test/jdk/java/util/Calendar/Bug4302966.java +++ b/test/jdk/java/util/Calendar/Bug4302966.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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,18 +26,22 @@ * @bug 4302966 8176841 * @modules jdk.localedata * @summary In Czech Republic first day of week is Monday not Sunday + * @run junit Bug4302966 */ import java.util.Calendar; import java.util.Locale; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + public class Bug4302966 { - public static void main(String[] args) { + // Specific day of week test for Czech locale + public void czechDayOfWeekTest() { Calendar czechCalendar = Calendar.getInstance(Locale.of("cs", "CZ")); int firstDayOfWeek = czechCalendar.getFirstDayOfWeek(); - if (firstDayOfWeek != Calendar.MONDAY) { - throw new RuntimeException(); - } + assertEquals(firstDayOfWeek, Calendar.MONDAY); } } diff --git a/test/jdk/java/util/Calendar/Bug4766302.java b/test/jdk/java/util/Calendar/Bug4766302.java index cd27e009ea2..4ddb3031ed2 100644 --- a/test/jdk/java/util/Calendar/Bug4766302.java +++ b/test/jdk/java/util/Calendar/Bug4766302.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -24,16 +24,21 @@ /* * @test * @bug 4766302 - * @summary Make sure that computeTime call doesn't reset the isTimeSet value. + * @summary Make sure that calling computeTime doesn't reset the isTimeSet value. + * @run junit Bug4766302 */ import java.util.GregorianCalendar; -@SuppressWarnings("serial") +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + public class Bug4766302 { + // Extend GregorianCalendar to check the protected value of isTimeSet + @SuppressWarnings("serial") static class MyCalendar extends GregorianCalendar { - boolean isTimeStillSet() { return isTimeSet; } @@ -43,11 +48,11 @@ protected void computeTime() { } } - public static void main(String[] args) { + // Check the value of isTimeStillSet() after calling computeTime() + @Test + public void validateIsTimeSetTest() { MyCalendar cal = new MyCalendar(); cal.computeTime(); - if (!cal.isTimeStillSet()) { - throw new RuntimeException("computeTime() call reset isTimeSet."); - } + assertTrue(cal.isTimeStillSet(), "computeTime() call reset isTimeSet."); } } diff --git a/test/jdk/java/util/Calendar/bug4028518.java b/test/jdk/java/util/Calendar/bug4028518.java index 982b93adc86..c3548ab18f0 100644 --- a/test/jdk/java/util/Calendar/bug4028518.java +++ b/test/jdk/java/util/Calendar/bug4028518.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -24,33 +24,30 @@ /* * @test * @bug 4028518 - * @summary Make sure cloned GregorianCalendar is unchanged by modifying its original. + * @summary Ensure cloned GregorianCalendar is unchanged when modifying its original. + * @run junit bug4028518 */ -import java.util.GregorianCalendar ; -import static java.util.Calendar.*; +import java.util.GregorianCalendar; + +import static java.util.Calendar.DAY_OF_MONTH; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class bug4028518 { - public static void main(String[] args) - { + /* + * Ensure modifying the original GregorianCalendar does not + * modify the cloned one as well + */ + @Test + public void clonedShouldNotChangeOriginalTest() { GregorianCalendar cal1 = new GregorianCalendar() ; GregorianCalendar cal2 = (GregorianCalendar) cal1.clone() ; - - printdate(cal1, "cal1: ") ; - printdate(cal2, "cal2 - cloned(): ") ; cal1.add(DAY_OF_MONTH, 1) ; - printdate(cal1, "cal1 after adding 1 day: ") ; - printdate(cal2, "cal2 should be unmodified: ") ; - if (cal1.get(DAY_OF_MONTH) == cal2.get(DAY_OF_MONTH)) { - throw new RuntimeException("cloned GregorianCalendar modified"); - } - } - - private static void printdate(GregorianCalendar cal, String string) - { - System.out.println(string + (cal.get(MONTH) + 1) - + "/" + cal.get(DAY_OF_MONTH) - + "/" + cal.get(YEAR)) ; + assertNotEquals(cal1.get(DAY_OF_MONTH), cal2.get(DAY_OF_MONTH), + "Cloned calendar should not have same value as original"); } } diff --git a/test/jdk/java/util/Calendar/bug4100311.java b/test/jdk/java/util/Calendar/bug4100311.java index ef0f36ecbd2..6fa885a3901 100644 --- a/test/jdk/java/util/Calendar/bug4100311.java +++ b/test/jdk/java/util/Calendar/bug4100311.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -24,24 +24,29 @@ /* * @test * @bug 4100311 - * @summary Make sure set(DAY_OF_YEAR, 1) works. + * @summary Ensure set(DAY_OF_YEAR, 1) works. + * @run junit bug4100311 */ import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Date; -public class bug4100311 -{ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class bug4100311 { + + // GregorianCalendar should be able to date to january 1st properly @SuppressWarnings("deprecation") - public static void main(String args[]) - { + @Test + public void dayOfYearIsOneTest() { GregorianCalendar cal = new GregorianCalendar(); cal.set(Calendar.YEAR, 1997); cal.set(Calendar.DAY_OF_YEAR, 1); - Date d = cal.getTime(); // Should be Jan 1 - if (d.getMonth() != 0 || d.getDate() != 1) { - throw new RuntimeException("Date isn't Jan 1"); - } + Date d = cal.getTime(); + assertEquals(0, d.getMonth(), "Date: "+d+" isn't January 1st"); + assertEquals(1, d.getDate(),"Date: "+d+" isn't January 1st"); } } diff --git a/test/jdk/java/util/Calendar/bug4243802.java b/test/jdk/java/util/Calendar/bug4243802.java index 1f3b910c1b3..a2361317abb 100644 --- a/test/jdk/java/util/Calendar/bug4243802.java +++ b/test/jdk/java/util/Calendar/bug4243802.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -24,70 +24,88 @@ /* * @test * @bug 4243802 - * @summary confirm that Calendar.setTimeInMillis() and - * getTimeInMillis() can be called from a user program. (They used to - * be protected methods.) - * @library /java/text/testlib + * @summary confirm that Calendar.setTimeInMillis() and getTimeInMillis() + * can be called from a user program. They used to be protected methods. + * @run junit bug4243802 */ -import java.util.*; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; -public class bug4243802 extends IntlTest { +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - new bug4243802().run(args); +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class bug4243802 { + + private static final TimeZone savedTz = TimeZone.getDefault(); + private static final Locale savedLocale = Locale.getDefault(); + + // Save JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + } + + // Restore JVM default Locale and TimeZone + @AfterAll + static void tearDownAll() { + Locale.setDefault(savedLocale); + TimeZone.setDefault(savedTz); } - /** - * 4243802: RFE: need way to set the date of a calendar without a Date object + /* + * Test getTimeInMillis() and setTimeInMillis(). Compare a Calendar + * set with a traditional date to one set using setTimeInMillis(), + * where both Calendars should be of equal times. */ - public void Test4243802() { - TimeZone saveZone = TimeZone.getDefault(); - Locale saveLocale = Locale.getDefault(); - try { - Locale.setDefault(Locale.US); - TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + @Test + public void setCalendarWithoutDateTest() { + Calendar cal1 = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); + cal1.clear(); + cal2.clear(); - cal1.clear(); - cal2.clear(); - cal1.set(2001, Calendar.JANUARY, 25, 1, 23, 45); - cal2.setTimeInMillis(cal1.getTimeInMillis()); - if ((cal2.get(Calendar.YEAR) != 2001) || - (cal2.get(Calendar.MONTH) != Calendar.JANUARY) || - (cal2.get(Calendar.DAY_OF_MONTH) != 25) || - (cal2.get(Calendar.HOUR_OF_DAY) != 1) || - (cal2.get(Calendar.MINUTE) != 23) || - (cal2.get(Calendar.SECOND) != 45) || - (cal2.get(Calendar.MILLISECOND) != 0)) { - errln("Failed: expected 1/25/2001 1:23:45.000" + - ", got " + (cal2.get(Calendar.MONTH)+1) + "/" + - cal2.get(Calendar.DAY_OF_MONTH) +"/" + - cal2.get(Calendar.YEAR) + " " + - cal2.get(Calendar.HOUR_OF_DAY) + ":" + - cal2.get(Calendar.MINUTE) + ":" + - cal2.get(Calendar.SECOND) + "." + - toMillis(cal2.get(Calendar.MILLISECOND))); - } - logln("Passed."); - } - finally { - Locale.setDefault(saveLocale); - TimeZone.setDefault(saveZone); - } + cal1.set(2001, Calendar.JANUARY, 25, 1, 23, 45); + // Build the second calendar using the getTimeInMillis of the first + cal2.setTimeInMillis(cal1.getTimeInMillis()); + + assertEquals(2001, cal2.get(Calendar.YEAR), getErrMsg(cal1)); + assertEquals(Calendar.JANUARY, cal2.get(Calendar.MONTH), getErrMsg(cal1)); + assertEquals(25, cal2.get(Calendar.DAY_OF_MONTH), getErrMsg(cal1)); + assertEquals(1, cal2.get(Calendar.HOUR_OF_DAY), getErrMsg(cal1)); + assertEquals(23, cal2.get(Calendar.MINUTE), getErrMsg(cal1)); + assertEquals(45, cal2.get(Calendar.SECOND), getErrMsg(cal1)); + assertEquals(0, cal2.get(Calendar.MILLISECOND), getErrMsg(cal1)); + } + + // Utility to build a long error message + private static String getErrMsg(Calendar cal) { + return "Failed: expected 1/25/2001 1:23:45.000" + + ", got " + (cal.get(Calendar.MONTH)+1) + "/" + + cal.get(Calendar.DAY_OF_MONTH) +"/" + + cal.get(Calendar.YEAR) + " " + + cal.get(Calendar.HOUR_OF_DAY) + ":" + + cal.get(Calendar.MINUTE) + ":" + + cal.get(Calendar.SECOND) + "." + + toMillis(cal.get(Calendar.MILLISECOND)); } - private String toMillis(int m) { - StringBuffer sb = new StringBuffer(); + // Utility to convert value to format of expected milisecond value + private static String toMillis(int m) { + StringBuilder sb = new StringBuilder(); if (m < 100) { sb.append('0'); } if (m < 10) { sb.append('0'); } - sb.append(m); - return sb.toString(); + return sb.append(m).toString(); } } diff --git a/test/jdk/java/util/Calendar/bug4316678.java b/test/jdk/java/util/Calendar/bug4316678.java index 8ae6bbc294f..b455f51e067 100644 --- a/test/jdk/java/util/Calendar/bug4316678.java +++ b/test/jdk/java/util/Calendar/bug4316678.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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 @@ -21,49 +21,62 @@ * questions. */ -import java.io.*; -import java.util.*; -import java.text.*; - -/** +/* * @test * @bug 4316678 - * @summary test that Calendar's Serializasion works correctly. - * @library /java/text/testlib + * @summary test that Calendar's Serialization works correctly. + * @run junit bug4316678 */ -public class bug4316678 extends IntlTest { - public static void main(String[] args) throws Exception { - new bug4316678().run(args); - } +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; - public void Test4316678() throws Exception { - GregorianCalendar gc1; - GregorianCalendar gc2; - TimeZone saveZone = TimeZone.getDefault(); +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class bug4316678 { - try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + private static final String serializedData = "bug4316678.ser"; + private static final TimeZone savedTz = TimeZone.getDefault(); - gc1 = new GregorianCalendar(2000, Calendar.OCTOBER, 10); - try (ObjectOutputStream out - = new ObjectOutputStream(new FileOutputStream("bug4316678.ser"))) { - out.writeObject(gc1); - } + // Save JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + TimeZone.setDefault(TimeZone.getTimeZone("PST")); + } + + // Restore JVM default Locale and TimeZone + @AfterAll + static void tearDownAll() { + TimeZone.setDefault(savedTz); + } - try (ObjectInputStream in - = new ObjectInputStream(new FileInputStream("bug4316678.ser"))) { - gc2 = (GregorianCalendar)in.readObject(); - } + // Test that a serialized GregorianCalendar has the expected values + @Test + public void serializationTest() throws IOException, ClassNotFoundException { + GregorianCalendar gc1 = new GregorianCalendar(2000, Calendar.OCTOBER, 10); + GregorianCalendar gc2; + try (ObjectOutputStream out + = new ObjectOutputStream(new FileOutputStream(serializedData))) { + out.writeObject(gc1); + } - gc1.set(Calendar.DATE, 16); - gc2.set(Calendar.DATE, 16); - if (!gc1.getTime().equals(gc2.getTime())) { - errln("Invalid Time :" + gc2.getTime() + - ", expected :" + gc1.getTime()); - } - } finally { - TimeZone.setDefault(saveZone); + try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(serializedData))) { + gc2 = (GregorianCalendar)in.readObject(); } + + gc1.set(Calendar.DATE, 16); + gc2.set(Calendar.DATE, 16); + assertEquals(gc2.getTime(), gc1.getTime(), + "Times should be equal after serialization"); } } diff --git a/test/jdk/java/util/Calendar/bug4372743.java b/test/jdk/java/util/Calendar/bug4372743.java index 6d380e523e2..da7d20e5cd0 100644 --- a/test/jdk/java/util/Calendar/bug4372743.java +++ b/test/jdk/java/util/Calendar/bug4372743.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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,21 +25,106 @@ * @test * @bug 4372743 * @summary test that checks transitions of ERA and YEAR which are caused by add(MONTH). - * @library /java/text/testlib + * @run junit bug4372743 */ import java.util.GregorianCalendar; import java.util.TimeZone; +import java.util.stream.Stream; -import static java.util.GregorianCalendar.*; +import static java.util.GregorianCalendar.AD; +import static java.util.GregorianCalendar.APRIL; +import static java.util.GregorianCalendar.AUGUST; +import static java.util.GregorianCalendar.BC; +import static java.util.GregorianCalendar.DECEMBER; +import static java.util.GregorianCalendar.ERA; +import static java.util.GregorianCalendar.FEBRUARY; +import static java.util.GregorianCalendar.JANUARY; +import static java.util.GregorianCalendar.JULY; +import static java.util.GregorianCalendar.JUNE; +import static java.util.GregorianCalendar.MARCH; +import static java.util.GregorianCalendar.MAY; +import static java.util.GregorianCalendar.MONTH; +import static java.util.GregorianCalendar.NOVEMBER; +import static java.util.GregorianCalendar.OCTOBER; +import static java.util.GregorianCalendar.SEPTEMBER; +import static java.util.GregorianCalendar.YEAR; -public class bug4372743 extends IntlTest { +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - new bug4372743().run(args); +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class bug4372743 { + + private static final TimeZone savedTz = TimeZone.getDefault(); + + // Save JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + TimeZone.setDefault(TimeZone.getTimeZone("PST")); + } + + // Restore JVM default Locale and TimeZone + @AfterAll + static void tearDownAll() { + TimeZone.setDefault(savedTz); } - private int[][] data = { + /* + * Set GregorianCalendar to (March 3, A.D. 2) and test adding + * to the month field. Ensure that the added field is as expected. + */ + @ParameterizedTest + @MethodSource("A_D_Values") + public void A_D_Test(GregorianCalendar gc, int monthValue) { + for (int i = 0; i < tableSize; i+=(-monthValue)) { + check(gc, i); + gc.add(MONTH, monthValue); + } + } + + // Given in format: (A.D.) GregorianCalendar, amount to add + private static Stream A_D_Values() { + return Stream.of( + Arguments.of(new GregorianCalendar(2, MARCH, 3), -1), + Arguments.of(new GregorianCalendar(2, MARCH, 3), -7)); + } + + /* + * Set GregorianCalendar to (March 10, 2 B.C.) and test adding + * to the month field. Ensure that the added field is as expected. + */ + @ParameterizedTest + @MethodSource("B_C_Values") + public void B_C_Test(GregorianCalendar gc, int monthValue) { + gc.add(YEAR, -3); + for (int i = tableSize - 1; i >= 0; i-=monthValue) { + check(gc, i); + gc.add(MONTH, monthValue); + } + } + + // Given in format: (B.C.) GregorianCalendar, amount to add + private static Stream B_C_Values() { + return Stream.of( + Arguments.of(new GregorianCalendar(2, OCTOBER, 10), 1), + Arguments.of(new GregorianCalendar(2, OCTOBER, 10), 8)); + } + + // Check golden data array with actual value + private void check(GregorianCalendar gc, int index) { + assertEquals(data[index][ERA], gc.get(ERA), "Invalid era"); + assertEquals(data[index][YEAR], gc.get(YEAR), "Invalid year"); + assertEquals(data[index][MONTH], gc.get(MONTH), "Invalid month"); + } + + // Expected ERA, YEAR, and MONTH combinations + private final int[][] data = { {AD, 2, MARCH}, {AD, 2, FEBRUARY}, {AD, 2, JANUARY}, @@ -70,61 +155,5 @@ public static void main(String[] args) throws Exception { {BC, 2, DECEMBER}, {BC, 2, NOVEMBER}, {BC, 2, OCTOBER}}; - private int tablesize = data.length; - - private void check(GregorianCalendar gc, int index) { - if (gc.get(ERA) != data[index][ERA]) { - errln("Invalid era :" + gc.get(ERA) - + ", expected :" + data[index][ERA]); - } - if (gc.get(YEAR) != data[index][YEAR]) { - errln("Invalid year :" + gc.get(YEAR) - + ", expected :" + data[index][YEAR]); - } - if (gc.get(MONTH) != data[index][MONTH]) { - errln("Invalid month :" + gc.get(MONTH) - + ", expected :" + data[index][MONTH]); - } - } - - public void Test4372743() { - GregorianCalendar gc; - TimeZone saveZone = TimeZone.getDefault(); - - try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); - - /* Set March 3, A.D. 2 */ - gc = new GregorianCalendar(2, MARCH, 3); - for (int i = 0; i < tablesize; i++) { - check(gc, i); - gc.add(MONTH, -1); - } - - /* Again, Set March 3, A.D. 2 */ - gc = new GregorianCalendar(2, MARCH, 3); - for (int i = 0; i < tablesize; i += 7) { - check(gc, i); - gc.add(MONTH, -7); - } - - /* Set March 10, 2 B.C. */ - gc = new GregorianCalendar(2, OCTOBER, 10); - gc.add(YEAR, -3); - for (int i = tablesize - 1; i >= 0; i--) { - check(gc, i); - gc.add(MONTH, 1); - } - - /* Again, Set March 10, 2 B.C. */ - gc = new GregorianCalendar(2, OCTOBER, 10); - gc.add(YEAR, -3); - for (int i = tablesize - 1; i >= 0; i -= 8) { - check(gc, i); - gc.add(MONTH, 8); - } - } finally { - TimeZone.setDefault(saveZone); - } - } + private final int tableSize = data.length; } diff --git a/test/jdk/java/util/Calendar/bug4401223.java b/test/jdk/java/util/Calendar/bug4401223.java index 3123181e1a1..15b420c283b 100644 --- a/test/jdk/java/util/Calendar/bug4401223.java +++ b/test/jdk/java/util/Calendar/bug4401223.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -24,73 +24,59 @@ /* * @test * @bug 4401223 - * @summary Make sure that GregorianCalendar doesn't cause IllegalArgumentException at some special situations which are related to the Leap Year. - * @library /java/text/testlib + * @summary Make sure that GregorianCalendar doesn't cause + * IllegalArgumentException at some special situations which are + * related to the Leap Year. + * @run junit bug4401223 */ import java.util.Date; import java.util.GregorianCalendar; -import static java.util.GregorianCalendar.*; +import static java.util.GregorianCalendar.DATE; +import static java.util.GregorianCalendar.DAY_OF_YEAR; +import static java.util.GregorianCalendar.DECEMBER; +import static java.util.GregorianCalendar.FEBRUARY; +import static java.util.GregorianCalendar.MONTH; +import static java.util.GregorianCalendar.YEAR; -public class bug4401223 extends IntlTest { +import org.junit.jupiter.api.Test; - public void Test4401223a() { - int status = 0; - String s = null; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; - try { - @SuppressWarnings("deprecation") - Date date = new Date(2000 - 1900, FEBRUARY, 29); - GregorianCalendar gc = new GregorianCalendar(); +public class bug4401223 { + + // Ensure IAE not thrown for date: 12-29-00 + @SuppressWarnings("deprecation") + @Test + public void checkExceptionTest() { + Date date = new Date(2000 - 1900, FEBRUARY, 29); + GregorianCalendar gc = new GregorianCalendar(); + assertDoesNotThrow(() -> { gc.setTime(date); gc.setLenient(false); gc.set(YEAR, 2001); - s = "02/29/00 & set(YEAR,2001) = " + gc.getTime().toString(); - } catch (Exception ex) { - status++; - s = "Exception occurred for 2/29/00 & set(YEAR,2001): " + ex; - } - if (status > 0) { - errln(s); - } else { - logln(s); - } + }, "Exception occurred for 2/29/00 & set(YEAR,2001)"); } - public void Test4401223b() { - int status = 0; - String s = null; - - try { - @SuppressWarnings("deprecation") - Date date = new Date(2000 - 1900, DECEMBER, 31); - GregorianCalendar gc = new GregorianCalendar(); + // Ensure IAE not thrown for date: 12-31-00. Validate expected values. + @SuppressWarnings("deprecation") + @Test + public void checkExceptionAndValuesTest() { + Date date = new Date(2000 - 1900, DECEMBER, 31); + GregorianCalendar gc = new GregorianCalendar(); + assertDoesNotThrow(() -> { gc.setTime(date); gc.setLenient(false); gc.set(YEAR, 2001); + }, "Exception occurred for 12/31/00 & set(YEAR,2001)"); - if (gc.get(YEAR) != 2001 - || gc.get(MONTH) != DECEMBER - || gc.get(DATE) != 31 - || gc.get(DAY_OF_YEAR) != 365) { - status++; - s = "Wrong Date : 12/31/00 & set(YEAR,2001) ---> " + gc.getTime().toString(); - } else { - s = "12/31/00 & set(YEAR,2001) = " + gc.getTime().toString(); - } - } catch (Exception ex) { - status++; - s = "Exception occurred for 12/31/00 & set(YEAR,2001) : " + ex; - } - if (status > 0) { - errln(s); - } else { - logln(s); - } - } + String errMsg = "Wrong date, got: " + gc.getTime(); - public static void main(String[] args) throws Exception { - new bug4401223().run(args); + assertEquals(2001, gc.get(YEAR), errMsg); + assertEquals(DECEMBER, gc.get(MONTH), errMsg); + assertEquals(31, gc.get(DATE), errMsg); + assertEquals(365, gc.get(DAY_OF_YEAR), errMsg); } } diff --git a/test/jdk/java/util/Calendar/bug4514831.java b/test/jdk/java/util/Calendar/bug4514831.java index f0c34a8aa2a..886c6a0915d 100644 --- a/test/jdk/java/util/Calendar/bug4514831.java +++ b/test/jdk/java/util/Calendar/bug4514831.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -24,77 +24,99 @@ /* * @test * @bug 4514831 - * @summary Confirm that GregorianCalendar.roll() works properly during transition from Daylight Saving Time to Standard Time. + * @summary Confirm that GregorianCalendar.roll() works properly during + * transition from Daylight Saving Time to Standard Time. + * @run junit bug4514831 */ import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; -import static java.util.GregorianCalendar.*; +import static java.util.GregorianCalendar.DAY_OF_MONTH; +import static java.util.GregorianCalendar.DAY_OF_WEEK; +import static java.util.GregorianCalendar.DAY_OF_WEEK_IN_MONTH; +import static java.util.GregorianCalendar.DAY_OF_YEAR; +import static java.util.GregorianCalendar.OCTOBER; +import static java.util.GregorianCalendar.THURSDAY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; -public class bug4514831 { - - public static void main(String[] args) { - Locale savedLocale = Locale.getDefault(); - TimeZone savedTimeZone = TimeZone.getDefault(); - boolean err = false; +import static org.junit.jupiter.api.Assertions.assertEquals; - String golden_data1 = "27-28 28-29 29-30 30-31 31-1 1-2 2-3 "; - String golden_data2 = "27-28 28-29 29-30 30-31 31-25 25-26 26-27 "; - String golden_data3 = "1-8 8-15 15-22 22-29 29-1 1-8 8-15 "; +public class bug4514831 { + // Data of 7 rolls in the form of a string for the respective field + private static final String expectedDayOfYearData = "27-28 28-29 29-30 30-31 31-1 1-2 2-3 "; + private static final String expectedDayOfWeekData = "27-28 28-29 29-30 30-31 31-25 25-26 26-27 "; + private static final String expectedDayOfWeekInMonthData = "1-8 8-15 15-22 22-29 29-1 1-8 8-15 "; + private static final TimeZone savedTz = TimeZone.getDefault(); + private static final Locale savedLocale = Locale.getDefault(); - try { - Locale.setDefault(Locale.US); - TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific")); + // Save JVM default Locale and TimeZone + @BeforeAll + void initAll() { + Locale.setDefault(Locale.US); + TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific")); + } - String test_roll = ""; - GregorianCalendar c_roll = new GregorianCalendar(2001, OCTOBER, 27); - for (int i = 0; i < 7; i++) { - test_roll += c_roll.get(DAY_OF_MONTH) + "-"; - c_roll.roll(DAY_OF_YEAR, true); - test_roll += c_roll.get(DAY_OF_MONTH) + " "; - } - if (!test_roll.equals(golden_data1)) { - err = true; - System.err.println("Wrong roll(DAY_OF_YEAR) transition: got " - + test_roll + "expected " + golden_data1); - } + // Restore JVM default Locale and TimeZone + @AfterAll + void tearDownAll() { + Locale.setDefault(savedLocale); + TimeZone.setDefault(savedTz); + } - test_roll = ""; - c_roll = new GregorianCalendar(2001, OCTOBER, 27); - c_roll.setFirstDayOfWeek(THURSDAY); - for (int i = 0; i < 7; i++) { - test_roll += c_roll.get(DAY_OF_MONTH) + "-"; - c_roll.roll(DAY_OF_WEEK, true); - test_roll += c_roll.get(DAY_OF_MONTH) + " "; - } - if (!test_roll.equals(golden_data2)) { - err = true; - System.err.println("Wrong roll(DAY_OF_WEEK) transition: got " - + test_roll + "expected " + golden_data2); - } + /* + * Test some roll values during transition (DAY_OF_YEAR field). Uses + * the boolean roll method. Roll multiple times and attach the returned + * values to a long string which is then compared to the expected data. + */ + public void rollDayOfYearTest() { + StringBuilder actualRollData = new StringBuilder(); + GregorianCalendar cal = new GregorianCalendar(2001, OCTOBER, 27); + for (int i = 0; i < 7; i++) { + actualRollData.append(cal.get(DAY_OF_MONTH)).append("-"); + cal.roll(DAY_OF_YEAR, true); + actualRollData.append(cal.get(DAY_OF_MONTH)).append(" "); + } + assertEquals(expectedDayOfYearData, actualRollData.toString(), + "Wrong roll(DAY_OF_YEAR) transition"); + } - test_roll = ""; - c_roll = new GregorianCalendar(2001, OCTOBER, 1); - for (int i = 0; i < 7; i++) { - test_roll += c_roll.get(DAY_OF_MONTH) + "-"; - c_roll.roll(DAY_OF_WEEK_IN_MONTH, true); - test_roll += c_roll.get(DAY_OF_MONTH) + " "; - } - if (!test_roll.equals(golden_data3)) { - err = true; - System.err.println("Wrong roll(DAY_OF_WEEK_IN_MONTH) transition: got " - + test_roll + "expected " + golden_data3); - } - } finally { - Locale.setDefault(savedLocale); - TimeZone.setDefault(savedTimeZone); + /* + * Test some roll values during transition (DAY_OF_WEEK field). Uses + * the boolean roll method. Roll multiple times and attach the returned + * values to a long string which is then compared to the expected data. + */ + public void rollDayOfWeekTest() { + StringBuilder actualRollData = new StringBuilder(); + GregorianCalendar cal = new GregorianCalendar(2001, OCTOBER, 27); + cal.setFirstDayOfWeek(THURSDAY); + for (int i = 0; i < 7; i++) { + actualRollData.append(cal.get(DAY_OF_MONTH)).append("-"); + cal.roll(DAY_OF_WEEK, true); + actualRollData.append(cal.get(DAY_OF_MONTH)).append(" "); } + assertEquals(expectedDayOfWeekData, actualRollData.toString(), + "Wrong roll(DAY_OF_WEEK) transition"); + } - if (err) { - throw new RuntimeException("Wrong roll() transition"); + /* + * Test some roll values during transition (DAY_OF_WEEK_IN_MONTH field). Uses + * the boolean roll method. Roll multiple times and attach the returned + * values to a long string which is then compared to the expected data. + */ + public void rollDayOfWeekInMonthTest() { + StringBuilder actualRollData = new StringBuilder(); + GregorianCalendar cal = new GregorianCalendar(2001, OCTOBER, 1); + for (int i = 0; i < 7; i++) { + actualRollData.append(cal.get(DAY_OF_MONTH)).append("-"); + cal.roll(DAY_OF_WEEK_IN_MONTH, true); + actualRollData.append(cal.get(DAY_OF_MONTH)).append(" "); } + assertEquals(expectedDayOfWeekInMonthData, actualRollData.toString(), + "Wrong roll(DAY_OF_WEEK_IN_MONTH) transition"); } } From 5762df6f816da7c5e76df54bc44c75e957ab46e2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 14 Mar 2024 20:16:38 +0000 Subject: [PATCH 070/298] 8321489: Update LCMS to 2.16 Backport-of: dc7d3b182d226253ca246dd854c85c4dd964f10e --- src/java.desktop/share/legal/lcms.md | 39 +- .../share/native/liblcms/cmsalpha.c | 26 +- .../share/native/liblcms/cmscgats.c | 487 ++++++++++++++---- .../share/native/liblcms/cmscnvrt.c | 41 +- .../share/native/liblcms/cmserr.c | 7 +- .../share/native/liblcms/cmsgamma.c | 28 +- .../share/native/liblcms/cmsgmt.c | 4 +- .../share/native/liblcms/cmsio0.c | 27 +- .../share/native/liblcms/cmsio1.c | 12 +- .../share/native/liblcms/cmslut.c | 11 +- .../share/native/liblcms/cmsnamed.c | 250 ++++++++- .../share/native/liblcms/cmsopt.c | 14 +- .../share/native/liblcms/cmspack.c | 185 ++++++- .../share/native/liblcms/cmsplugin.c | 21 +- .../share/native/liblcms/cmsps2.c | 187 +++---- .../share/native/liblcms/cmssamp.c | 2 +- .../share/native/liblcms/cmstypes.c | 271 +++++++++- .../share/native/liblcms/cmsvirt.c | 137 ++++- .../share/native/liblcms/cmsxform.c | 15 +- src/java.desktop/share/native/liblcms/lcms2.h | 53 +- .../share/native/liblcms/lcms2_internal.h | 7 +- 21 files changed, 1465 insertions(+), 359 deletions(-) diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md index da86a9c47ca..02af4fff000 100644 --- a/src/java.desktop/share/legal/lcms.md +++ b/src/java.desktop/share/legal/lcms.md @@ -1,34 +1,29 @@ -## Little Color Management System (LCMS) v2.15 +## Little Color Management System (LCMS) v2.16 ### LCMS License

    -README.1ST file information
     
    -LittleCMS core is released under MIT License
    +MIT License
     
    ----------------------------------
    -
    -Little CMS
    -Copyright (c) 1998-2023 Marti Maria Saguer
    +Copyright (C) 1998-2023 Marti Maria Saguer
     
     Permission is hereby granted, free of charge, to any person obtaining
    -a copy of this software and associated documentation files (the
    -"Software"), to deal in the Software without restriction, including
    -without limitation the rights to use, copy, modify, merge, publish,
    -distribute, sublicense, and/or sell copies of the Software, and to
    -permit persons to whom the Software is furnished to do so, subject
    -to the following conditions:
    +a copy of this software and associated documentation files (the "Software"),
    +to deal in the Software without restriction, including without limitation
    +the rights to use, copy, modify, merge, publish, distribute, sublicense,
    +and/or sell copies of the Software, and to permit persons to whom the Software
    +is furnished to do so, subject to the following conditions:
     
    -The above copyright notice and this permission notice shall be
    -included in all copies or substantial portions of the Software.
    +The above copyright notice and this permission notice shall be included in
    +all copies or substantial portions of the Software.
     
     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     
     ---------------------------------
     The below license applies to the following files:
    @@ -47,7 +42,6 @@ Users of this code must verify correctness for their application.
     ### AUTHORS File Information
     ```
     
    -
     Main Author
     ------------
     Marti Maria
    @@ -91,6 +85,7 @@ Philipp Knechtges
     Amyspark
     Lovell Fuller
     Eli Schwartz
    +Diogo Teles Sant'Anna
     
     Special Thanks
     --------------
    diff --git a/src/java.desktop/share/native/liblcms/cmsalpha.c b/src/java.desktop/share/native/liblcms/cmsalpha.c
    index e69259e8a51..78d3ca6b671 100644
    --- a/src/java.desktop/share/native/liblcms/cmsalpha.c
    +++ b/src/java.desktop/share/native/liblcms/cmsalpha.c
    @@ -431,7 +431,7 @@ static cmsFormatterAlphaFn FormattersAlpha[6][6] = {
     
     // This function computes the distance from each component to the next one in bytes.
     static
    -void ComputeIncrementsForChunky(cmsUInt32Number Format,
    +cmsBool ComputeIncrementsForChunky(cmsUInt32Number Format,
                                     cmsUInt32Number ComponentStartingOrder[],
                                     cmsUInt32Number ComponentPointerIncrements[])
     {
    @@ -445,7 +445,7 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
     
            // Sanity check
            if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
    -           return;
    +           return FALSE;
     
             memset(channels, 0, sizeof(channels));
     
    @@ -482,13 +482,15 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
     
            for (i = 0; i < extra; i++)
                   ComponentStartingOrder[i] = channels[i + nchannels];
    +
    +       return TRUE;
     }
     
     
     
     //  On planar configurations, the distance is the stride added to any non-negative
     static
    -void ComputeIncrementsForPlanar(cmsUInt32Number Format,
    +cmsBool ComputeIncrementsForPlanar(cmsUInt32Number Format,
                                     cmsUInt32Number BytesPerPlane,
                                     cmsUInt32Number ComponentStartingOrder[],
                                     cmsUInt32Number ComponentPointerIncrements[])
    @@ -502,7 +504,7 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
     
            // Sanity check
            if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
    -           return;
    +           return FALSE;
     
            memset(channels, 0, sizeof(channels));
     
    @@ -538,29 +540,29 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
     
            for (i = 0; i < extra; i++)
                   ComponentStartingOrder[i] = channels[i + nchannels];
    +
    +       return TRUE;
     }
     
     
     
     // Dispatcher por chunky and planar RGB
     static
    -void  ComputeComponentIncrements(cmsUInt32Number Format,
    +cmsBool ComputeComponentIncrements(cmsUInt32Number Format,
                                      cmsUInt32Number BytesPerPlane,
                                      cmsUInt32Number ComponentStartingOrder[],
                                      cmsUInt32Number ComponentPointerIncrements[])
     {
            if (T_PLANAR(Format)) {
     
    -              ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
    +              return ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
            }
            else {
    -              ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
    +              return ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
            }
     
     }
     
    -
    -
     // Handles extra channels copying alpha if requested by the flags
     void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
                                                    void* out,
    @@ -595,8 +597,10 @@ void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
             return;
     
         // Compute the increments
    -    ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
    -    ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
    +    if (!ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements))
    +        return;
    +    if (!ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements))
    +        return;
     
         // Check for conversions 8, 16, half, float, dbl
         copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
    diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
    index 9d0aea27d73..57725ae4731 100644
    --- a/src/java.desktop/share/native/liblcms/cmscgats.c
    +++ b/src/java.desktop/share/native/liblcms/cmscgats.c
    @@ -87,7 +87,7 @@ typedef enum {
             SEOF,       // End of stream
             SSYNERROR,  // Syntax error found on stream
     
    -        // Keywords
    +        // IT8 symbols
     
             SBEGIN_DATA,
             SBEGIN_DATA_FORMAT,
    @@ -95,7 +95,19 @@ typedef enum {
             SEND_DATA_FORMAT,
             SKEYWORD,
             SDATA_FORMAT_ID,
    -        SINCLUDE
    +        SINCLUDE,
    +
    +        // Cube symbols
    +
    +        SDOMAIN_MAX,
    +        SDOMAIN_MIN,
    +        S_LUT1D_SIZE,
    +        S_LUT1D_INPUT_RANGE,
    +        S_LUT3D_SIZE,
    +        S_LUT3D_INPUT_RANGE,
    +        S_LUT_IN_VIDEO_RANGE,
    +        S_LUT_OUT_VIDEO_RANGE,
    +        STITLE
     
         } SYMBOL;
     
    @@ -178,6 +190,10 @@ typedef struct struct_it8 {
             cmsUInt32Number  TablesCount;                     // How many tables in this stream
             cmsUInt32Number  nTable;                          // The actual table
     
    +        // Partser type
    +        cmsBool        IsCUBE;
    +
    +        // Tables
             TABLE Tab[MAXTABLES];
     
             // Memory management
    @@ -237,8 +253,8 @@ typedef struct {
     
        } KEYWORD;
     
    -// The keyword->symbol translation table. Sorting is required.
    -static const KEYWORD TabKeys[] = {
    +// The keyword->symbol translation tables. Sorting is required.
    +static const KEYWORD TabKeysIT8[] = {
     
             {"$INCLUDE",               SINCLUDE},   // This is an extension!
             {".INCLUDE",               SINCLUDE},   // This is an extension!
    @@ -251,7 +267,25 @@ static const KEYWORD TabKeys[] = {
             {"KEYWORD",                SKEYWORD}
             };
     
    -#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
    +#define NUMKEYS_IT8 (sizeof(TabKeysIT8)/sizeof(KEYWORD))
    +
    +static const KEYWORD TabKeysCUBE[] = {
    +
    +        {"DOMAIN_MAX",             SDOMAIN_MAX },
    +        {"DOMAIN_MIN",             SDOMAIN_MIN },
    +        {"LUT_1D_SIZE",            S_LUT1D_SIZE },
    +        {"LUT_1D_INPUT_RANGE",     S_LUT1D_INPUT_RANGE },
    +        {"LUT_3D_SIZE",            S_LUT3D_SIZE },
    +        {"LUT_3D_INPUT_RANGE",     S_LUT3D_INPUT_RANGE },
    +        {"LUT_IN_VIDEO_RANGE",     S_LUT_IN_VIDEO_RANGE },
    +        {"LUT_OUT_VIDEO_RANGE",    S_LUT_OUT_VIDEO_RANGE },
    +        {"TITLE",                  STITLE }
    +
    +};
    +
    +#define NUMKEYS_CUBE (sizeof(TabKeysCUBE)/sizeof(KEYWORD))
    +
    +
     
     // Predefined properties
     
    @@ -455,7 +489,7 @@ void StringCat(string* s, const char* c)
     static
     cmsBool isseparator(int c)
     {
    -    return (c == ' ') || (c == '\t') ;
    +    return (c == ' ') || (c == '\t');
     }
     
     // Checks whatever c is a valid identifier char
    @@ -476,7 +510,7 @@ cmsBool isidchar(int c)
     static
     cmsBool isfirstidchar(int c)
     {
    -     return !isdigit(c) && ismiddle(c);
    +     return c != '-' && !isdigit(c) && ismiddle(c);
     }
     
     // Guess whether the supplied path looks like an absolute path
    @@ -515,13 +549,13 @@ cmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffe
         // Already absolute?
         if (isabsolutepath(relPath)) {
     
    -        strncpy(buffer, relPath, MaxLen);
    +        memcpy(buffer, relPath, MaxLen);
             buffer[MaxLen-1] = 0;
             return TRUE;
         }
     
         // No, search for last
    -    strncpy(buffer, basePath, MaxLen);
    +    memcpy(buffer, basePath, MaxLen);
         buffer[MaxLen-1] = 0;
     
         tail = strrchr(buffer, DIR_CHAR);
    @@ -603,10 +637,10 @@ void NextCh(cmsIT8* it8)
     
     // Try to see if current identifier is a keyword, if so return the referred symbol
     static
    -SYMBOL BinSrchKey(const char *id)
    +SYMBOL BinSrchKey(const char *id, int NumKeys, const KEYWORD* TabKeys)
     {
         int l = 1;
    -    int r = NUMKEYS;
    +    int r = NumKeys;
         int x, res;
     
         while (r >= l)
    @@ -776,7 +810,7 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
     }
     
     
    -// Reads a string, special case to avoid infinite resursion on .include
    +// Reads a string, special case to avoid infinite recursion on .include
     static
     void InStringSymbol(cmsIT8* it8)
     {
    @@ -833,7 +867,9 @@ void InSymbol(cmsIT8* it8)
                 } while (isidchar(it8->ch));
     
     
    -            key = BinSrchKey(StringPtr(it8->id));
    +            key = BinSrchKey(StringPtr(it8->id),
    +                    it8->IsCUBE ? NUMKEYS_CUBE : NUMKEYS_IT8,
    +                    it8->IsCUBE ? TabKeysCUBE : TabKeysIT8);
                 if (key == SUNDEFINED) it8->sy = SIDENT;
                 else it8->sy = key;
     
    @@ -942,6 +978,7 @@ void InSymbol(cmsIT8* it8)
                             snprintf(buffer, sizeof(buffer), it8 ->DoubleFormatter, it8->dnum);
                         }
     
    +                    StringClear(it8->id);
                         StringCat(it8->id, buffer);
     
                         do {
    @@ -971,7 +1008,7 @@ void InSymbol(cmsIT8* it8)
             // Next line
             case '\r':
                 NextCh(it8);
    -            if (it8 ->ch == '\n')
    +            if (it8->ch == '\n')
                     NextCh(it8);
                 it8->sy = SEOLN;
                 it8->lineno++;
    @@ -1292,7 +1329,12 @@ KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *S
     
             // This may work for editing properties
     
    -        //     return SynError(it8, "duplicate key <%s>", Key);
    +        if (cmsstrcasecmp(Key, "NUMBER_OF_FIELDS") == 0 ||
    +            cmsstrcasecmp(Key, "NUMBER_OF_SETS") == 0) {
    +
    +            SynError(it8, "duplicate key <%s>", Key);
    +            return NULL;
    +        }
         }
         else {
     
    @@ -1413,6 +1455,8 @@ cmsHANDLE  CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
         it8->MemoryBlock = NULL;
         it8->MemorySink  = NULL;
     
    +    it8->IsCUBE = FALSE;
    +
         it8 ->nTable = 0;
     
         it8->ContextID = ContextID;
    @@ -1694,7 +1738,7 @@ char* GetData(cmsIT8* it8, int nSet, int nField)
         int nSamples    = t -> nSamples;
         int nPatches    = t -> nPatches;
     
    -    if (nSet >= nPatches || nField >= nSamples)
    +    if (nSet < 0 || nSet >= nPatches || nField < 0 || nField >= nSamples)
             return NULL;
     
         if (!t->Data) return NULL;
    @@ -1879,11 +1923,14 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
            WriteStr(fp, " ");
            nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
     
    -       for (i = 0; i < nSamples; i++) {
    +       if (nSamples <= t->nSamples) {
     
    -              WriteStr(fp, t->DataFormat[i]);
    -              WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
    -          }
    +           for (i = 0; i < nSamples; i++) {
    +
    +               WriteStr(fp, t->DataFormat[i]);
    +               WriteStr(fp, ((i == (nSamples - 1)) ? "\n" : "\t"));
    +           }
    +       }
     
            WriteStr (fp, "END_DATA_FORMAT\n");
     }
    @@ -1893,39 +1940,42 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
     static
     void WriteData(SAVESTREAM* fp, cmsIT8* it8)
     {
    -       int  i, j;
    +       int  i, j, nPatches;
            TABLE* t = GetTable(it8);
     
            if (!t->Data) return;
     
            WriteStr (fp, "BEGIN_DATA\n");
     
    -       t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
    +       nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
     
    -       for (i = 0; i < t-> nPatches; i++) {
    +       if (nPatches <= t->nPatches) {
     
    -              WriteStr(fp, " ");
    +           for (i = 0; i < nPatches; i++) {
     
    -              for (j = 0; j < t->nSamples; j++) {
    +               WriteStr(fp, " ");
     
    -                     char *ptr = t->Data[i*t->nSamples+j];
    +               for (j = 0; j < t->nSamples; j++) {
     
    -                     if (ptr == NULL) WriteStr(fp, "\"\"");
    -                     else {
    -                         // If value contains whitespace, enclose within quote
    +                   char* ptr = t->Data[i * t->nSamples + j];
     
    -                         if (strchr(ptr, ' ') != NULL) {
    +                   if (ptr == NULL) WriteStr(fp, "\"\"");
    +                   else {
    +                       // If value contains whitespace, enclose within quote
     
    -                             WriteStr(fp, "\"");
    -                             WriteStr(fp, ptr);
    -                             WriteStr(fp, "\"");
    -                         }
    -                         else
    -                            WriteStr(fp, ptr);
    -                     }
    +                       if (strchr(ptr, ' ') != NULL) {
     
    -                     WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t"));
    -              }
    +                           WriteStr(fp, "\"");
    +                           WriteStr(fp, ptr);
    +                           WriteStr(fp, "\"");
    +                       }
    +                       else
    +                           WriteStr(fp, ptr);
    +                   }
    +
    +                   WriteStr(fp, ((j == (t->nSamples - 1)) ? "\n" : "\t"));
    +               }
    +           }
            }
            WriteStr (fp, "END_DATA\n");
     }
    @@ -1946,15 +1996,29 @@ cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName)
     
         for (i=0; i < it8 ->TablesCount; i++) {
     
    -            cmsIT8SetTable(hIT8, i);
    -            WriteHeader(it8, &sd);
    -            WriteDataFormat(&sd, it8);
    -            WriteData(&sd, it8);
    +        TABLE* t;
    +
    +        if (cmsIT8SetTable(hIT8, i) < 0) goto Error;
    +
    +        /**
    +        * Check for wrong data
    +        */
    +        t = GetTable(it8);
    +        if (t->Data == NULL) goto Error;
    +        if (t->DataFormat == NULL) goto Error;
    +
    +        WriteHeader(it8, &sd);
    +        WriteDataFormat(&sd, it8);
    +        WriteData(&sd, it8);
         }
     
         if (fclose(sd.stream) != 0) return FALSE;
    -
         return TRUE;
    +
    +Error:
    +    fclose(sd.stream);
    +    return FALSE;
    +
     }
     
     
    @@ -2331,78 +2395,72 @@ void CookPointers(cmsIT8* it8)
         int idField, i;
         char* Fld;
         cmsUInt32Number j;
    -    cmsUInt32Number nOldTable = it8 ->nTable;
    +    cmsUInt32Number nOldTable = it8->nTable;
     
    -    for (j=0; j < it8 ->TablesCount; j++) {
    +    for (j = 0; j < it8->TablesCount; j++) {
     
    -    TABLE* t = it8 ->Tab + j;
    +        TABLE* t = it8->Tab + j;
     
    -    t -> SampleID = 0;
    -    it8 ->nTable = j;
    +        t->SampleID = 0;
    +        it8->nTable = j;
     
    -    for (idField = 0; idField < t -> nSamples; idField++)
    -    {
    -        if (t ->DataFormat == NULL){
    -            SynError(it8, "Undefined DATA_FORMAT");
    -            return;
    -        }
    +        for (idField = 0; idField < t->nSamples; idField++)
    +        {
    +            if (t->DataFormat == NULL) {
    +                SynError(it8, "Undefined DATA_FORMAT");
    +                return;
    +            }
     
    -        Fld = t->DataFormat[idField];
    -        if (!Fld) continue;
    +            Fld = t->DataFormat[idField];
    +            if (!Fld) continue;
     
     
    -        if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
    +            if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
     
    -            t -> SampleID = idField;
    -        }
    +                t->SampleID = idField;
    +            }
     
    -        // "LABEL" is an extension. It keeps references to forward tables
    +            // "LABEL" is an extension. It keeps references to forward tables
     
    -        if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
    +            if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
     
    -            // Search for table references...
    -            for (i = 0; i < t->nPatches; i++) {
    +                // Search for table references...
    +                for (i = 0; i < t->nPatches; i++) {
     
    -                char* Label = GetData(it8, i, idField);
    +                    char* Label = GetData(it8, i, idField);
     
    -                if (Label) {
    +                    if (Label) {
     
    -                    cmsUInt32Number k;
    +                        cmsUInt32Number k;
     
    -                    // This is the label, search for a table containing
    -                    // this property
    +                        // This is the label, search for a table containing
    +                        // this property
     
    -                    for (k = 0; k < it8->TablesCount; k++) {
    +                        for (k = 0; k < it8->TablesCount; k++) {
     
    -                        TABLE* Table = it8->Tab + k;
    -                        KEYVALUE* p;
    +                            TABLE* Table = it8->Tab + k;
    +                            KEYVALUE* p;
     
    -                        if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
    +                            if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
     
    -                            // Available, keep type and table
    -                            char Buffer[256];
    +                                // Available, keep type and table
    +                                char Buffer[256];
     
    -                            char* Type = p->Value;
    -                            int  nTable = (int)k;
    +                                char* Type = p->Value;
    +                                int  nTable = (int)k;
     
    -                            snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
    +                                snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
     
    -                            SetData(it8, i, idField, Buffer);
    +                                SetData(it8, i, idField, Buffer);
    +                            }
                             }
                         }
    -
    -
                     }
    -
                 }
    -
    -
             }
    -
    -    }
         }
     
    -    it8 ->nTable = nOldTable;
    +    it8->nTable = nOldTable;
     }
     
     // Try to infere if the file is a CGATS/IT8 file at all. Read first line
    @@ -2493,7 +2551,7 @@ cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
         if (it8->MemoryBlock == NULL)
         {
             cmsIT8Free(hIT8);
    -        return FALSE;
    +        return NULL;
         }
     
         strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
    @@ -2505,7 +2563,7 @@ cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
         if (!ParseIT8(it8, type-1)) {
     
             cmsIT8Free(hIT8);
    -        return FALSE;
    +        return NULL;
         }
     
         CookPointers(it8);
    @@ -2602,17 +2660,17 @@ cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyN
         }
     
     
    -        Props = (char**)AllocChunk(it8, sizeof(char*) * n);
    -        if (Props != NULL) {
    -
    -                // Pass#2 - Fill pointers
    -                n = 0;
    -                for (p = t->HeaderList; p != NULL; p = p->Next) {
    -                        Props[n++] = p->Keyword;
    -                }
    +    Props = (char**)AllocChunk(it8, sizeof(char*) * n);
    +    if (Props != NULL) {
     
    +        // Pass#2 - Fill pointers
    +        n = 0;
    +        for (p = t->HeaderList; p != NULL; p = p->Next) {
    +            Props[n++] = p->Keyword;
             }
    -        *PropertyNames = Props;
    +
    +    }
    +    *PropertyNames = Props;
     
         return n;
     }
    @@ -2972,3 +3030,236 @@ void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter)
         it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
     }
     
    +
    +static
    +cmsBool ReadNumbers(cmsIT8* cube, int n, cmsFloat64Number* arr)
    +{
    +    int i;
    +
    +    for (i = 0; i < n; i++) {
    +
    +        if (cube->sy == SINUM)
    +            arr[i] = cube->inum;
    +        else
    +            if (cube->sy == SDNUM)
    +                arr[i] = cube->dnum;
    +            else
    +                return SynError(cube, "Number expected");
    +
    +        InSymbol(cube);
    +    }
    +
    +    return CheckEOLN(cube);
    +}
    +
    +static
    +cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[])
    +{
    +    cmsFloat64Number domain_min[3] = { 0, 0, 0 };
    +    cmsFloat64Number domain_max[3] = { 1.0, 1.0, 1.0 };
    +    cmsFloat64Number check_0_1[2] = { 0, 1.0 };
    +    int shaper_size = 0;
    +    int lut_size = 0;
    +    int i;
    +
    +    InSymbol(cube);
    +
    +    while (cube->sy != SEOF) {
    +        switch (cube->sy)
    +        {
    +        // Set profile description
    +        case STITLE:
    +            InSymbol(cube);
    +            if (!Check(cube, SSTRING, "Title string expected")) return FALSE;
    +            memcpy(title, StringPtr(cube->str), MAXSTR);
    +            title[MAXSTR - 1] = 0;
    +            InSymbol(cube);
    +            break;
    +
    +        // Define domain
    +        case SDOMAIN_MIN:
    +            InSymbol(cube);
    +            if (!ReadNumbers(cube, 3, domain_min)) return FALSE;
    +            break;
    +
    +        case SDOMAIN_MAX:
    +            InSymbol(cube);
    +            if (!ReadNumbers(cube, 3, domain_max)) return FALSE;
    +            break;
    +
    +        // Define shaper
    +        case S_LUT1D_SIZE:
    +            InSymbol(cube);
    +            if (!Check(cube, SINUM, "Shaper size expected")) return FALSE;
    +            shaper_size = cube->inum;
    +            InSymbol(cube);
    +            break;
    +
    +        // Deefine CLUT
    +        case S_LUT3D_SIZE:
    +            InSymbol(cube);
    +            if (!Check(cube, SINUM, "LUT size expected")) return FALSE;
    +            lut_size = cube->inum;
    +            InSymbol(cube);
    +            break;
    +
    +        // Range. If present, has to be 0..1.0
    +        case S_LUT1D_INPUT_RANGE:
    +        case S_LUT3D_INPUT_RANGE:
    +            InSymbol(cube);
    +            if (!ReadNumbers(cube, 2, check_0_1)) return FALSE;
    +            if (check_0_1[0] != 0 || check_0_1[1] != 1.0) {
    +                return SynError(cube, "Unsupported format");
    +            }
    +            break;
    +
    +        case SEOLN:
    +            InSymbol(cube);
    +            break;
    +
    +        default:
    +        case S_LUT_IN_VIDEO_RANGE:
    +        case S_LUT_OUT_VIDEO_RANGE:
    +            return SynError(cube, "Unsupported format");
    +
    +            // Read and create tables
    +        case SINUM:
    +        case SDNUM:
    +
    +            if (shaper_size > 0) {
    +
    +                cmsToneCurve* curves[3];
    +                cmsFloat32Number* shapers = (cmsFloat32Number*)_cmsMalloc(cube->ContextID, 3 * shaper_size * sizeof(cmsFloat32Number));
    +                if (shapers == NULL) return FALSE;
    +
    +                for (i = 0; i < shaper_size; i++) {
    +
    +                    cmsFloat64Number nums[3];
    +
    +                    if (!ReadNumbers(cube, 3, nums)) return FALSE;
    +
    +                    shapers[i + 0]               = (cmsFloat32Number) ((nums[0] - domain_min[0]) / (domain_max[0] - domain_min[0]));
    +                    shapers[i + 1 * shaper_size] = (cmsFloat32Number) ((nums[1] - domain_min[1]) / (domain_max[1] - domain_min[1]));
    +                    shapers[i + 2 * shaper_size] = (cmsFloat32Number) ((nums[2] - domain_min[2]) / (domain_max[2] - domain_min[2]));
    +                }
    +
    +                for (i = 0; i < 3; i++) {
    +
    +                    curves[i] = cmsBuildTabulatedToneCurveFloat(cube->ContextID, shaper_size,
    +                        &shapers[i * shaper_size]);
    +                    if (curves[i] == NULL) return FALSE;
    +                }
    +
    +                *Shaper = cmsStageAllocToneCurves(cube->ContextID, 3, curves);
    +
    +                cmsFreeToneCurveTriple(curves);
    +            }
    +
    +            if (lut_size > 0) {
    +
    +                int nodes = lut_size * lut_size * lut_size;
    +
    +                cmsFloat32Number* lut_table = _cmsMalloc(cube->ContextID, nodes * 3 * sizeof(cmsFloat32Number));
    +                if (lut_table == NULL) return FALSE;
    +
    +                for (i = 0; i < nodes; i++) {
    +
    +                    cmsFloat64Number nums[3];
    +
    +                    if (!ReadNumbers(cube, 3, nums)) return FALSE;
    +
    +                    lut_table[i * 3 + 2] = (cmsFloat32Number) ((nums[0] - domain_min[0]) / (domain_max[0] - domain_min[0]));
    +                    lut_table[i * 3 + 1] = (cmsFloat32Number) ((nums[1] - domain_min[1]) / (domain_max[1] - domain_min[1]));
    +                    lut_table[i * 3 + 0] = (cmsFloat32Number) ((nums[2] - domain_min[2]) / (domain_max[2] - domain_min[2]));
    +                }
    +
    +                *CLUT = cmsStageAllocCLutFloat(cube->ContextID, lut_size, 3, 3, lut_table);
    +                _cmsFree(cube->ContextID, lut_table);
    +            }
    +
    +            if (!Check(cube, SEOF, "Extra symbols found in file")) return FALSE;
    +        }
    +    }
    +
    +    return TRUE;
    +}
    +
    +// Share the parser to read .cube format and create RGB devicelink profiles
    +cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, const char* cFileName)
    +{
    +    cmsHPROFILE hProfile = NULL;
    +    cmsIT8* cube = NULL;
    +    cmsPipeline* Pipeline = NULL;
    +    cmsStage* CLUT = NULL;
    +    cmsStage* Shaper = NULL;
    +    cmsMLU* DescriptionMLU = NULL;
    +    char title[MAXSTR];
    +
    +    _cmsAssert(cFileName != NULL);
    +
    +    cube = (cmsIT8*) cmsIT8Alloc(ContextID);
    +    if (!cube) return NULL;
    +
    +    cube->IsCUBE = TRUE;
    +    cube->FileStack[0]->Stream = fopen(cFileName, "rt");
    +
    +    if (!cube->FileStack[0]->Stream) goto Done;
    +
    +    strncpy(cube->FileStack[0]->FileName, cFileName, cmsMAX_PATH - 1);
    +    cube->FileStack[0]->FileName[cmsMAX_PATH - 1] = 0;
    +
    +    if (!ParseCube(cube, &Shaper, &CLUT, title)) goto Done;
    +
    +    // Success on parsing, let's create the profile
    +    hProfile = cmsCreateProfilePlaceholder(ContextID);
    +    if (!hProfile) goto Done;
    +
    +    cmsSetProfileVersion(hProfile, 4.4);
    +
    +    cmsSetDeviceClass(hProfile, cmsSigLinkClass);
    +    cmsSetColorSpace(hProfile,  cmsSigRgbData);
    +    cmsSetPCS(hProfile,         cmsSigRgbData);
    +
    +    cmsSetHeaderRenderingIntent(hProfile, INTENT_PERCEPTUAL);
    +
    +    // Creates a Pipeline to hold CLUT and shaper
    +    Pipeline = cmsPipelineAlloc(ContextID, 3, 3);
    +    if (Pipeline == NULL) goto Done;
    +
    +    // Populates the pipeline
    +    if (Shaper != NULL) {
    +        if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper))
    +            goto Done;
    +    }
    +
    +    if (CLUT != NULL) {
    +        if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT))
    +            goto Done;
    +    }
    +
    +    // Propagate the description. We put no copyright because we know
    +    // nothing on the copyrighted state of the .cube
    +    DescriptionMLU = cmsMLUalloc(ContextID, 1);
    +    if (!cmsMLUsetUTF8(DescriptionMLU, cmsNoLanguage, cmsNoCountry, title)) goto Done;
    +
    +    // Flush the tags
    +    if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Done;
    +    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, (void*)Pipeline)) goto Done;
    +
    +Done:
    +
    +    if (DescriptionMLU != NULL)
    +        cmsMLUfree(DescriptionMLU);
    +
    +    if (Pipeline != NULL)
    +        cmsPipelineFree(Pipeline);
    +
    +    cmsIT8Free((cmsHANDLE) cube);
    +
    +    return hProfile;
    +}
    +
    +cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFile(const char* cFileName)
    +{
    +    return cmsCreateDeviceLinkFromCubeFileTHR(NULL, cFileName);
    +}
    diff --git a/src/java.desktop/share/native/liblcms/cmscnvrt.c b/src/java.desktop/share/native/liblcms/cmscnvrt.c
    index b73d594f2ec..d18865b15b9 100644
    --- a/src/java.desktop/share/native/liblcms/cmscnvrt.c
    +++ b/src/java.desktop/share/native/liblcms/cmscnvrt.c
    @@ -263,7 +263,7 @@ cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad)
     
     // Compute a CHAD based on a given temperature
     static
    -    void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
    +void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
     {
         cmsCIEXYZ White;
         cmsCIExyY ChromaticityOfWhite;
    @@ -744,6 +744,16 @@ int BlackPreservingGrayOnlySampler(CMSREGISTER const cmsUInt16Number In[], CMSRE
         return TRUE;
     }
     
    +
    +// Check whatever the profile is a CMYK->CMYK devicelink
    +static
    +cmsBool is_cmyk_devicelink(cmsHPROFILE hProfile)
    +{
    +    return cmsGetDeviceClass(hProfile) == cmsSigLinkClass &&
    +            cmsGetColorSpace(hProfile) == cmsSigCmykData &&
    +            cmsGetColorSpace(hProfile) == cmsSigCmykData;
    +}
    +
     // This is the entry for black-preserving K-only intents, which are non-ICC
     static
     cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
    @@ -776,14 +786,16 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
         lastProfilePos = nProfiles - 1;
         hLastProfile = hProfiles[lastProfilePos];
     
    -    while (lastProfilePos > 1)
    +    // Skip CMYK->CMYK devicelinks on ending
    +    while (is_cmyk_devicelink(hLastProfile))
         {
    -        hLastProfile = hProfiles[--lastProfilePos];
    -        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
    -            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
    +        if (lastProfilePos < 2)
                 break;
    +
    +        hLastProfile = hProfiles[--lastProfilePos];
         }
     
    +
         preservationProfilesCount = lastProfilePos + 1;
     
         // Check for non-cmyk profiles
    @@ -800,7 +812,7 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     
         // Create a LUT holding normal ICC transform
         bp.cmyk2cmyk = DefaultICCintents(ContextID,
    -                                     preservationProfilesCount,
    +        preservationProfilesCount,
             ICCIntents,
             hProfiles,
             BPC,
    @@ -812,7 +824,7 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
         // Now, compute the tone curve
         bp.KTone = _cmsBuildKToneCurve(ContextID,
             4096,
    -                                    preservationProfilesCount,
    +        preservationProfilesCount,
             ICCIntents,
             hProfiles,
             BPC,
    @@ -1002,12 +1014,13 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
         lastProfilePos = nProfiles - 1;
         hLastProfile = hProfiles[lastProfilePos];
     
    -    while (lastProfilePos > 1)
    +    // Skip CMYK->CMYK devicelinks on ending
    +    while (is_cmyk_devicelink(hLastProfile))
         {
    -        hLastProfile = hProfiles[--lastProfilePos];
    -        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
    -            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
    +        if (lastProfilePos < 2)
                 break;
    +
    +        hLastProfile = hProfiles[--lastProfilePos];
         }
     
         preservationProfilesCount = lastProfilePos + 1;
    @@ -1177,8 +1190,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
         cmsIntentsList* pt;
         cmsUInt32Number nIntents;
     
    -
    -    for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next)
    +    for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
         {
             if (nIntents < nMax) {
                 if (Codes != NULL)
    @@ -1191,7 +1203,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
             nIntents++;
         }
     
    -    for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
    +    for (pt = ctx->Intents; pt != NULL; pt = pt -> Next)
         {
             if (nIntents < nMax) {
                 if (Codes != NULL)
    @@ -1203,6 +1215,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
     
             nIntents++;
         }
    +
         return nIntents;
     }
     
    diff --git a/src/java.desktop/share/native/liblcms/cmserr.c b/src/java.desktop/share/native/liblcms/cmserr.c
    index 739cc0b2c98..9fb7db89c9a 100644
    --- a/src/java.desktop/share/native/liblcms/cmserr.c
    +++ b/src/java.desktop/share/native/liblcms/cmserr.c
    @@ -101,7 +101,7 @@ long int CMSEXPORT cmsfilelength(FILE* f)
     //
     // This is the interface to low-level memory management routines. By default a simple
     // wrapping to malloc/free/realloc is provided, although there is a limit on the max
    -// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent
    +// amount of memory that can be reclaimed. This is mostly as a safety feature to prevent
     // bogus or evil code to allocate huge blocks that otherwise lcms would never need.
     
     #define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*512U))
    @@ -121,7 +121,8 @@ cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plug
     static
     void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size)
     {
    -    if (size > MAX_MEMORY_FOR_ALLOC) return NULL;  // Never allow over maximum
    +    // Never allow 0 or over maximum
    +    if (size == 0 || size > MAX_MEMORY_FOR_ALLOC) return NULL;
     
         return (void*) malloc(size);
     
    @@ -263,7 +264,7 @@ cmsBool  _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data)
     
         // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure.
         // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the
    -    // context internal data should be malloce'd by using those functions.
    +    // context internal data should be malloc'ed by using those functions.
         if (Data == NULL) {
     
            struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID;
    diff --git a/src/java.desktop/share/native/liblcms/cmsgamma.c b/src/java.desktop/share/native/liblcms/cmsgamma.c
    index 08409434064..8e489a43c55 100644
    --- a/src/java.desktop/share/native/liblcms/cmsgamma.c
    +++ b/src/java.desktop/share/native/liblcms/cmsgamma.c
    @@ -329,6 +329,10 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEnt
             return p;
     
     Error:
    +    for (i=0; i < nSegments; i++) {
    +        if (p ->Segments && p ->Segments[i].SampledPoints) _cmsFree(ContextID, p ->Segments[i].SampledPoints);
    +        if (p ->SegInterp && p ->SegInterp[i]) _cmsFree(ContextID, p ->SegInterp[i]);
    +    }
         if (p -> SegInterp) _cmsFree(ContextID, p -> SegInterp);
         if (p -> Segments) _cmsFree(ContextID, p -> Segments);
         if (p -> Evals) _cmsFree(ContextID, p -> Evals);
    @@ -622,10 +626,16 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
         case 6:
             e = Params[1]*R + Params[2];
     
    -        if (e < 0)
    -            Val = Params[3];
    -        else
    -            Val = pow(e, Params[0]) + Params[3];
    +        // On gamma 1.0, don't clamp
    +        if (Params[0] == 1.0) {
    +            Val = e + Params[3];
    +        }
    +        else {
    +            if (e < 0)
    +                Val = Params[3];
    +            else
    +                Val = pow(e, Params[0]) + Params[3];
    +        }
             break;
     
         // ((Y - c) ^1/Gamma - b) / a
    @@ -1520,13 +1530,13 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Num
         return (sum / n);   // The mean
     }
     
    +// Retrieve segments on tone curves
     
    -// Retrieve parameters on one-segment tone curves
    -
    -cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t)
    +const cmsCurveSegment* CMSEXPORT cmsGetToneCurveSegment(cmsInt32Number n, const cmsToneCurve* t)
     {
         _cmsAssert(t != NULL);
     
    -    if (t->nSegments != 1) return NULL;
    -    return t->Segments[0].Params;
    +    if (n < 0 || n >= (cmsInt32Number) t->nSegments) return NULL;
    +    return t->Segments + n;
     }
    +
    diff --git a/src/java.desktop/share/native/liblcms/cmsgmt.c b/src/java.desktop/share/native/liblcms/cmsgmt.c
    index 60a01aa5088..e9ee73b52cd 100644
    --- a/src/java.desktop/share/native/liblcms/cmsgmt.c
    +++ b/src/java.desktop/share/native/liblcms/cmsgmt.c
    @@ -248,7 +248,7 @@ int GamutSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Nu
         cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS];
         cmsFloat64Number dE1, dE2, ErrorRatio;
     
    -    // Assume in-gamut by default.
    +    // Assume in-gamut by default. NEVER READ, USED FOR DEBUG PURPOSES.
         ErrorRatio = 1.0;
     
         // Convert input to Lab
    @@ -625,7 +625,7 @@ cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab,
     // Actually, doing that "well" is quite hard, since every component may behave completely different.
     // Since the true point of this function is to detect suitable optimizations, I am imposing some requirements
     // that simplifies things: only RGB, and only profiles that can got in both directions.
    -// The algorithm obtains Y from a syntetical gray R=G=B. Then least squares fitting is used to estimate gamma.
    +// The algorithm obtains Y from a synthetical gray R=G=B. Then least squares fitting is used to estimate gamma.
     // For gamma close to 1.0, RGB is linear. On profiles not supported, -1 is returned.
     
     cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsHPROFILE hProfile, cmsFloat64Number threshold)
    diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
    index 6763970f619..05baa9392e2 100644
    --- a/src/java.desktop/share/native/liblcms/cmsio0.c
    +++ b/src/java.desktop/share/native/liblcms/cmsio0.c
    @@ -560,6 +560,20 @@ cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
         // Set default version
         Icc ->Version =  0x02100000;
     
    +    // Set default CMM (that's me!)
    +    Icc ->CMM = lcmsSignature;
    +
    +    // Set default creator
    +    // Created by LittleCMS (that's me!)
    +    Icc ->creator = lcmsSignature;
    +
    +    // Set default platform
    +#ifdef CMS_IS_WINDOWS_
    +    Icc ->platform = cmsSigMicrosoft;
    +#else
    +    Icc ->platform = cmsSigMacintosh;
    +#endif
    +
         // Set default device class
         Icc->DeviceClass = cmsSigDisplayClass;
     
    @@ -813,11 +827,13 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
         }
     
         // Adjust endianness of the used parameters
    +    Icc -> CMM             = _cmsAdjustEndianess32(Header.cmmId);
         Icc -> DeviceClass     = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
         Icc -> ColorSpace      = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.colorSpace);
         Icc -> PCS             = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.pcs);
     
         Icc -> RenderingIntent = _cmsAdjustEndianess32(Header.renderingIntent);
    +    Icc -> platform        = (cmsPlatformSignature)_cmsAdjustEndianess32(Header.platform);
         Icc -> flags           = _cmsAdjustEndianess32(Header.flags);
         Icc -> manufacturer    = _cmsAdjustEndianess32(Header.manufacturer);
         Icc -> model           = _cmsAdjustEndianess32(Header.model);
    @@ -922,7 +938,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
         cmsUInt32Number Count;
     
         Header.size        = _cmsAdjustEndianess32(UsedSpace);
    -    Header.cmmId       = _cmsAdjustEndianess32(lcmsSignature);
    +    Header.cmmId       = _cmsAdjustEndianess32(Icc ->CMM);
         Header.version     = _cmsAdjustEndianess32(Icc ->Version);
     
         Header.deviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Icc -> DeviceClass);
    @@ -934,11 +950,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
     
         Header.magic       = _cmsAdjustEndianess32(cmsMagicNumber);
     
    -#ifdef CMS_IS_WINDOWS_
    -    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMicrosoft);
    -#else
    -    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMacintosh);
    -#endif
    +    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(Icc -> platform);
     
         Header.flags        = _cmsAdjustEndianess32(Icc -> flags);
         Header.manufacturer = _cmsAdjustEndianess32(Icc -> manufacturer);
    @@ -954,8 +966,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
         Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y));
         Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z));
     
    -    // Created by LittleCMS (that's me!)
    -    Header.creator      = _cmsAdjustEndianess32(lcmsSignature);
    +    Header.creator      = _cmsAdjustEndianess32(Icc ->creator);
     
         memset(&Header.reserved, 0, sizeof(Header.reserved));
     
    diff --git a/src/java.desktop/share/native/liblcms/cmsio1.c b/src/java.desktop/share/native/liblcms/cmsio1.c
    index bd8a832ac40..e42d4d38987 100644
    --- a/src/java.desktop/share/native/liblcms/cmsio1.c
    +++ b/src/java.desktop/share/native/liblcms/cmsio1.c
    @@ -607,7 +607,7 @@ cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFlo
         return NULL;
     }
     
    -// Create an output MPE LUT from agiven profile. Version mismatches are handled here
    +// Create an output MPE LUT from a given profile. Version mismatches are handled here
     cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
     {
         cmsTagTypeSignature OriginalType;
    @@ -1056,3 +1056,13 @@ cmsUInt32Number  CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoT
     
         return cmsMLUgetASCII(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
     }
    +
    +cmsUInt32Number  CMSEXPORT cmsGetProfileInfoUTF8(cmsHPROFILE hProfile, cmsInfoType Info,
    +                                                          const char LanguageCode[3], const char CountryCode[3],
    +                                                          char* Buffer, cmsUInt32Number BufferSize)
    +{
    +    const cmsMLU* mlu = GetInfo(hProfile, Info);
    +    if (mlu == NULL) return 0;
    +
    +    return cmsMLUgetUTF8(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
    +}
    diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
    index 24114632ad0..b544c948625 100644
    --- a/src/java.desktop/share/native/liblcms/cmslut.c
    +++ b/src/java.desktop/share/native/liblcms/cmslut.c
    @@ -504,6 +504,9 @@ cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
             if (rv > UINT_MAX / dim) return 0;
         }
     
    +    // Again, prevent overflow
    +    if (rv > UINT_MAX / 15) return 0;
    +
         return rv;
     }
     
    @@ -843,7 +846,13 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
         cmsUInt32Number nInputs, nOutputs;
         cmsUInt32Number* nSamples;
         cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
    -    _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data;
    +    _cmsStageCLutData* clut;
    +
    +    if (mpe == NULL) return FALSE;
    +
    +    clut = (_cmsStageCLutData*)mpe->Data;
    +
    +    if (clut == NULL) return FALSE;
     
         nSamples = clut->Params ->nSamples;
         nInputs  = clut->Params ->nInputs;
    diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
    index 04280180230..d3cd97d4aea 100644
    --- a/src/java.desktop/share/native/liblcms/cmsnamed.c
    +++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
    @@ -229,17 +229,145 @@ void strFrom16(char str[3], cmsUInt16Number n)
         str[0] = (char)(n >> 8);
         str[1] = (char)n;
         str[2] = (char)0;
    +}
    +
    +
    +// Convert from UTF8 to wchar, returns len.
    +static
    +cmsUInt32Number decodeUTF8(wchar_t* out, const char* in)
    +{
    +    cmsUInt32Number codepoint = 0;
    +    cmsUInt32Number size = 0;
    +
    +    while (*in)
    +    {
    +        cmsUInt8Number ch = (cmsUInt8Number) *in;
    +
    +        if (ch <= 0x7f)
    +        {
    +            codepoint = ch;
    +        }
    +        else if (ch <= 0xbf)
    +        {
    +            codepoint = (codepoint << 6) | (ch & 0x3f);
    +        }
    +        else if (ch <= 0xdf)
    +        {
    +            codepoint = ch & 0x1f;
    +        }
    +        else if (ch <= 0xef)
    +        {
    +            codepoint = ch & 0x0f;
    +        }
    +        else
    +        {
    +            codepoint = ch & 0x07;
    +        }
    +
    +        in++;
     
    +        if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
    +        {
    +            if (sizeof(wchar_t) > 2)
    +            {
    +                if (out) *out++ = (wchar_t) codepoint;
    +                size++;
    +            }
    +            else
    +                if (codepoint > 0xffff)
    +                {
    +                    if (out)
    +                    {
    +                        *out++ = (wchar_t)(0xd800 + (codepoint >> 10));
    +                        *out++ = (wchar_t)(0xdc00 + (codepoint & 0x03ff));
    +                        size += 2;
    +                    }
    +                }
    +                else
    +                    if (codepoint < 0xd800 || codepoint >= 0xe000)
    +                    {
    +                        if (out) *out++ = (wchar_t) codepoint;
    +                        size++;
    +                    }
    +        }
    +    }
    +
    +    return size;
    +}
    +
    +// Convert from wchar_t to UTF8
    +static
    +cmsUInt32Number encodeUTF8(char* out, const wchar_t* in, cmsUInt32Number max_wchars, cmsUInt32Number max_chars)
    +{
    +    cmsUInt32Number codepoint = 0;
    +    cmsUInt32Number size = 0;
    +    cmsUInt32Number len_w = 0;
    +
    +    while (*in && len_w < max_wchars)
    +    {
    +        if (*in >= 0xd800 && *in <= 0xdbff)
    +            codepoint = ((*in - 0xd800) << 10) + 0x10000;
    +        else
    +        {
    +            if (*in >= 0xdc00 && *in <= 0xdfff)
    +                codepoint |= *in - 0xdc00;
    +            else
    +                codepoint = *in;
    +
    +            if (codepoint <= 0x7f)
    +            {
    +                if (out && (size + 1 < max_chars)) *out++ = (char)codepoint;
    +                size++;
    +            }
    +
    +            else if (codepoint <= 0x7ff)
    +            {
    +                if (out && (max_chars > 0) && (size + 2 < max_chars))
    +                {
    +                    *out++ = (char)(cmsUInt32Number)(0xc0 | ((codepoint >> 6) & 0x1f));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
    +                }
    +                size += 2;
    +            }
    +            else if (codepoint <= 0xffff)
    +            {
    +                if (out && (max_chars > 0) && (size + 3 < max_chars))
    +                {
    +                    *out++ = (char)(cmsUInt32Number)(0xe0 | ((codepoint >> 12) & 0x0f));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 6) & 0x3f));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
    +                }
    +                size += 3;
    +            }
    +            else
    +            {
    +                if (out && (max_chars > 0) && (size + 4 < max_chars))
    +                {
    +                    *out++ = (char)(cmsUInt32Number)(0xf0 | ((codepoint >> 18) & 0x07));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 12) & 0x3f));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 6) & 0x3f));
    +                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
    +                }
    +                size += 4;
    +            }
    +
    +            codepoint = 0;
    +        }
    +
    +        in++; len_w++;
    +    }
    +
    +    return size;
     }
     
     // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
     // In the case the user explicitly sets an empty string, we force a \0
     cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
     {
    -    cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
    +    cmsUInt32Number i, len = (cmsUInt32Number)strlen(ASCIIString);
         wchar_t* WStr;
         cmsBool  rc;
    -    cmsUInt16Number Lang  = strTo16(LanguageCode);
    +    cmsUInt16Number Lang = strTo16(LanguageCode);
         cmsUInt16Number Cntry = strTo16(CountryCode);
     
         if (mlu == NULL) return FALSE;
    @@ -247,22 +375,56 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const
         // len == 0 would prevent operation, so we set a empty string pointing to zero
         if (len == 0)
         {
    -        len = 1;
    +        wchar_t empty = 0;
    +        return AddMLUBlock(mlu, sizeof(wchar_t), &empty, Lang, Cntry);
         }
     
    -    WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len,  sizeof(wchar_t));
    +    WStr = (wchar_t*)_cmsCalloc(mlu->ContextID, len, sizeof(wchar_t));
         if (WStr == NULL) return FALSE;
     
    -    for (i=0; i < len; i++)
    -        WStr[i] = (wchar_t) ASCIIString[i];
    +    for (i = 0; i < len; i++)
    +        WStr[i] = (wchar_t)ASCIIString[i];
     
    -    rc = AddMLUBlock(mlu, len  * sizeof(wchar_t), WStr, Lang, Cntry);
    +    rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry);
     
    -    _cmsFree(mlu ->ContextID, WStr);
    +    _cmsFree(mlu->ContextID, WStr);
         return rc;
     
     }
     
    +// Add an UTF8 entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
    +// In the case the user explicitly sets an empty string, we force a \0
    +cmsBool CMSEXPORT cmsMLUsetUTF8(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* UTF8String)
    +{
    +    cmsUInt32Number UTF8len;
    +    wchar_t* WStr;
    +    cmsBool  rc;
    +    cmsUInt16Number Lang  = strTo16(LanguageCode);
    +    cmsUInt16Number Cntry = strTo16(CountryCode);
    +
    +    if (mlu == NULL) return FALSE;
    +
    +    if (*UTF8String == '\0')
    +    {
    +        wchar_t empty = 0;
    +        return AddMLUBlock(mlu, sizeof(wchar_t), &empty, Lang, Cntry);
    +    }
    +
    +    // Len excluding terminator 0
    +    UTF8len = decodeUTF8(NULL, UTF8String);
    +
    +    // Get space for dest
    +    WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, UTF8len,  sizeof(wchar_t));
    +    if (WStr == NULL) return FALSE;
    +
    +    decodeUTF8(WStr, UTF8String);
    +
    +    rc = AddMLUBlock(mlu, UTF8len  * sizeof(wchar_t), WStr, Lang, Cntry);
    +
    +    _cmsFree(mlu ->ContextID, WStr);
    +    return rc;
    +}
    +
     // We don't need any wcs support library
     static
     cmsUInt32Number mywcslen(const wchar_t *s)
    @@ -401,7 +563,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
     
         if (v->StrW + v->Len > mlu->PoolSize) return NULL;
     
    -    return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
    +    return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
     }
     
     
    @@ -439,10 +601,12 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
         // Precess each character
         for (i=0; i < ASCIIlen; i++) {
     
    -        if (Wide[i] == 0)
    -            Buffer[i] = 0;
    +        wchar_t wc = Wide[i];
    +
    +        if (wc < 0xff)
    +            Buffer[i] = (char)wc;
             else
    -            Buffer[i] = (char) Wide[i];
    +            Buffer[i] = '?';
         }
     
         // We put a termination "\0"
    @@ -450,6 +614,46 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
         return ASCIIlen + 1;
     }
     
    +
    +// Obtain a UTF8 representation of the wide string. Setting buffer to NULL returns the len
    +cmsUInt32Number CMSEXPORT cmsMLUgetUTF8(const cmsMLU* mlu,
    +                                       const char LanguageCode[3], const char CountryCode[3],
    +                                       char* Buffer, cmsUInt32Number BufferSize)
    +{
    +    const wchar_t *Wide;
    +    cmsUInt32Number  StrLen = 0;
    +    cmsUInt32Number UTF8len;
    +
    +    cmsUInt16Number Lang  = strTo16(LanguageCode);
    +    cmsUInt16Number Cntry = strTo16(CountryCode);
    +
    +    // Sanitize
    +    if (mlu == NULL) return 0;
    +
    +    // Get WideChar
    +    Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
    +    if (Wide == NULL) return 0;
    +
    +    UTF8len = encodeUTF8(NULL, Wide, StrLen / sizeof(wchar_t), BufferSize);
    +
    +    // Maybe we want only to know the len?
    +    if (Buffer == NULL) return UTF8len + 1; // Note the zero at the end
    +
    +    // No buffer size means no data
    +    if (BufferSize <= 0) return 0;
    +
    +    // Some clipping may be required
    +    if (BufferSize < UTF8len + 1)
    +        UTF8len = BufferSize - 1;
    +
    +    // Process it
    +    encodeUTF8(Buffer, Wide, StrLen / sizeof(wchar_t), BufferSize);
    +
    +    // We put a termination "\0"
    +    Buffer[UTF8len] = 0;
    +    return UTF8len + 1;
    +}
    +
     // Obtain a wide representation of the MLU, on depending on current locale settings
     cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
                                           const char LanguageCode[3], const char CountryCode[3],
    @@ -470,12 +674,12 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
         // Maybe we want only to know the len?
         if (Buffer == NULL) return StrLen + sizeof(wchar_t);
     
    -  // No buffer size means no data
    -    if (BufferSize <= 0) return 0;
    +    // Invalid buffer size means no data
    +    if (BufferSize < sizeof(wchar_t)) return 0;
     
         // Some clipping may be required
         if (BufferSize < StrLen + sizeof(wchar_t))
    -        StrLen = BufferSize - + sizeof(wchar_t);
    +        StrLen = BufferSize - sizeof(wchar_t);
     
         memmove(Buffer, Wide, StrLen);
         Buffer[StrLen / sizeof(wchar_t)] = 0;
    @@ -843,13 +1047,19 @@ void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq)
     {
         cmsUInt32Number i;
     
    -    for (i=0; i < pseq ->n; i++) {
    -        if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer);
    -        if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model);
    -        if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description);
    +    if (pseq == NULL)
    +        return;
    +
    +    if (pseq ->seq != NULL) {
    +        for (i=0; i < pseq ->n; i++) {
    +            if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer);
    +            if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model);
    +            if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description);
    +        }
    +
    +        _cmsFree(pseq ->ContextID, pseq ->seq);
         }
     
    -    if (pseq ->seq != NULL) _cmsFree(pseq ->ContextID, pseq ->seq);
         _cmsFree(pseq -> ContextID, pseq);
     }
     
    diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
    index 3e81ae1df1b..421a4f4a701 100644
    --- a/src/java.desktop/share/native/liblcms/cmsopt.c
    +++ b/src/java.desktop/share/native/liblcms/cmsopt.c
    @@ -212,6 +212,7 @@ cmsBool  isFloatMatrixIdentity(const cmsMAT3* a)
     
            return TRUE;
     }
    +
     // if two adjacent matrices are found, multiply them.
     static
     cmsBool _MultiplyMatrix(cmsPipeline* Lut)
    @@ -1142,14 +1143,17 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
     
             // Store result in curve
             for (t=0; t < OriginalLut ->InputChannels; t++)
    -            Trans[t] ->Table16[i] = _cmsQuickSaturateWord(Out[t] * 65535.0);
    +        {
    +            if (Trans[t]->Table16 != NULL)
    +                Trans[t] ->Table16[i] = _cmsQuickSaturateWord(Out[t] * 65535.0);
    +        }
         }
     
         // Slope-limit the obtained curves
         for (t = 0; t < OriginalLut ->InputChannels; t++)
             SlopeLimiting(Trans[t]);
     
    -    // Check for validity
    +    // Check for validity. lIsLinear is here for debug purposes
         lIsSuitable = TRUE;
         lIsLinear   = TRUE;
         for (t=0; (lIsSuitable && (t < OriginalLut ->InputChannels)); t++) {
    @@ -1753,6 +1757,8 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
     
                          _cmsStageMatrixData* Data = (_cmsStageMatrixData*)cmsStageData(Matrix1);
     
    +                     if (Matrix1->InputChannels != 3 || Matrix1->OutputChannels != 3) return FALSE;
    +
                          // Copy the matrix to our result
                          memcpy(&res, Data->Double, sizeof(res));
     
    @@ -1797,7 +1803,7 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
             _cmsStageToneCurvesData* mpeC2 = (_cmsStageToneCurvesData*) cmsStageData(Curve2);
     
             // In this particular optimization, cache does not help as it takes more time to deal with
    -        // the cache that with the pixel handling
    +        // the cache than with the pixel handling
             *dwFlags |= cmsFLAGS_NOCACHE;
     
             // Setup the optimizarion routines
    @@ -1954,7 +1960,7 @@ cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
         for (mpe = cmsPipelineGetPtrToFirstStage(*PtrLut);
             mpe != NULL;
             mpe = cmsStageNext(mpe)) {
    -        if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
    +            if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
         }
     
         // Try to get rid of identities and trivial conversions.
    diff --git a/src/java.desktop/share/native/liblcms/cmspack.c b/src/java.desktop/share/native/liblcms/cmspack.c
    index da5fc6019d3..fc875995a80 100644
    --- a/src/java.desktop/share/native/liblcms/cmspack.c
    +++ b/src/java.desktop/share/native/liblcms/cmspack.c
    @@ -2980,6 +2980,108 @@ cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
     
     // --------------------------------------------------------------------------------------------------------
     
    +static
    +cmsUInt8Number* PackBytesFromFloat(_cmsTRANSFORM* info,
    +                                    cmsFloat32Number wOut[],
    +                                    cmsUInt8Number* output,
    +                                    cmsUInt32Number Stride)
    +{
    +    cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
    +    cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
    +    cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
    +    cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
    +    cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
    +    cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
    +    cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
    +    cmsUInt8Number* swap1 = (cmsUInt8Number*)output;
    +    cmsFloat64Number v = 0;
    +    cmsUInt8Number vv = 0;
    +    cmsUInt32Number i, start = 0;
    +
    +    if (ExtraFirst)
    +        start = Extra;
    +
    +    for (i = 0; i < nChan; i++) {
    +
    +        cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
    +
    +        v = wOut[index] * 65535.0;
    +
    +        if (Reverse)
    +            v = 65535.0 - v;
    +
    +        vv =  FROM_16_TO_8(_cmsQuickSaturateWord(v));
    +
    +        if (Planar)
    +            ((cmsUInt8Number*)output)[(i + start) * Stride] = vv;
    +        else
    +            ((cmsUInt8Number*)output)[i + start] = vv;
    +    }
    +
    +
    +    if (Extra == 0 && SwapFirst) {
    +
    +        memmove(swap1 + 1, swap1, (nChan - 1) * sizeof(cmsUInt8Number));
    +        *swap1 = vv;
    +    }
    +
    +    if (T_PLANAR(info->OutputFormat))
    +        return output + sizeof(cmsUInt8Number);
    +    else
    +        return output + (nChan + Extra) * sizeof(cmsUInt8Number);
    +}
    +
    +static
    +cmsUInt8Number* PackWordsFromFloat(_cmsTRANSFORM* info,
    +                                    cmsFloat32Number wOut[],
    +                                    cmsUInt8Number* output,
    +                                    cmsUInt32Number Stride)
    +{
    +    cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
    +    cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
    +    cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
    +    cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
    +    cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
    +    cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
    +    cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
    +    cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
    +    cmsFloat64Number v = 0;
    +    cmsUInt16Number vv = 0;
    +    cmsUInt32Number i, start = 0;
    +
    +    if (ExtraFirst)
    +        start = Extra;
    +
    +    for (i = 0; i < nChan; i++) {
    +
    +        cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
    +
    +        v = wOut[index] * 65535.0;
    +
    +        if (Reverse)
    +            v = 65535.0 - v;
    +
    +        vv = _cmsQuickSaturateWord(v);
    +
    +        if (Planar)
    +            ((cmsUInt16Number*)output)[(i + start) * Stride] = vv;
    +        else
    +            ((cmsUInt16Number*)output)[i + start] = vv;
    +    }
    +
    +    if (Extra == 0 && SwapFirst) {
    +
    +        memmove(swap1 + 1, swap1, (nChan - 1) * sizeof(cmsUInt16Number));
    +        *swap1 = vv;
    +    }
    +
    +    if (T_PLANAR(info->OutputFormat))
    +        return output + sizeof(cmsUInt16Number);
    +    else
    +        return output + (nChan + Extra) * sizeof(cmsUInt16Number);
    +}
    +
    +
     static
     cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
                                         cmsFloat32Number wOut[],
    @@ -3143,6 +3245,77 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
     }
     
     
    +static
    +cmsUInt8Number* PackEncodedBytesLabV2FromFloat(_cmsTRANSFORM* Info,
    +                                           cmsFloat32Number wOut[],
    +                                           cmsUInt8Number* output,
    +                                           cmsUInt32Number Stride)
    +{
    +    cmsCIELab Lab;
    +    cmsUInt16Number wlab[3];
    +
    +    Lab.L = (cmsFloat64Number)(wOut[0] * 100.0);
    +    Lab.a = (cmsFloat64Number)(wOut[1] * 255.0 - 128.0);
    +    Lab.b = (cmsFloat64Number)(wOut[2] * 255.0 - 128.0);
    +
    +    cmsFloat2LabEncoded(wlab, &Lab);
    +
    +    if (T_PLANAR(Info -> OutputFormat)) {
    +
    +        Stride /= PixelSize(Info->OutputFormat);
    +
    +        output[0]        = wlab[0] >> 8;
    +        output[Stride]   = wlab[1] >> 8;
    +        output[Stride*2] = wlab[2] >> 8;
    +
    +        return output + 1;
    +    }
    +    else {
    +
    +        output[0] = wlab[0] >> 8;
    +        output[1] = wlab[1] >> 8;
    +        output[2] = wlab[2] >> 8;
    +
    +        return output + (3 + T_EXTRA(Info ->OutputFormat));
    +    }
    +}
    +
    +static
    +cmsUInt8Number* PackEncodedWordsLabV2FromFloat(_cmsTRANSFORM* Info,
    +                                           cmsFloat32Number wOut[],
    +                                           cmsUInt8Number* output,
    +                                           cmsUInt32Number Stride)
    +{
    +    cmsCIELab Lab;
    +    cmsUInt16Number wlab[3];
    +
    +    Lab.L = (cmsFloat64Number)(wOut[0] * 100.0);
    +    Lab.a = (cmsFloat64Number)(wOut[1] * 255.0 - 128.0);
    +    Lab.b = (cmsFloat64Number)(wOut[2] * 255.0 - 128.0);
    +
    +    cmsFloat2LabEncodedV2(wlab, &Lab);
    +
    +    if (T_PLANAR(Info -> OutputFormat)) {
    +
    +        Stride /= PixelSize(Info->OutputFormat);
    +
    +        ((cmsUInt16Number*) output)[0]        = wlab[0];
    +        ((cmsUInt16Number*) output)[Stride]   = wlab[1];
    +        ((cmsUInt16Number*) output)[Stride*2] = wlab[2];
    +
    +        return output + sizeof(cmsUInt16Number);
    +    }
    +    else {
    +
    +         ((cmsUInt16Number*) output)[0] = wlab[0];
    +         ((cmsUInt16Number*) output)[1] = wlab[1];
    +         ((cmsUInt16Number*) output)[2] = wlab[2];
    +
    +        return output + (3 + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsUInt16Number);
    +    }
    +}
    +
    +
     // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
     static
     cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
    @@ -3676,10 +3849,20 @@ static const cmsFormattersFloat OutputFormattersFloat[] = {
         {     TYPE_Lab_DBL,                                                ANYPLANAR|ANYEXTRA,   PackLabDoubleFromFloat},
         {     TYPE_XYZ_DBL,                                                ANYPLANAR|ANYEXTRA,   PackXYZDoubleFromFloat},
     
    +    {     TYPE_LabV2_8,                                                ANYPLANAR|ANYEXTRA,   PackEncodedBytesLabV2FromFloat},
    +    {     TYPE_LabV2_16,                                               ANYPLANAR|ANYEXTRA,   PackEncodedWordsLabV2FromFloat},
    +
         {     FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
                                  ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackFloatsFromFloat },
         {     FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
                                  ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackDoublesFromFloat },
    +
    +    {     BYTES_SH(2), ANYPLANAR|
    +                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackWordsFromFloat },
    +
    +    {     BYTES_SH(1), ANYPLANAR|
    +                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackBytesFromFloat },
    +
     #ifndef CMS_NO_HALF_SUPPORT
         {     FLOAT_SH(1)|BYTES_SH(2),
                                  ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackHalfFromFloat },
    @@ -3890,7 +4073,7 @@ cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsU
         cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
     
         cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
    -    cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
    +    cmsInt32Number  nOutputChans = cmsChannelsOfColorSpace(ColorSpace);
         cmsUInt32Number Float = lIsFloat ? 1U : 0;
     
         // Unsupported color space?
    diff --git a/src/java.desktop/share/native/liblcms/cmsplugin.c b/src/java.desktop/share/native/liblcms/cmsplugin.c
    index c2808bb9278..f84e0172c81 100644
    --- a/src/java.desktop/share/native/liblcms/cmsplugin.c
    +++ b/src/java.desktop/share/native/liblcms/cmsplugin.c
    @@ -393,12 +393,7 @@ cmsBool CMSEXPORT  _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
     // from Fixed point 8.8 to double
     cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
     {
    -       cmsUInt8Number  msb, lsb;
    -
    -       lsb = (cmsUInt8Number) (fixed8 & 0xff);
    -       msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
    -
    -       return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
    +    return fixed8 / 256.0;
     }
     
     cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
    @@ -410,19 +405,7 @@ cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
     // from Fixed point 15.16 to double
     cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
     {
    -    cmsFloat64Number floater, sign, mid;
    -    int Whole, FracPart;
    -
    -    sign  = (fix32 < 0 ? -1 : 1);
    -    fix32 = abs(fix32);
    -
    -    Whole     = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
    -    FracPart  = (cmsUInt16Number)(fix32 & 0xffff);
    -
    -    mid     = (cmsFloat64Number) FracPart / 65536.0;
    -    floater = (cmsFloat64Number) Whole + mid;
    -
    -    return sign * floater;
    +    return fix32 / 65536.0;
     }
     
     // from double to Fixed point 15.16
    diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
    index 537f6854067..9a2ab464f31 100644
    --- a/src/java.desktop/share/native/liblcms/cmsps2.c
    +++ b/src/java.desktop/share/native/liblcms/cmsps2.c
    @@ -460,48 +460,46 @@ void EmitLab2XYZ(cmsIOHANDLER* m)
         _cmsIOPrintf(m, "]\n");
     }
     
    -static
    -void EmitSafeGuardBegin(cmsIOHANDLER* m, const char* name)
    -{
    -    _cmsIOPrintf(m, "%%LCMS2: Save previous definition of %s on the operand stack\n", name);
    -    _cmsIOPrintf(m, "currentdict /%s known { /%s load } { null } ifelse\n", name, name);
    -}
     
    -static
    -void EmitSafeGuardEnd(cmsIOHANDLER* m, const char* name, int depth)
    -{
    -    _cmsIOPrintf(m, "%%LCMS2: Restore previous definition of %s\n", name);
    -    if (depth > 1) {
    -        // cycle topmost items on the stack to bring the previous definition to the front
    -        _cmsIOPrintf(m, "%d -1 roll ", depth);
    -    }
    -    _cmsIOPrintf(m, "dup null eq { pop currentdict /%s undef } { /%s exch def } ifelse\n", name, name);
    -}
     
     // Outputs a table of words. It does use 16 bits
     
     static
    -void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
    +void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
     {
         cmsUInt32Number i;
         cmsFloat64Number gamma;
     
    -    if (Table == NULL) return; // Error
    +    /**
    +    * On error, empty tables or lienar assume gamma 1.0
    +    */
    +    if (Table == NULL ||
    +        Table->nEntries <= 0 ||
    +        cmsIsToneCurveLinear(Table)) {
     
    -    if (Table ->nEntries <= 0) return;  // Empty table
    +        _cmsIOPrintf(m, "{ 1 } bind ");
    +        return;
    +    }
     
    -    // Suppress whole if identity
    -    if (cmsIsToneCurveLinear(Table)) return;
     
         // Check if is really an exponential. If so, emit "exp"
         gamma = cmsEstimateGamma(Table, 0.001);
          if (gamma > 0) {
    -            _cmsIOPrintf(m, "/%s { %g exp } bind def\n", name, gamma);
    +            _cmsIOPrintf(m, "{ %g exp } bind ", gamma);
                 return;
          }
     
    -    EmitSafeGuardBegin(m, "lcms2gammatable");
    -    _cmsIOPrintf(m, "/lcms2gammatable [");
    +    _cmsIOPrintf(m, "{ ");
    +
    +    // Bounds check
    +    EmitRangeCheck(m);
    +
    +    // Emit intepolation code
    +
    +    // PostScript code                      Stack
    +    // ===============                      ========================
    +                                            // v
    +    _cmsIOPrintf(m, " [");
     
         for (i=0; i < Table->nEntries; i++) {
         if (i % 10 == 0)
    @@ -509,20 +507,8 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
             _cmsIOPrintf(m, "%d ", Table->Table16[i]);
         }
     
    -    _cmsIOPrintf(m, "] def\n");
    +    _cmsIOPrintf(m, "] ");                        // v tab
     
    -
    -    // Emit interpolation code
    -
    -    // PostScript code                            Stack
    -    // ===============                            ========================
    -                                                  // v
    -    _cmsIOPrintf(m, "/%s {\n  ", name);
    -
    -    // Bounds check
    -    EmitRangeCheck(m);
    -
    -    _cmsIOPrintf(m, "\n  //lcms2gammatable ");    // v tab
         _cmsIOPrintf(m, "dup ");                      // v tab tab
         _cmsIOPrintf(m, "length 1 sub ");             // v tab dom
         _cmsIOPrintf(m, "3 -1 roll ");                // tab dom v
    @@ -549,9 +535,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
         _cmsIOPrintf(m, "add ");                      // y
         _cmsIOPrintf(m, "65535 div\n");               // result
     
    -    _cmsIOPrintf(m, "} bind def\n");
    -
    -    EmitSafeGuardEnd(m, "lcms2gammatable", 1);
    +    _cmsIOPrintf(m, " } bind ");
     }
     
     
    @@ -568,10 +552,10 @@ cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Numb
     // Does write a set of gamma curves
     
     static
    -void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const char* nameprefix)
    +void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[])
     {
         cmsUInt32Number i;
    -    static char buffer[2048];
    +
     
         for( i=0; i < n; i++ )
         {
    @@ -579,12 +563,10 @@ void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const cha
     
             if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) {
     
    -            _cmsIOPrintf(m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1);
    +            _cmsIOPrintf(m, "dup ");
             }
             else {
    -            snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i);
    -        buffer[sizeof(buffer)-1] = '\0';
    -            Emit1Gamma(m, g[i], buffer);
    +            Emit1Gamma(m, g[i]);
             }
         }
     
    @@ -708,18 +690,21 @@ void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj,
         sc.FixWhite = FixWhite;
         sc.ColorSpace = ColorSpace;
     
    -    _cmsIOPrintf(m, "[");
    +    if (sc.Pipeline != NULL && sc.Pipeline->Params != NULL) {
     
    -    for (i=0; i < sc.Pipeline->Params->nInputs; i++)
    -        _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
    +        _cmsIOPrintf(m, "[");
     
    -    _cmsIOPrintf(m, " [\n");
    +        for (i = 0; i < sc.Pipeline->Params->nInputs; i++)
    +            _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
     
    -    cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*) &sc, SAMPLER_INSPECT);
    +        _cmsIOPrintf(m, " [\n");
     
    -    _cmsIOPrintf(m, PostMin);
    -    _cmsIOPrintf(m, PostMaj);
    -    _cmsIOPrintf(m, "] ");
    +        cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*)&sc, SAMPLER_INSPECT);
    +
    +        _cmsIOPrintf(m, PostMin);
    +        _cmsIOPrintf(m, PostMaj);
    +        _cmsIOPrintf(m, "] ");
    +    }
     
     }
     
    @@ -733,11 +718,11 @@ int EmitCIEBasedA(cmsIOHANDLER* m, cmsToneCurve* Curve, cmsCIEXYZ* BlackPoint)
         _cmsIOPrintf(m, "[ /CIEBasedA\n");
         _cmsIOPrintf(m, "  <<\n");
     
    -    EmitSafeGuardBegin(m, "lcms2gammaproc");
    -    Emit1Gamma(m, Curve, "lcms2gammaproc");
    +    _cmsIOPrintf(m, "/DecodeA ");
    +
    +    Emit1Gamma(m, Curve);
     
    -    _cmsIOPrintf(m, "/DecodeA /lcms2gammaproc load\n");
    -    EmitSafeGuardEnd(m, "lcms2gammaproc", 3);
    +    _cmsIOPrintf(m, " \n");
     
         _cmsIOPrintf(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n");
         _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
    @@ -761,19 +746,11 @@ int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** Cu
     
         _cmsIOPrintf(m, "[ /CIEBasedABC\n");
         _cmsIOPrintf(m, "<<\n");
    +    _cmsIOPrintf(m, "/DecodeABC [ ");
    +
    +    EmitNGamma(m, 3, CurveSet);
     
    -    EmitSafeGuardBegin(m, "lcms2gammaproc0");
    -    EmitSafeGuardBegin(m, "lcms2gammaproc1");
    -    EmitSafeGuardBegin(m, "lcms2gammaproc2");
    -    EmitNGamma(m, 3, CurveSet, "lcms2gammaproc");
    -    _cmsIOPrintf(m, "/DecodeABC [\n");
    -    _cmsIOPrintf(m, "   /lcms2gammaproc0 load\n");
    -    _cmsIOPrintf(m, "   /lcms2gammaproc1 load\n");
    -    _cmsIOPrintf(m, "   /lcms2gammaproc2 load\n");
         _cmsIOPrintf(m, "]\n");
    -    EmitSafeGuardEnd(m, "lcms2gammaproc2", 3);
    -    EmitSafeGuardEnd(m, "lcms2gammaproc1", 3);
    -    EmitSafeGuardEnd(m, "lcms2gammaproc0", 3);
     
         _cmsIOPrintf(m, "/MatrixABC [ " );
     
    @@ -805,10 +782,8 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Inte
     {
         const char* PreMaj;
         const char* PostMaj;
    -    const char* PreMin, * PostMin;
    +    const char* PreMin, *PostMin;
         cmsStage* mpe;
    -    int i, numchans;
    -    static char buffer[2048];
     
         mpe = Pipeline->Elements;
     
    @@ -837,34 +812,18 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Inte
     
         if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
     
    -        numchans = (int) cmsStageOutputChannels(mpe);
    -        for (i = 0; i < numchans; ++i) {
    -            snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
    -            buffer[sizeof(buffer) - 1] = '\0';
    -            EmitSafeGuardBegin(m, buffer);
    -        }
    -        EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe), "lcms2gammaproc");
    -        _cmsIOPrintf(m, "/DecodeDEF [\n");
    -        for (i = 0; i < numchans; ++i) {
    -            snprintf(buffer, sizeof(buffer), "  /lcms2gammaproc%d load\n", i);
    -            buffer[sizeof(buffer) - 1] = '\0';
    -            _cmsIOPrintf(m, buffer);
    -        }
    +        _cmsIOPrintf(m, "/DecodeDEF [ ");
    +        EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe));
             _cmsIOPrintf(m, "]\n");
    -        for (i = numchans - 1; i >= 0; --i) {
    -            snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
    -            buffer[sizeof(buffer) - 1] = '\0';
    -            EmitSafeGuardEnd(m, buffer, 3);
    -        }
     
    -        mpe = mpe->Next;
    +        mpe = mpe ->Next;
         }
     
         if (cmsStageType(mpe) == cmsSigCLutElemType) {
     
    -        _cmsIOPrintf(m, "/Table ");
    -        WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature)0);
    -        _cmsIOPrintf(m, "]\n");
    +            _cmsIOPrintf(m, "/Table ");
    +            WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature) 0);
    +            _cmsIOPrintf(m, "]\n");
         }
     
         EmitLab2XYZ(m);
    @@ -1024,9 +983,9 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr
                     for (j = 0; j < 3; j++)
                         Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
     
    -            rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat,
    -                _cmsStageGetPtrToCurveSet(Shaper),
    -                &BlackPointAdaptedToD50);
    +            rc = EmitCIEBasedABC(m,  (cmsFloat64Number *) &Mat,
    +                                _cmsStageGetPtrToCurveSet(Shaper),
    +                                 &BlackPointAdaptedToD50);
             }
             else {
     
    @@ -1053,10 +1012,15 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
     
         hLab  = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
         xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0);
    +    cmsCloseProfile(hLab);
    +
         if (xform == NULL) return 0;
     
         NamedColorList = cmsGetNamedColorList(xform);
    -    if (NamedColorList == NULL) return 0;
    +    if (NamedColorList == NULL) {
    +        cmsDeleteTransform(xform);
    +        return 0;
    +    }
     
         _cmsIOPrintf(m, "<<\n");
         _cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA");
    @@ -1065,7 +1029,6 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
     
         nColors   = cmsNamedColorCount(NamedColorList);
     
    -
         for (i=0; i < nColors; i++) {
     
             cmsUInt16Number In[1];
    @@ -1080,12 +1043,9 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
             _cmsIOPrintf(m, "  (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
         }
     
    -
    -
         _cmsIOPrintf(m, ">>\n");
     
         cmsDeleteTransform(xform);
    -    cmsCloseProfile(hLab);
         return 1;
     }
     
    @@ -1339,7 +1299,7 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
         cmsUInt32Number InFrm = TYPE_Lab_16;
         cmsUInt32Number RelativeEncodingIntent;
         cmsColorSpaceSignature ColorSpace;
    -
    +    cmsStage* first;
     
         hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
         if (hLab == NULL) return 0;
    @@ -1366,7 +1326,6 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
         cmsCloseProfile(hLab);
     
         if (xform == NULL) {
    -
             cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
             return 0;
         }
    @@ -1374,10 +1333,12 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
         // Get a copy of the internal devicelink
         v = (_cmsTRANSFORM*) xform;
         DeviceLink = cmsPipelineDup(v ->Lut);
    -    if (DeviceLink == NULL) return 0;
    -
    +    if (DeviceLink == NULL) {
    +        cmsDeleteTransform(xform);
    +        return 0;
    +    }
     
    -    // We need a CLUT
    +     // We need a CLUT
         dwFlags |= cmsFLAGS_FORCE_CLUT;
         _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
     
    @@ -1404,8 +1365,10 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     
         _cmsIOPrintf(m, "/RenderTable ");
     
    -
    -    WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace);
    +    first = cmsPipelineGetPtrToFirstStage(DeviceLink);
    +    if (first != NULL) {
    +        WriteCLUT(m, first, "<", ">\n", "", "", lFixWhite, ColorSpace);
    +    }
     
         _cmsIOPrintf(m, " %d {} bind ", nChannels);
     
    @@ -1414,7 +1377,6 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     
         _cmsIOPrintf(m, "]\n");
     
    -
         EmitIntent(m, Intent);
     
         _cmsIOPrintf(m, ">>\n");
    @@ -1477,7 +1439,10 @@ int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
     
     
         NamedColorList = cmsGetNamedColorList(xform);
    -    if (NamedColorList == NULL) return 0;
    +    if (NamedColorList == NULL) {
    +        cmsDeleteTransform(xform);
    +        return 0;
    +    }
     
         _cmsIOPrintf(m, "<<\n");
         _cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile");
    diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
    index 8a01f7ec685..74f5f4bff29 100644
    --- a/src/java.desktop/share/native/liblcms/cmssamp.c
    +++ b/src/java.desktop/share/native/liblcms/cmssamp.c
    @@ -152,7 +152,7 @@ cmsBool  BlackPointAsDarkerColorant(cmsHPROFILE    hInput,
         // Convert black to Lab
         cmsDoTransform(xform, Black, &Lab, 1);
     
    -    // Force it to be neutral, check for inconsistences
    +    // Force it to be neutral, check for inconsistencies
         Lab.a = Lab.b = 0;
         if (Lab.L > 50 || Lab.L < 0) Lab.L = 0;
     
    diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
    index 7b07b6b9cf4..862f393497a 100644
    --- a/src/java.desktop/share/native/liblcms/cmstypes.c
    +++ b/src/java.desktop/share/native/liblcms/cmstypes.c
    @@ -122,7 +122,7 @@ cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient
         return TRUE;
     }
     
    -// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons
    +// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additions
     // made by plug-ins and then the built-in defaults.
     static
     cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList)
    @@ -954,6 +954,7 @@ static
     void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
     {
         char* Text = NULL;
    +    wchar_t* UnicodeString = NULL;
         cmsMLU* mlu = NULL;
         cmsUInt32Number  AsciiCount;
         cmsUInt32Number  i, UnicodeCode, UnicodeCount;
    @@ -973,7 +974,7 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
         if (SizeOfTag < AsciiCount) return NULL;
     
         // All seems Ok, allocate the container
    -    mlu = cmsMLUalloc(self ->ContextID, 1);
    +    mlu = cmsMLUalloc(self ->ContextID, 2);
         if (mlu == NULL) return NULL;
     
         // As many memory as size of tag
    @@ -998,15 +999,30 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
         if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done;
         SizeOfTag -= 2* sizeof(cmsUInt32Number);
     
    -    if (SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
    +    if (UnicodeCount == 0 || SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
    +
    +    UnicodeString = (wchar_t*)_cmsMallocZero(self->ContextID, (UnicodeCount + 1) * sizeof(wchar_t));
    +    if (UnicodeString == NULL) goto Done;
    +
    +    if (!_cmsReadWCharArray(io, UnicodeCount, UnicodeString)) {
    +        _cmsFree(self->ContextID, (void*)UnicodeString);
    +        goto Done;
    +    }
    +
    +    UnicodeString[UnicodeCount] = 0;
     
    -    for (i=0; i < UnicodeCount; i++) {
    -        if (!io ->Read(io, &Dummy, sizeof(cmsUInt16Number), 1)) goto Done;
    +    if (!cmsMLUsetWide(mlu, cmsV2Unicode, cmsV2Unicode, UnicodeString)) {
    +        _cmsFree(self->ContextID, (void*)UnicodeString);
    +        goto Done;
         }
    +
    +    _cmsFree(self->ContextID, (void*)UnicodeString);
    +    UnicodeString = NULL;
    +
         SizeOfTag -= UnicodeCount*sizeof(cmsUInt16Number);
     
         // Skip ScriptCode code if present. Some buggy profiles does have less
    -    // data that stricttly required. We need to skip it as this type may come
    +    // data that strictly required. We need to skip it as this type may come
         // embedded in other types.
     
         if (SizeOfTag >= sizeof(cmsUInt16Number) + sizeof(cmsUInt8Number) + 67) {
    @@ -1026,6 +1042,7 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
         return mlu;
     
     Error:
    +    if (UnicodeString)  _cmsFree(self->ContextID, (void*)UnicodeString);
         if (Text) _cmsFree(self ->ContextID, (void*) Text);
         if (mlu) cmsMLUfree(mlu);
         return NULL;
    @@ -1078,7 +1095,7 @@ cmsBool  Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
     
             // Get both representations.
             cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry,  Text, len * sizeof(char));
    -        cmsMLUgetWide(mlu,  cmsNoLanguage, cmsNoCountry,  Wide, len * sizeof(wchar_t));
    +        cmsMLUgetWide(mlu,  cmsV2Unicode,  cmsV2Unicode,  Wide, len * sizeof(wchar_t));
         }
     
         // Tell the real text len including the null terminator and padding
    @@ -1577,8 +1594,6 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
         if (SizeOfTag == 0)
         {
             Block = NULL;
    -        NumOfWchar = 0;
    -
         }
         else
         {
    @@ -1940,7 +1955,7 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
     
     // We only allow a specific MPE structure: Matrix plus prelin, plus clut, plus post-lin.
     static
    -cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
    +cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
     {
         cmsUInt32Number j, nTabSize, i;
         cmsUInt8Number  val;
    @@ -1953,6 +1968,12 @@ cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
     
         // Disassemble the LUT into components.
         mpe = NewLUT -> Elements;
    +
    +    if (mpe == NULL) {  // Should never be empty. Corrupted?
    +        cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "empty LUT8 is not supported");
    +        return FALSE;
    +    }
    +
         if (mpe ->Type == cmsSigMatrixElemType) {
     
             if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE;
    @@ -2694,8 +2715,8 @@ cmsBool WriteSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
             // If this is a table-based curve, use curve type even on V4
             CurrentType = Type;
     
    -        if ((Curves[i] ->nSegments == 0)||
    -            ((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) )
    +        if ((Curves[i] ->nSegments == 0) ||                                         // 16 bits tabulated
    +            ((Curves[i]->nSegments == 3) && (Curves[i] ->Segments[1].Type == 0)) )  // Floating-point tabulated
                 CurrentType = cmsSigCurveType;
             else
             if (Curves[i] ->Segments[0].Type < 0)
    @@ -4459,8 +4480,8 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
         if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
         if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
     
    -    if (InputChans == 0) goto Error;
    -    if (OutputChans == 0) goto Error;
    +    if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) goto Error;
    +    if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) goto Error;
     
         if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16)
             goto Error;
    @@ -5250,11 +5271,13 @@ cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,  _c
         }
     
         Before = io ->Tell(io);
    -    e ->Offsets[i] = Before - BaseOffset;
    +    if (e->Offsets != NULL)
    +        e ->Offsets[i] = Before - BaseOffset;
     
         if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE;
     
    -    e ->Sizes[i] = io ->Tell(io) - Before;
    +    if (e->Sizes != NULL)
    +        e ->Sizes[i] = io ->Tell(io) - Before;
         return TRUE;
     }
     
    @@ -5499,6 +5522,216 @@ void Type_VideoSignal_Free(struct _cms_typehandler_struct* self, void* Ptr)
         _cmsFree(self->ContextID, Ptr);
     }
     
    +
    +// ********************************************************************************
    +// Microsoft's MHC2 Type support
    +// ********************************************************************************
    +
    +static
    +void SetIdentity(cmsFloat64Number XYZ2XYZmatrix[3][4])
    +{
    +    XYZ2XYZmatrix[0][0] = 1.0; XYZ2XYZmatrix[0][1] = 0.0; XYZ2XYZmatrix[0][2] = 0.0; XYZ2XYZmatrix[0][3] = 0.0;
    +    XYZ2XYZmatrix[1][0] = 0.0; XYZ2XYZmatrix[1][1] = 1.0; XYZ2XYZmatrix[1][2] = 0.0; XYZ2XYZmatrix[1][3] = 0.0;
    +    XYZ2XYZmatrix[2][0] = 0.0; XYZ2XYZmatrix[2][1] = 0.0; XYZ2XYZmatrix[2][2] = 1.0; XYZ2XYZmatrix[2][3] = 0.0;
    +}
    +
    +static
    +cmsBool CloseEnough(cmsFloat64Number a, cmsFloat64Number b)
    +{
    +    return fabs(b - a) < (1.0 / 65535.0);
    +}
    +
    +cmsBool IsIdentity(cmsFloat64Number XYZ2XYZmatrix[3][4])
    +{
    +    cmsFloat64Number Identity[3][4];
    +    int i, j;
    +
    +    SetIdentity(Identity);
    +
    +    for (i = 0; i < 3; i++)
    +        for (j = 0; j < 4; j++)
    +            if (!CloseEnough(XYZ2XYZmatrix[i][j], Identity[i][j])) return FALSE;
    +
    +    return TRUE;
    +}
    +
    +static
    +void Type_MHC2_Free(struct _cms_typehandler_struct* self, void* Ptr)
    +{
    +    cmsMHC2Type* mhc2 = (cmsMHC2Type*)Ptr;
    +
    +    if (mhc2->RedCurve != NULL) _cmsFree(self->ContextID, mhc2->RedCurve);
    +    if (mhc2->GreenCurve != NULL) _cmsFree(self->ContextID, mhc2->GreenCurve);
    +    if (mhc2->BlueCurve != NULL) _cmsFree(self->ContextID, mhc2->BlueCurve);
    +
    +    _cmsFree(self->ContextID, Ptr);
    +}
    +
    +void* Type_MHC2_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
    +{
    +    cmsMHC2Type* mhc2 = _cmsDupMem(self->ContextID, Ptr, sizeof(cmsMHC2Type));
    +
    +    mhc2->RedCurve = _cmsDupMem(self->ContextID,   mhc2->RedCurve, mhc2->CurveEntries*sizeof(cmsFloat64Number));
    +    mhc2->GreenCurve = _cmsDupMem(self->ContextID, mhc2->GreenCurve, mhc2->CurveEntries * sizeof(cmsFloat64Number));
    +    mhc2->BlueCurve = _cmsDupMem(self->ContextID,  mhc2->BlueCurve, mhc2->CurveEntries * sizeof(cmsFloat64Number));
    +
    +    if (mhc2->RedCurve == NULL ||
    +        mhc2->GreenCurve == NULL ||
    +        mhc2->BlueCurve == NULL) {
    +
    +        Type_MHC2_Free(self, mhc2);
    +        return NULL;
    +    }
    +
    +    return mhc2;
    +
    +    cmsUNUSED_PARAMETER(n);
    +}
    +
    +
    +static
    +cmsBool WriteDoubles(cmsIOHANDLER* io, cmsUInt32Number n, cmsFloat64Number* Values)
    +{
    +    cmsUInt32Number i;
    +
    +    for (i = 0; i < n; i++) {
    +
    +        if (!_cmsWrite15Fixed16Number(io, *Values++)) return FALSE;
    +    }
    +
    +    return TRUE;
    +}
    +
    +static
    +cmsBool Type_MHC2_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
    +{
    +    cmsMHC2Type* mhc2 = (cmsMHC2Type*)Ptr;
    +    cmsUInt32Number BaseOffset = io->Tell(io) - sizeof(_cmsTagBase);
    +    cmsUInt32Number TablesOffsetPos;
    +    cmsUInt32Number MatrixOffset;
    +    cmsUInt32Number OffsetRedTable, OffsetGreenTable, OffsetBlueTable;
    +
    +    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
    +    if (!_cmsWriteUInt32Number(io, mhc2->CurveEntries)) return FALSE;
    +
    +    if (!_cmsWrite15Fixed16Number(io, mhc2->MinLuminance)) return FALSE;
    +    if (!_cmsWrite15Fixed16Number(io, mhc2->PeakLuminance)) return FALSE;
    +
    +    TablesOffsetPos = io->Tell(io);
    +
    +    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Matrix
    +    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve R
    +    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve G
    +    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve B
    +
    +
    +    if (IsIdentity(mhc2->XYZ2XYZmatrix))
    +    {
    +        MatrixOffset = 0;
    +    }
    +    else
    +    {
    +        MatrixOffset = io->Tell(io) - BaseOffset;
    +        if (!WriteDoubles(io, 3 * 4, &mhc2->XYZ2XYZmatrix[0][0])) return FALSE;
    +    }
    +
    +    OffsetRedTable = io->Tell(io) - BaseOffset;
    +    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->RedCurve)) return FALSE;
    +    OffsetGreenTable = io->Tell(io) - BaseOffset;
    +    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->GreenCurve)) return FALSE;
    +    OffsetBlueTable = io->Tell(io) - BaseOffset;
    +    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->BlueCurve)) return FALSE;
    +
    +    if (!io->Seek(io, TablesOffsetPos)) return FALSE;
    +
    +    if (!_cmsWriteUInt32Number(io, MatrixOffset)) return FALSE;
    +    if (!_cmsWriteUInt32Number(io, OffsetRedTable)) return FALSE;
    +    if (!_cmsWriteUInt32Number(io, OffsetGreenTable)) return FALSE;
    +    if (!_cmsWriteUInt32Number(io, OffsetBlueTable)) return FALSE;
    +
    +    return TRUE;
    +
    +    cmsUNUSED_PARAMETER(self);
    +    cmsUNUSED_PARAMETER(nItems);
    +}
    +
    +
    +static
    +cmsBool ReadDoublesAt(cmsIOHANDLER* io, cmsUInt32Number At, cmsUInt32Number n, cmsFloat64Number* Values)
    +{
    +    cmsUInt32Number CurrentPos = io->Tell(io);
    +    cmsUInt32Number i;
    +
    +    if (!io->Seek(io, At)) return FALSE;
    +
    +    for (i = 0; i < n; i++) {
    +
    +        if (!_cmsRead15Fixed16Number(io, Values++)) return FALSE;
    +    }
    +
    +    if (!io->Seek(io, CurrentPos)) return FALSE;
    +
    +    return TRUE;
    +}
    +
    +static
    +void* Type_MHC2_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
    +{
    +    cmsMHC2Type* mhc2 = NULL;
    +
    +    cmsUInt32Number BaseOffset = io->Tell(io) - sizeof(_cmsTagBase);
    +    cmsUInt32Number MatrixOffset;
    +    cmsUInt32Number OffsetRedTable, OffsetGreenTable, OffsetBlueTable;
    +
    +    if (!_cmsReadUInt32Number(io, NULL)) return NULL;
    +
    +    mhc2 = (cmsMHC2Type*)_cmsCalloc(self->ContextID, 1, sizeof(cmsMHC2Type));
    +    if (mhc2 == NULL) return NULL;
    +
    +    if (!_cmsReadUInt32Number(io,    &mhc2->CurveEntries)) goto Error;
    +
    +    if (mhc2->CurveEntries > 4096) goto Error;
    +
    +    mhc2->RedCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
    +    mhc2->GreenCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
    +    mhc2->BlueCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
    +
    +    if (mhc2->RedCurve == NULL ||
    +        mhc2->GreenCurve == NULL ||
    +        mhc2->BlueCurve == NULL)  goto Error;
    +
    +    if (!_cmsRead15Fixed16Number(io, &mhc2->MinLuminance)) goto Error;
    +    if (!_cmsRead15Fixed16Number(io, &mhc2->PeakLuminance)) goto Error;
    +
    +    if (!_cmsReadUInt32Number(io, &MatrixOffset)) goto Error;
    +    if (!_cmsReadUInt32Number(io, &OffsetRedTable)) goto Error;
    +    if (!_cmsReadUInt32Number(io, &OffsetGreenTable)) goto Error;
    +    if (!_cmsReadUInt32Number(io, &OffsetBlueTable)) goto Error;
    +
    +    if (MatrixOffset == 0)
    +        SetIdentity(mhc2->XYZ2XYZmatrix);
    +    else
    +    {
    +        if (!ReadDoublesAt(io, BaseOffset + MatrixOffset, 3*4, &mhc2->XYZ2XYZmatrix[0][0])) goto Error;
    +    }
    +
    +    if (!ReadDoublesAt(io, BaseOffset + OffsetRedTable, mhc2->CurveEntries, mhc2->RedCurve)) goto Error;
    +    if (!ReadDoublesAt(io, BaseOffset + OffsetGreenTable, mhc2->CurveEntries, mhc2->GreenCurve)) goto Error;
    +    if (!ReadDoublesAt(io, BaseOffset + OffsetBlueTable, mhc2->CurveEntries, mhc2->BlueCurve)) goto Error;
    +
    +    // Success
    +    *nItems = 1;
    +    return mhc2;
    +
    +Error:
    +    Type_MHC2_Free(self, mhc2);
    +    return NULL;
    +
    +    cmsUNUSED_PARAMETER(SizeOfTag);
    +}
    +
    +
    +
     // ********************************************************************************
     // Type support main routines
     // ********************************************************************************
    @@ -5538,7 +5771,8 @@ static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
     {TYPE_HANDLER(cmsSigProfileSequenceIdType,     ProfileSequenceId),  (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
     {TYPE_HANDLER(cmsSigDictType,                  Dictionary),         (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
     {TYPE_HANDLER(cmsSigcicpType,                  VideoSignal),        (_cmsTagTypeLinkedList*) &SupportedTagTypes[31] },
    -{TYPE_HANDLER(cmsSigVcgtType,                  vcgt),                NULL }
    +{TYPE_HANDLER(cmsSigVcgtType,                  vcgt),               (_cmsTagTypeLinkedList*) &SupportedTagTypes[32] },
    +{TYPE_HANDLER(cmsSigMHC2Type,                  MHC2),                NULL }
     };
     
     
    @@ -5734,7 +5968,8 @@ static _cmsTagLinkedList SupportedTags[] = {
         { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
         { cmsSigcicpTag,                { 1, 1, { cmsSigcicpType},               NULL },   &SupportedTags[64]},
     
    -    { cmsSigArgyllArtsTag,          { 9, 1, { cmsSigS15Fixed16ArrayType},    NULL}, NULL}
    +    { cmsSigArgyllArtsTag,          { 9, 1, { cmsSigS15Fixed16ArrayType},    NULL}, &SupportedTags[65]},
    +    { cmsSigMHC2Tag,                { 1, 1, { cmsSigMHC2Type },              NULL}, NULL}
     
     };
     
    diff --git a/src/java.desktop/share/native/liblcms/cmsvirt.c b/src/java.desktop/share/native/liblcms/cmsvirt.c
    index 6ce04796174..e8d18d4ca9f 100644
    --- a/src/java.desktop/share/native/liblcms/cmsvirt.c
    +++ b/src/java.desktop/share/native/liblcms/cmsvirt.c
    @@ -435,10 +435,9 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
     
         if (Limit < 0.0 || Limit > 400) {
     
    -        cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400");
    -        if (Limit < 0) Limit = 0;
    +        cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 1..400");
    +        if (Limit < 1) Limit = 1;
             if (Limit > 400) Limit = 400;
    -
         }
     
         hICC = cmsCreateProfilePlaceholder(ContextID);
    @@ -701,6 +700,127 @@ cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void)
         return cmsCreate_sRGBProfileTHR(NULL);
     }
     
    +/**
    +* Oklab colorspace profile (experimental)
    +*
    +* This virtual profile cannot be saved as an ICC file
    +*/
    +cmsHPROFILE cmsCreate_OkLabProfile(cmsContext ctx)
    +{
    +    cmsStage* XYZPCS = _cmsStageNormalizeFromXyzFloat(ctx);
    +    cmsStage* PCSXYZ = _cmsStageNormalizeToXyzFloat(ctx);
    +
    +    const double M_D65_D50[] =
    +    {
    +       1.047886, 0.022919, -0.050216,
    +       0.029582, 0.990484, -0.017079,
    +      -0.009252, 0.015073,  0.751678
    +    };
    +
    +    const double M_D50_D65[] =
    +    {
    +         0.955512609517083, -0.023073214184645,  0.063308961782107,
    +        -0.028324949364887,  1.009942432477107,  0.021054814890112,
    +         0.012328875695483, -0.020535835374141,  1.330713916450354
    +    };
    +
    +    cmsStage* D65toD50 = cmsStageAllocMatrix(ctx, 3, 3, M_D65_D50, NULL);
    +    cmsStage* D50toD65 = cmsStageAllocMatrix(ctx, 3, 3, M_D50_D65, NULL);
    +
    +    const double M_D65_LMS[] =
    +    {
    +        0.8189330101, 0.3618667424, -0.1288597137,
    +        0.0329845436, 0.9293118715,  0.0361456387,
    +        0.0482003018, 0.2643662691,  0.6338517070
    +    };
    +
    +    const double M_LMS_D65[] =
    +    {
    +        1.227013851103521, -0.557799980651822,  0.281256148966468,
    +       -0.040580178423281,  1.112256869616830, -0.071676678665601,
    +       -0.076381284505707, -0.421481978418013,  1.586163220440795
    +    };
    +
    +    cmsStage* D65toLMS = cmsStageAllocMatrix(ctx, 3, 3, M_D65_LMS, NULL);
    +    cmsStage* LMStoD65 = cmsStageAllocMatrix(ctx, 3, 3, M_LMS_D65, NULL);
    +
    +    cmsToneCurve* CubeRoot = cmsBuildGamma(ctx, 1.0 / 3.0);
    +    cmsToneCurve* Cube     = cmsBuildGamma(ctx,  3.0);
    +
    +    cmsToneCurve* Roots[3] = { CubeRoot, CubeRoot, CubeRoot };
    +    cmsToneCurve* Cubes[3] = { Cube, Cube, Cube };
    +
    +    cmsStage* NonLinearityFw = cmsStageAllocToneCurves(ctx, 3, Roots);
    +    cmsStage* NonLinearityRv = cmsStageAllocToneCurves(ctx, 3, Cubes);
    +
    +    const double M_LMSprime_OkLab[] =
    +    {
    +        0.2104542553,  0.7936177850, -0.0040720468,
    +        1.9779984951, -2.4285922050,  0.4505937099,
    +        0.0259040371,  0.7827717662, -0.8086757660
    +    };
    +
    +    const double M_OkLab_LMSprime[] =
    +    {
    +        0.999999998450520,  0.396337792173768,  0.215803758060759,
    +        1.000000008881761, -0.105561342323656, -0.063854174771706,
    +        1.000000054672411, -0.089484182094966, -1.291485537864092
    +    };
    +
    +    cmsStage* LMSprime_OkLab = cmsStageAllocMatrix(ctx, 3, 3, M_LMSprime_OkLab, NULL);
    +    cmsStage* OkLab_LMSprime = cmsStageAllocMatrix(ctx, 3, 3, M_OkLab_LMSprime, NULL);
    +
    +    cmsPipeline* AToB = cmsPipelineAlloc(ctx, 3, 3);
    +    cmsPipeline* BToA = cmsPipelineAlloc(ctx, 3, 3);
    +
    +    cmsHPROFILE hProfile = cmsCreateProfilePlaceholder(ctx);
    +
    +    cmsSetProfileVersion(hProfile, 4.4);
    +
    +    cmsSetDeviceClass(hProfile, cmsSigColorSpaceClass);
    +    cmsSetColorSpace(hProfile, cmsSig3colorData);
    +    cmsSetPCS(hProfile, cmsSigXYZData);
    +
    +    cmsSetHeaderRenderingIntent(hProfile, INTENT_RELATIVE_COLORIMETRIC);
    +
    +    /**
    +    * Conversion PCS (XYZ/D50) to OkLab
    +    */
    +    if (!cmsPipelineInsertStage(BToA, cmsAT_END, PCSXYZ)) goto error;
    +    if (!cmsPipelineInsertStage(BToA, cmsAT_END, D50toD65)) goto error;
    +    if (!cmsPipelineInsertStage(BToA, cmsAT_END, D65toLMS)) goto error;
    +    if (!cmsPipelineInsertStage(BToA, cmsAT_END, NonLinearityFw)) goto error;
    +    if (!cmsPipelineInsertStage(BToA, cmsAT_END, LMSprime_OkLab)) goto error;
    +
    +    if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, BToA)) goto error;
    +
    +    if (!cmsPipelineInsertStage(AToB, cmsAT_END, OkLab_LMSprime)) goto error;
    +    if (!cmsPipelineInsertStage(AToB, cmsAT_END, NonLinearityRv)) goto error;
    +    if (!cmsPipelineInsertStage(AToB, cmsAT_END, LMStoD65)) goto error;
    +    if (!cmsPipelineInsertStage(AToB, cmsAT_END, D65toD50)) goto error;
    +    if (!cmsPipelineInsertStage(AToB, cmsAT_END, XYZPCS)) goto error;
    +
    +    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, AToB)) goto error;
    +
    +    cmsPipelineFree(BToA);
    +    cmsPipelineFree(AToB);
    +
    +    cmsFreeToneCurve(CubeRoot);
    +    cmsFreeToneCurve(Cube);
    +
    +    return hProfile;
    +
    +error:
    +    cmsPipelineFree(BToA);
    +    cmsPipelineFree(AToB);
    +
    +    cmsFreeToneCurve(CubeRoot);
    +    cmsFreeToneCurve(Cube);
    +    cmsCloseProfile(hProfile);
    +
    +    return NULL;
    +
    +}
     
     
     typedef struct {
    @@ -1060,7 +1180,7 @@ cmsBool CheckOne(const cmsAllowedLUT* Tab, const cmsPipeline* Lut)
     
         for (n=0, mpe = Lut ->Elements; mpe != NULL; mpe = mpe ->Next, n++) {
     
    -        if (n > Tab ->nTypes) return FALSE;
    +        if (n >= Tab ->nTypes) return FALSE;
             if (cmsStageType(mpe) != Tab ->MpeTypes[n]) return FALSE;
         }
     
    @@ -1091,9 +1211,9 @@ const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTa
     cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
     {
         cmsHPROFILE hProfile = NULL;
    -        cmsUInt32Number FrmIn, FrmOut;
    -        cmsInt32Number ChansIn, ChansOut;
    -        int ColorSpaceBitsIn, ColorSpaceBitsOut;
    +    cmsUInt32Number FrmIn, FrmOut;
    +    cmsInt32Number ChansIn, ChansOut;
    +    int ColorSpaceBitsIn, ColorSpaceBitsOut;
         _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
         cmsPipeline* LUT = NULL;
         cmsStage* mpe;
    @@ -1104,6 +1224,9 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
     
         _cmsAssert(hTransform != NULL);
     
    +    // Check if the pipeline holding is valid
    +    if (xform -> Lut == NULL) return NULL;
    +
         // Get the first mpe to check for named color
         mpe = cmsPipelineGetPtrToFirstStage(xform ->Lut);
     
    diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
    index 3f3ad28c6c4..86afd7202fd 100644
    --- a/src/java.desktop/share/native/liblcms/cmsxform.c
    +++ b/src/java.desktop/share/native/liblcms/cmsxform.c
    @@ -943,7 +943,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
            }
     
         // Check whatever this is a true floating point transform
    -    if (_cmsFormatterIsFloat(*OutputFormat)) {
    +    if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) {
     
             // Get formatter function always return a valid union, but the contents of this union may be NULL.
             p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
    @@ -1018,6 +1018,19 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
             }
         }
     
    +    /**
    +    * Check consistency for alpha channel copy
    +    */
    +    if (*dwFlags & cmsFLAGS_COPY_ALPHA)
    +    {
    +        if (T_EXTRA(*InputFormat) != T_EXTRA(*OutputFormat))
    +        {
    +            cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Mismatched alpha channels");
    +            cmsDeleteTransform(p);
    +            return NULL;
    +        }
    +    }
    +
         p ->InputFormat     = *InputFormat;
         p ->OutputFormat    = *OutputFormat;
         p ->dwOriginalFlags = *dwFlags;
    diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
    index d5b8c477f23..2d9a8b1248f 100644
    --- a/src/java.desktop/share/native/liblcms/lcms2.h
    +++ b/src/java.desktop/share/native/liblcms/lcms2.h
    @@ -52,7 +52,7 @@
     //
     //---------------------------------------------------------------------------------
     //
    -// Version 2.15
    +// Version 2.16
     //
     
     #ifndef _lcms2_H
    @@ -105,12 +105,15 @@
     
     #ifndef CMS_USE_CPP_API
     #   ifdef __cplusplus
    +#       if __cplusplus >= 201703L
    +#            define CMS_NO_REGISTER_KEYWORD 1
    +#       endif
     extern "C" {
     #   endif
     #endif
     
     // Version/release
    -#define LCMS_VERSION        2150
    +#define LCMS_VERSION        2160
     
     // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
     #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
    @@ -354,7 +357,8 @@ typedef enum {
         cmsSigUInt8ArrayType                    = 0x75693038,  // 'ui08'
         cmsSigVcgtType                          = 0x76636774,  // 'vcgt'
         cmsSigViewingConditionsType             = 0x76696577,  // 'view'
    -    cmsSigXYZType                           = 0x58595A20   // 'XYZ '
    +    cmsSigXYZType                           = 0x58595A20,  // 'XYZ '
    +    cmsSigMHC2Type                          = 0x4D484332   // 'MHC2'
     
     
     } cmsTagTypeSignature;
    @@ -432,7 +436,8 @@ typedef enum {
         cmsSigVcgtTag                           = 0x76636774,  // 'vcgt'
         cmsSigMetaTag                           = 0x6D657461,  // 'meta'
         cmsSigcicpTag                           = 0x63696370,  // 'cicp'
    -    cmsSigArgyllArtsTag                     = 0x61727473   // 'arts'
    +    cmsSigArgyllArtsTag                     = 0x61727473,  // 'arts'
    +    cmsSigMHC2Tag                           = 0x4D484332   // 'MHC2'
     
     } cmsTagSignature;
     
    @@ -977,6 +982,7 @@ typedef void* cmsHTRANSFORM;
     #define TYPE_RGB_DBL          (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0))
     #define TYPE_BGR_DBL          (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)|DOSWAP_SH(1))
     #define TYPE_CMYK_DBL         (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0))
    +#define TYPE_OKLAB_DBL        (FLOAT_SH(1)|COLORSPACE_SH(PT_MCH3)|CHANNELS_SH(3)|BYTES_SH(0))
     
     // IEEE 754-2008 "half"
     #define TYPE_GRAY_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2))
    @@ -1077,6 +1083,19 @@ typedef struct {
     
     } cmsVideoSignalType;
     
    +typedef struct {
    +    cmsUInt32Number   CurveEntries;
    +    cmsFloat64Number* RedCurve;
    +    cmsFloat64Number* GreenCurve;
    +    cmsFloat64Number* BlueCurve;
    +
    +    cmsFloat64Number  MinLuminance;         // ST.2086 min luminance in nits
    +    cmsFloat64Number  PeakLuminance;        // ST.2086 peak luminance in nits
    +
    +    cmsFloat64Number XYZ2XYZmatrix[3][4];
    +
    +} cmsMHC2Type;
    +
     
     
     // Get LittleCMS version (for shared objects) -----------------------------------------------------------------------------
    @@ -1249,7 +1268,8 @@ CMSAPI cmsBool           CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t
     CMSAPI cmsBool           CMSEXPORT cmsIsToneCurveDescending(const cmsToneCurve* t);
     CMSAPI cmsInt32Number    CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t);
     CMSAPI cmsFloat64Number  CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision);
    -CMSAPI cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t);
    +
    +CMSAPI const cmsCurveSegment* CMSEXPORT cmsGetToneCurveSegment(cmsInt32Number n, const cmsToneCurve* t);
     
     // Tone curve tabular estimation
     CMSAPI cmsUInt32Number         CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t);
    @@ -1343,8 +1363,11 @@ CMSAPI cmsBool           CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, c
     
     typedef struct _cms_MLU_struct cmsMLU;
     
    -#define  cmsNoLanguage "\0\0"
    -#define  cmsNoCountry  "\0\0"
    +#define  cmsNoLanguage    "\0\0"
    +#define  cmsNoCountry     "\0\0"
    +
    +// Special language/country to retrieve unicode field for description in V2 profiles. Use with care.
    +#define  cmsV2Unicode     "\xff\xff"
     
     CMSAPI cmsMLU*           CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems);
     CMSAPI void              CMSEXPORT cmsMLUfree(cmsMLU* mlu);
    @@ -1356,6 +1379,9 @@ CMSAPI cmsBool           CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu,
     CMSAPI cmsBool           CMSEXPORT cmsMLUsetWide(cmsMLU* mlu,
                                                       const char LanguageCode[3], const char CountryCode[3],
                                                       const wchar_t* WideString);
    +CMSAPI cmsBool           CMSEXPORT cmsMLUsetUTF8(cmsMLU* mlu,
    +                                                  const char LanguageCode[3], const char CountryCode[3],
    +                                                  const char* UTF8String);
     
     CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
                                                       const char LanguageCode[3], const char CountryCode[3],
    @@ -1364,6 +1390,10 @@ CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
     CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
                                                      const char LanguageCode[3], const char CountryCode[3],
                                                      wchar_t* Buffer, cmsUInt32Number BufferSize);
    +CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetUTF8(const cmsMLU* mlu,
    +                                                 const char LanguageCode[3], const char CountryCode[3],
    +                                                 char* Buffer, cmsUInt32Number BufferSize);
    +
     
     CMSAPI cmsBool           CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
                                                              const char LanguageCode[3], const char CountryCode[3],
    @@ -1588,6 +1618,10 @@ CMSAPI cmsUInt32Number   CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile,
                                                                 const char LanguageCode[3], const char CountryCode[3],
                                                                 char* Buffer, cmsUInt32Number BufferSize);
     
    +CMSAPI cmsUInt32Number  CMSEXPORT cmsGetProfileInfoUTF8(cmsHPROFILE hProfile, cmsInfoType Info,
    +                                                            const char LanguageCode[3], const char CountryCode[3],
    +                                                            char* Buffer, cmsUInt32Number BufferSize);
    +
     // IO handlers ----------------------------------------------------------------------------------------------------------
     
     typedef struct _cms_io_handler cmsIOHANDLER;
    @@ -1650,6 +1684,9 @@ CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext C
     
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateInkLimitingDeviceLink(cmsColorSpaceSignature ColorSpace, cmsFloat64Number Limit);
     
    +CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateDeviceLinkFromCubeFile(const char* cFileName);
    +
    +CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, const char* cFileName);
     
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint);
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateLab2Profile(const cmsCIExyY* WhitePoint);
    @@ -1662,6 +1699,8 @@ CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateXYZProfile(void);
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID);
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_sRGBProfile(void);
     
    +CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_OkLabProfile(cmsContext ctx);
    +
     CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
                                                                  cmsUInt32Number nLUTPoints,
                                                                  cmsFloat64Number Bright,
    diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
    index 4c29a6c0218..75973edad0d 100644
    --- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
    +++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
    @@ -288,6 +288,7 @@ typedef CRITICAL_SECTION _cmsMutex;
     #ifdef _MSC_VER
     #    if (_MSC_VER >= 1800)
     #          pragma warning(disable : 26135)
    +#          pragma warning(disable : 4127)
     #    endif
     #endif
     
    @@ -545,7 +546,7 @@ struct _cmsContext_struct {
         struct _cmsContext_struct* Next;  // Points to next context in the new style
         _cmsSubAllocator* MemPool;        // The memory pool that stores context data
     
    -    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
    +    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is held in the suballocator.
                                           // If NULL, then it reverts to global Context0
     
         _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
    @@ -839,6 +840,9 @@ typedef struct _cms_iccprofile_struct {
         // Creation time
         struct tm                Created;
     
    +    // Color management module identification
    +    cmsUInt32Number          CMM;
    +
         // Only most important items found in ICC profiles
         cmsUInt32Number          Version;
         cmsProfileClassSignature DeviceClass;
    @@ -846,6 +850,7 @@ typedef struct _cms_iccprofile_struct {
         cmsColorSpaceSignature   PCS;
         cmsUInt32Number          RenderingIntent;
     
    +    cmsPlatformSignature     platform;
         cmsUInt32Number          flags;
         cmsUInt32Number          manufacturer, model;
         cmsUInt64Number          attributes;
    
    From 5431b82d06878cb6a9d0875c971bc481b69dca0b Mon Sep 17 00:00:00 2001
    From: Goetz Lindenmaier 
    Date: Thu, 14 Mar 2024 20:18:46 +0000
    Subject: [PATCH 071/298] 8322239: [macos] a11y :
     java.lang.NullPointerException is thrown when focus is moved on the
     JTabbedPane
    
    Backport-of: 3b1062d45df69d4cf8479c6a65602bd2453ab885
    ---
     .../classes/javax/swing/JTabbedPane.java      |  17 ++-
     .../swing/JTabbedPane/TabbedPaneNPECheck.java | 102 ++++++++++++++++++
     2 files changed, 115 insertions(+), 4 deletions(-)
     create mode 100644 test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java
    
    diff --git a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
    index 4ac249bf0f1..3a9d714061d 100644
    --- a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
    +++ b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2021, 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
    @@ -31,6 +31,7 @@
     import java.awt.Dimension;
     import java.awt.Font;
     import java.awt.FontMetrics;
    +import java.awt.IllegalComponentStateException;
     import java.awt.Point;
     import java.awt.Rectangle;
     import java.awt.event.FocusListener;
    @@ -2337,15 +2338,23 @@ public boolean contains(Point p) {
             }
     
             public Point getLocationOnScreen() {
    -             Point parentLocation = parent.getLocationOnScreen();
    +             Point parentLocation;
    +             try {
    +                 parentLocation = parent.getLocationOnScreen();
    +             } catch (IllegalComponentStateException icse) {
    +                 return null;
    +             }
                  Point componentLocation = getLocation();
    +             if (parentLocation == null || componentLocation == null) {
    +                 return null;
    +             }
                  componentLocation.translate(parentLocation.x, parentLocation.y);
                  return componentLocation;
             }
     
             public Point getLocation() {
                  Rectangle r = getBounds();
    -             return new Point(r.x, r.y);
    +             return r == null ? null : new Point(r.x, r.y);
             }
     
             public void setLocation(Point p) {
    @@ -2362,7 +2371,7 @@ public void setBounds(Rectangle r) {
     
             public Dimension getSize() {
                 Rectangle r = getBounds();
    -            return new Dimension(r.width, r.height);
    +            return r == null ? null : new Dimension(r.width, r.height);
             }
     
             public void setSize(Dimension d) {
    diff --git a/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java b/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java
    new file mode 100644
    index 00000000000..57321435bc4
    --- /dev/null
    +++ b/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java
    @@ -0,0 +1,102 @@
    +/*
    + * 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.
    + */
    +
    +/*
    + * @test
    + * @bug 8322239
    + * @summary [macos] a11y : java.lang.NullPointerException is thrown when
    + *          focus is moved on the JTabbedPane
    + * @key headful
    + * @run main TabbedPaneNPECheck
    + */
    +
    +import java.awt.BorderLayout;
    +import java.awt.Dimension;
    +import java.awt.Point;
    +import java.awt.Rectangle;
    +import java.lang.reflect.InvocationTargetException;
    +import javax.accessibility.Accessible;
    +import javax.accessibility.AccessibleComponent;
    +import javax.accessibility.AccessibleContext;
    +import javax.swing.JFrame;
    +import javax.swing.JPanel;
    +import javax.swing.JTabbedPane;
    +import javax.swing.SwingUtilities;
    +
    +public class TabbedPaneNPECheck {
    +    JTabbedPane pane;
    +    JFrame mainFrame;
    +    public static void main(String[] args) throws InterruptedException,
    +            InvocationTargetException {
    +        TabbedPaneNPECheck me = new TabbedPaneNPECheck();
    +        SwingUtilities.invokeAndWait(me::setupGUI);
    +        try {
    +            SwingUtilities.invokeAndWait(me::test);
    +        } finally {
    +            SwingUtilities.invokeAndWait(me::shutdownGUI);
    +        }
    +    }
    +
    +    public void setupGUI() {
    +        mainFrame = new JFrame("TabbedPaneNPECheck");
    +        pane = new JTabbedPane();
    +        Dimension panelSize = new Dimension(200, 200);
    +        for (int i = 0; i < 25; i++) {
    +            JPanel p = new JPanel();
    +            p.setMinimumSize(panelSize);
    +            p.setMaximumSize(panelSize);
    +            p.setSize(panelSize);
    +            pane.addTab("Tab no." + i, p);
    +        }
    +        mainFrame.setLayout(new BorderLayout());
    +        mainFrame.add(pane, BorderLayout.CENTER);
    +        mainFrame.setLocationRelativeTo(null);
    +        mainFrame.setSize(250, 250);
    +        mainFrame.setVisible(true);
    +    }
    +
    +    public void test() {
    +        AccessibleContext context = pane.getAccessibleContext();
    +        int nChild = context.getAccessibleChildrenCount();
    +        for (int i = 0; i < nChild; i++) {
    +            Accessible accessible = context.getAccessibleChild(i);
    +            if (accessible instanceof AccessibleComponent) {
    +                try {
    +                    AccessibleComponent component = (AccessibleComponent) accessible;
    +                    Point p = component.getLocationOnScreen();
    +                    Rectangle r = component.getBounds();
    +                } catch (NullPointerException npe) {
    +                    throw new RuntimeException("Unexpected NullPointerException " +
    +                            "while getting accessible component bounds: ", npe);
    +                }
    +            }
    +        }
    +    }
    +
    +    public void shutdownGUI() {
    +        if (mainFrame != null) {
    +            mainFrame.setVisible(false);
    +            mainFrame.dispose();
    +        }
    +    }
    +}
    
    From 6d8d049e4a7c77d8aa8a5d71446de1deb64d96e9 Mon Sep 17 00:00:00 2001
    From: Goetz Lindenmaier 
    Date: Thu, 14 Mar 2024 20:22:26 +0000
    Subject: [PATCH 072/298] 8324632: Update Zlib Data Compression Library to
     Version 1.3.1 8315117: Update Zlib Data Compression Library to Version 1.3
     8326351: Update the Zlib version in open/src/java.base/share/legal/zlib.md to
     1.3.1
    
    Backport-of: b5c267fc8a0af50be9e3d1d09cdaa6bf4bb29851
    ---
     src/java.base/share/legal/zlib.md             |   4 +-
     .../share/native/libzip/zlib/ChangeLog        | 217 +++++--
     src/java.base/share/native/libzip/zlib/README |  19 +-
     .../share/native/libzip/zlib/compress.c       |  21 +-
     .../share/native/libzip/zlib/deflate.c        | 612 ++++++++----------
     .../share/native/libzip/zlib/deflate.h        |  51 +-
     .../share/native/libzip/zlib/gzclose.c        |   4 +-
     .../share/native/libzip/zlib/gzguts.h         |  31 +-
     .../share/native/libzip/zlib/gzlib.c          | 113 +---
     .../share/native/libzip/zlib/gzread.c         |  88 +--
     .../share/native/libzip/zlib/gzwrite.c        |  84 +--
     .../share/native/libzip/zlib/infback.c        |  30 +-
     .../share/native/libzip/zlib/inffast.c        |   5 +-
     .../share/native/libzip/zlib/inffast.h        |   2 +-
     .../share/native/libzip/zlib/inflate.c        | 131 +---
     .../share/native/libzip/zlib/inftrees.c       |  17 +-
     .../share/native/libzip/zlib/inftrees.h       |  10 +-
     .../native/libzip/zlib/patches/ChangeLog_java |   2 +-
     .../share/native/libzip/zlib/trees.c          | 542 +++++++---------
     .../share/native/libzip/zlib/uncompr.c        |  16 +-
     .../share/native/libzip/zlib/zadler32.c       |  32 +-
     .../share/native/libzip/zlib/zconf.h          |  18 +-
     .../share/native/libzip/zlib/zcrc32.c         | 248 +++----
     src/java.base/share/native/libzip/zlib/zlib.h | 391 +++++------
     .../share/native/libzip/zlib/zutil.c          |  60 +-
     .../share/native/libzip/zlib/zutil.h          |  47 +-
     26 files changed, 1184 insertions(+), 1611 deletions(-)
    
    diff --git a/src/java.base/share/legal/zlib.md b/src/java.base/share/legal/zlib.md
    index d856af6ccd4..fcc5457bf5b 100644
    --- a/src/java.base/share/legal/zlib.md
    +++ b/src/java.base/share/legal/zlib.md
    @@ -1,9 +1,9 @@
    -## zlib v1.2.13
    +## zlib v1.3.1
     
     ### zlib License
     
     
    -Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
    +Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
     
     This software is provided 'as-is', without any express or implied
     warranty.  In no event will the authors be held liable for any damages
    diff --git a/src/java.base/share/native/libzip/zlib/ChangeLog b/src/java.base/share/native/libzip/zlib/ChangeLog
    index 9dbeb5e5642..b801a1031ec 100644
    --- a/src/java.base/share/native/libzip/zlib/ChangeLog
    +++ b/src/java.base/share/native/libzip/zlib/ChangeLog
    @@ -1,6 +1,109 @@
     
                     ChangeLog file for zlib
     
    +Changes in 1.3.1 (22 Jan 2024)
    +- Reject overflows of zip header fields in minizip
    +- Fix bug in inflateSync() for data held in bit buffer
    +- Add LIT_MEM define to use more memory for a small deflate speedup
    +- Fix decision on the emission of Zip64 end records in minizip
    +- Add bounds checking to ERR_MSG() macro, used by zError()
    +- Neutralize zip file traversal attacks in miniunz
    +- Fix a bug in ZLIB_DEBUG compiles in check_match()
    +- Various portability and appearance improvements
    +
    +Changes in 1.3 (18 Aug 2023)
    +- Remove K&R function definitions and zlib2ansi
    +- Fix bug in deflateBound() for level 0 and memLevel 9
    +- Fix bug when gzungetc() is used immediately after gzopen()
    +- Fix bug when using gzflush() with a very small buffer
    +- Fix crash when gzsetparams() attempted for transparent write
    +- Fix test/example.c to work with FORCE_STORED
    +- Rewrite of zran in examples (see zran.c version history)
    +- Fix minizip to allow it to open an empty zip file
    +- Fix reading disk number start on zip64 files in minizip
    +- Fix logic error in minizip argument processing
    +- Add minizip testing to Makefile
    +- Read multiple bytes instead of byte-by-byte in minizip unzip.c
    +- Add memory sanitizer to configure (--memory)
    +- Various portability improvements
    +- Various documentation improvements
    +- Various spelling and typo corrections
    +
    +Changes in 1.2.13 (13 Oct 2022)
    +- Fix configure issue that discarded provided CC definition
    +- Correct incorrect inputs provided to the CRC functions
    +- Repair prototypes and exporting of new CRC functions
    +- Fix inflateBack to detect invalid input with distances too far
    +- Have infback() deliver all of the available output up to any error
    +- Fix a bug when getting a gzip header extra field with inflate()
    +- Fix bug in block type selection when Z_FIXED used
    +- Tighten deflateBound bounds
    +- Remove deleted assembler code references
    +- Various portability and appearance improvements
    +
    +Changes in 1.2.12 (27 Mar 2022)
    +- Cygwin does not have _wopen(), so do not create gzopen_w() there
    +- Permit a deflateParams() parameter change as soon as possible
    +- Limit hash table inserts after switch from stored deflate
    +- Fix bug when window full in deflate_stored()
    +- Fix CLEAR_HASH macro to be usable as a single statement
    +- Avoid a conversion error in gzseek when off_t type too small
    +- Have Makefile return non-zero error code on test failure
    +- Avoid some conversion warnings in gzread.c and gzwrite.c
    +- Update use of errno for newer Windows CE versions
    +- Small speedup to inflate [psumbera]
    +- Return an error if the gzputs string length can't fit in an int
    +- Add address checking in clang to -w option of configure
    +- Don't compute check value for raw inflate if asked to validate
    +- Handle case where inflateSync used when header never processed
    +- Avoid the use of ptrdiff_t
    +- Avoid an undefined behavior of memcpy() in gzappend()
    +- Avoid undefined behaviors of memcpy() in gz*printf()
    +- Avoid an undefined behavior of memcpy() in _tr_stored_block()
    +- Make the names in functions declarations identical to definitions
    +- Remove old assembler code in which bugs have manifested
    +- Fix deflateEnd() to not report an error at start of raw deflate
    +- Add legal disclaimer to README
    +- Emphasize the need to continue decompressing gzip members
    +- Correct the initialization requirements for deflateInit2()
    +- Fix a bug that can crash deflate on some input when using Z_FIXED
    +- Assure that the number of bits for deflatePrime() is valid
    +- Use a structure to make globals in enough.c evident
    +- Use a macro for the printf format of big_t in enough.c
    +- Clean up code style in enough.c, update version
    +- Use inline function instead of macro for index in enough.c
    +- Clarify that prefix codes are counted in enough.c
    +- Show all the codes for the maximum tables size in enough.c
    +- Add gznorm.c example, which normalizes gzip files
    +- Fix the zran.c example to work on a multiple-member gzip file
    +- Add tables for crc32_combine(), to speed it up by a factor of 200
    +- Add crc32_combine_gen() and crc32_combine_op() for fast combines
    +- Speed up software CRC-32 computation by a factor of 1.5 to 3
    +- Use atomic test and set, if available, for dynamic CRC tables
    +- Don't bother computing check value after successful inflateSync()
    +- Correct comment in crc32.c
    +- Add use of the ARMv8 crc32 instructions when requested
    +- Use ARM crc32 instructions if the ARM architecture has them
    +- Explicitly note that the 32-bit check values are 32 bits
    +- Avoid adding empty gzip member after gzflush with Z_FINISH
    +- Fix memory leak on error in gzlog.c
    +- Fix error in comment on the polynomial representation of a byte
    +- Clarify gz* function interfaces, referring to parameter names
    +- Change macro name in inflate.c to avoid collision in VxWorks
    +- Correct typo in blast.c
    +- Improve portability of contrib/minizip
    +- Fix indentation in minizip's zip.c
    +- Replace black/white with allow/block. (theresa-m)
    +- minizip warning fix if MAXU32 already defined. (gvollant)
    +- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner)
    +- Clean up minizip to reduce warnings for testing
    +- Add fallthrough comments for gcc
    +- Eliminate use of ULL constants
    +- Separate out address sanitizing from warnings in configure
    +- Remove destructive aspects of make distclean
    +- Check for cc masquerading as gcc or clang in configure
    +- Fix crc32.c to compile local functions only if used
    +
     Changes in 1.2.11 (15 Jan 2017)
     - Fix deflate stored bug when pulling last block from window
     - Permit immediate deflateParams changes before any deflate input
    @@ -96,7 +199,7 @@ Changes in 1.2.7.1 (24 Mar 2013)
     - Fix types in contrib/minizip to match result of get_crc_table()
     - Simplify contrib/vstudio/vc10 with 'd' suffix
     - Add TOP support to win32/Makefile.msc
    -- Suport i686 and amd64 assembler builds in CMakeLists.txt
    +- Support i686 and amd64 assembler builds in CMakeLists.txt
     - Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
     - Add vc11 and vc12 build files to contrib/vstudio
     - Add gzvprintf() as an undocumented function in zlib
    @@ -296,15 +399,15 @@ Changes in 1.2.5.1 (10 Sep 2011)
     - Use u4 type for crc_table to avoid conversion warnings
     - Apply casts in zlib.h to avoid conversion warnings
     - Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
    -- Improve inflateSync() documentation to note indeterminancy
    +- Improve inflateSync() documentation to note indeterminacy
     - Add deflatePending() function to return the amount of pending output
     - Correct the spelling of "specification" in FAQ [Randers-Pehrson]
     - Add a check in configure for stdarg.h, use for gzprintf()
     - Check that pointers fit in ints when gzprint() compiled old style
     - Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
     - Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
    -- Add debug records in assmebler code [Londer]
    -- Update RFC references to use https://tools.ietf.org/html/... [Li]
    +- Add debug records in assembler code [Londer]
    +- Update RFC references to use http://tools.ietf.org/html/... [Li]
     - Add --archs option, use of libtool to configure for Mac OS X [Borstel]
     
     Changes in 1.2.5 (19 Apr 2010)
    @@ -511,7 +614,7 @@ Changes in 1.2.3.5 (8 Jan 2010)
     - Don't use _vsnprintf on later versions of MSVC [Lowman]
     - Add CMake build script and input file [Lowman]
     - Update contrib/minizip to 1.1 [Svensson, Vollant]
    -- Moved nintendods directory from contrib to .
    +- Moved nintendods directory from contrib to root
     - Replace gzio.c with a new set of routines with the same functionality
     - Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
     - Update contrib/minizip to 1.1b
    @@ -685,7 +788,7 @@ Changes in 1.2.2.4 (11 July 2005)
     - Be more strict on incomplete code sets in inflate_table() and increase
       ENOUGH and MAXD -- this repairs a possible security vulnerability for
       invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
    -  discovering the vulnerability and providing test cases.
    +  discovering the vulnerability and providing test cases
     - Add ia64 support to configure for HP-UX [Smith]
     - Add error return to gzread() for format or i/o error [Levin]
     - Use malloc.h for OS/2 [Necasek]
    @@ -721,7 +824,7 @@ Changes in 1.2.2.2 (30 December 2004)
     - Add Z_FIXED strategy option to deflateInit2() to force fixed trees
     - Add updated make_vms.com [Coghlan], update README
     - Create a new "examples" directory, move gzappend.c there, add zpipe.c,
    -  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
    +  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html
     - Add FAQ entry and comments in deflate.c on uninitialized memory access
     - Add Solaris 9 make options in configure [Gilbert]
     - Allow strerror() usage in gzio.c for STDC
    @@ -792,7 +895,7 @@ Changes in 1.2.1.1 (9 January 2004)
     - Fix a big fat bug in inftrees.c that prevented decoding valid
       dynamic blocks with only literals and no distance codes --
       Thanks to "Hot Emu" for the bug report and sample file
    -- Add a note to puff.c on no distance codes case.
    +- Add a note to puff.c on no distance codes case
     
     Changes in 1.2.1 (17 November 2003)
     - Remove a tab in contrib/gzappend/gzappend.c
    @@ -970,7 +1073,7 @@ Changes in 1.2.0.1 (17 March 2003)
         - Include additional header file on VMS for off_t typedef
     - Try to use _vsnprintf where it supplants vsprintf [Vollant]
     - Add some casts in inffast.c
    -- Enchance comments in zlib.h on what happens if gzprintf() tries to
    +- Enhance comments in zlib.h on what happens if gzprintf() tries to
       write more than 4095 bytes before compression
     - Remove unused state from inflateBackEnd()
     - Remove exit(0) from minigzip.c, example.c
    @@ -1036,14 +1139,14 @@ Changes in 1.2.0 (9 March 2003)
     - Add contrib/puff/ simple inflate for deflate format description
     
     Changes in 1.1.4 (11 March 2002)
    -- ZFREE was repeated on same allocation on some error conditions.
    +- ZFREE was repeated on same allocation on some error conditions
       This creates a security problem described in
       http://www.zlib.org/advisory-2002-03-11.txt
     - Returned incorrect error (Z_MEM_ERROR) on some invalid data
     - Avoid accesses before window for invalid distances with inflate window
    -  less than 32K.
    +  less than 32K
     - force windowBits > 8 to avoid a bug in the encoder for a window size
    -  of 256 bytes. (A complete fix will be available in 1.1.5).
    +  of 256 bytes. (A complete fix will be available in 1.1.5)
     
     Changes in 1.1.3 (9 July 1998)
     - fix "an inflate input buffer bug that shows up on rare but persistent
    @@ -1117,7 +1220,7 @@ Changes in 1.1.1 (27 Feb 98)
     - remove block truncation heuristic which had very marginal effect for zlib
       (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
       compression ratio on some files. This also allows inlining _tr_tally for
    -  matches in deflate_slow.
    +  matches in deflate_slow
     - added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
     
     Changes in 1.1.0 (24 Feb 98)
    @@ -1148,7 +1251,7 @@ Changes in 1.0.9 (17 Feb 1998)
     - Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
     - in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
     - in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
    -  the declaration of FAR (Gilles VOllant)
    +  the declaration of FAR (Gilles Vollant)
     - install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
     - read_buf buf parameter of type Bytef* instead of charf*
     - zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
    @@ -1162,7 +1265,7 @@ Changes in 1.0.8 (27 Jan 1998)
     - include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
     - use constant arrays for the static trees in trees.c instead of computing
       them at run time (thanks to Ken Raeburn for this suggestion). To create
    -  trees.h, compile with GEN_TREES_H and run "make test".
    +  trees.h, compile with GEN_TREES_H and run "make test"
     - check return code of example in "make test" and display result
     - pass minigzip command line options to file_compress
     - simplifying code of inflateSync to avoid gcc 2.8 bug
    @@ -1201,12 +1304,12 @@ Changes in 1.0.6 (19 Jan 1998)
     - add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
       gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
     - Fix a deflate bug occurring only with compression level 0 (thanks to
    -  Andy Buckler for finding this one).
    -- In minigzip, pass transparently also the first byte for .Z files.
    +  Andy Buckler for finding this one)
    +- In minigzip, pass transparently also the first byte for .Z files
     - return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
     - check Z_FINISH in inflate (thanks to Marc Schluper)
     - Implement deflateCopy (thanks to Adam Costello)
    -- make static libraries by default in configure, add --shared option.
    +- make static libraries by default in configure, add --shared option
     - move MSDOS or Windows specific files to directory msdos
     - suppress the notion of partial flush to simplify the interface
       (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
    @@ -1218,7 +1321,7 @@ Changes in 1.0.6 (19 Jan 1998)
     - added Makefile.nt (thanks to Stephen Williams)
     - added the unsupported "contrib" directory:
        contrib/asm386/ by Gilles Vollant 
    -        386 asm code replacing longest_match().
    +        386 asm code replacing longest_match()
        contrib/iostream/ by Kevin Ruland 
             A C++ I/O streams interface to the zlib gz* functions
        contrib/iostream2/  by Tyge Løvset 
    @@ -1226,7 +1329,7 @@ Changes in 1.0.6 (19 Jan 1998)
        contrib/untgz/  by "Pedro A. Aranda Guti\irrez" 
             A very simple tar.gz file extractor using zlib
        contrib/visual-basic.txt by Carlos Rios 
    -        How to use compress(), uncompress() and the gz* functions from VB.
    +        How to use compress(), uncompress() and the gz* functions from VB
     - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
       level) in minigzip (thanks to Tom Lane)
     
    @@ -1235,8 +1338,8 @@ Changes in 1.0.6 (19 Jan 1998)
     - add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
     - add undocumented function zError to convert error code to string
       (for Tim Smithers)
    -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
    -- Use default memcpy for Symantec MSDOS compiler.
    +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code
    +- Use default memcpy for Symantec MSDOS compiler
     - Add EXPORT keyword for check_func (needed for Windows DLL)
     - add current directory to LD_LIBRARY_PATH for "make test"
     - create also a link for libz.so.1
    @@ -1249,7 +1352,7 @@ Changes in 1.0.6 (19 Jan 1998)
     - allow compilation with ANSI keywords only enabled for TurboC in large model
     - avoid "versionString"[0] (Borland bug)
     - add NEED_DUMMY_RETURN for Borland
    -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
    +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch)
     - allow compilation with CC
     - defined STDC for OS/2 (David Charlap)
     - limit external names to 8 chars for MVS (Thomas Lund)
    @@ -1259,7 +1362,7 @@ Changes in 1.0.6 (19 Jan 1998)
     - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
     - added makelcc.bat for lcc-win32 (Tom St Denis)
     - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
    -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
    +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion
     - check for unistd.h in configure (for off_t)
     - remove useless check parameter in inflate_blocks_free
     - avoid useless assignment of s->check to itself in inflate_blocks_new
    @@ -1280,7 +1383,7 @@ Changes in 1.0.5 (3 Jan 98)
     Changes in 1.0.4 (24 Jul 96)
     - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
       bit, so the decompressor could decompress all the correct data but went
    -  on to attempt decompressing extra garbage data. This affected minigzip too.
    +  on to attempt decompressing extra garbage data. This affected minigzip too
     - zlibVersion and gzerror return const char* (needed for DLL)
     - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
     - use z_error only for DEBUG (avoid problem with DLLs)
    @@ -1310,7 +1413,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
     - fix array overlay in deflate.c which sometimes caused bad compressed data
     - fix inflate bug with empty stored block
     - fix MSDOS medium model which was broken in 0.99
    -- fix deflateParams() which could generate bad compressed data.
    +- fix deflateParams() which could generate bad compressed data
     - Bytef is define'd instead of typedef'ed (work around Borland bug)
     - added an INDEX file
     - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
    @@ -1331,7 +1434,7 @@ Changes in 0.99 (27 Jan 96)
     - allow preset dictionary shared between compressor and decompressor
     - allow compression level 0 (no compression)
     - add deflateParams in zlib.h: allow dynamic change of compression level
    -  and compression strategy.
    +  and compression strategy
     - test large buffers and deflateParams in example.c
     - add optional "configure" to build zlib as a shared library
     - suppress Makefile.qnx, use configure instead
    @@ -1370,33 +1473,33 @@ Changes in 0.99 (27 Jan 96)
     - fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
     - in fcalloc, normalize pointer if size > 65520 bytes
     - don't use special fcalloc for 32 bit Borland C++
    -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
    +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc.
     - use Z_BINARY instead of BINARY
     - document that gzclose after gzdopen will close the file
    -- allow "a" as mode in gzopen.
    +- allow "a" as mode in gzopen
     - fix error checking in gzread
     - allow skipping .gz extra-field on pipes
     - added reference to Perl interface in README
     - put the crc table in FAR data (I dislike more and more the medium model :)
     - added get_crc_table
    -- added a dimension to all arrays (Borland C can't count).
    +- added a dimension to all arrays (Borland C can't count)
     - workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
     - guard against multiple inclusion of *.h (for precompiled header on Mac)
    -- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
    +- Watcom C pretends to be Microsoft C small model even in 32 bit mode
     - don't use unsized arrays to avoid silly warnings by Visual C++:
          warning C4746: 'inflate_mask' : unsized array treated as  '__far'
    -     (what's wrong with far data in far model?).
    +     (what's wrong with far data in far model?)
     - define enum out of inflate_blocks_state to allow compilation with C++
     
     Changes in 0.95 (16 Aug 95)
     - fix MSDOS small and medium model (now easier to adapt to any compiler)
     - inlined send_bits
     - fix the final (:-) bug for deflate with flush (output was correct but
    -  not completely flushed in rare occasions).
    +  not completely flushed in rare occasions)
     - default window size is same for compression and decompression
    -  (it's now sufficient to set MAX_WBITS in zconf.h).
    +  (it's now sufficient to set MAX_WBITS in zconf.h)
     - voidp -> voidpf and voidnp -> voidp (for consistency with other
    -  typedefs and because voidnp was not near in large model).
    +  typedefs and because voidnp was not near in large model)
     
     Changes in 0.94 (13 Aug 95)
     - support MSDOS medium model
    @@ -1405,12 +1508,12 @@ Changes in 0.94 (13 Aug 95)
     - added support for VMS
     - allow a compression level in gzopen()
     - gzflush now calls fflush
    -- For deflate with flush, flush even if no more input is provided.
    +- For deflate with flush, flush even if no more input is provided
     - rename libgz.a as libz.a
     - avoid complex expression in infcodes.c triggering Turbo C bug
     - work around a problem with gcc on Alpha (in INSERT_STRING)
     - don't use inline functions (problem with some gcc versions)
    -- allow renaming of Byte, uInt, etc... with #define.
    +- allow renaming of Byte, uInt, etc... with #define
     - avoid warning about (unused) pointer before start of array in deflate.c
     - avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
     - avoid reserved word 'new' in trees.c
    @@ -1429,7 +1532,7 @@ Changes in 0.92 (3 May 95)
     - no memcpy on Pyramid
     - suppressed inftest.c
     - optimized fill_window, put longest_match inline for gcc
    -- optimized inflate on stored blocks.
    +- optimized inflate on stored blocks
     - untabify all sources to simplify patches
     
     Changes in 0.91 (2 May 95)
    @@ -1447,7 +1550,7 @@ Changes in 0.9 (1 May 95)
     - let again gzread copy uncompressed data unchanged (was working in 0.71)
     - deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
     - added a test of inflateSync in example.c
    -- moved MAX_WBITS to zconf.h because users might want to change that.
    +- moved MAX_WBITS to zconf.h because users might want to change that
     - document explicitly that zalloc(64K) on MSDOS must return a normalized
       pointer (zero offset)
     - added Makefiles for Microsoft C, Turbo C, Borland C++
    @@ -1456,7 +1559,7 @@ Changes in 0.9 (1 May 95)
     Changes in 0.8 (29 April 95)
     - added fast inflate (inffast.c)
     - deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
    -  is incompatible with previous versions of zlib which returned Z_OK.
    +  is incompatible with previous versions of zlib which returned Z_OK
     - work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
       (actually that was not a compiler bug, see 0.81 above)
     - gzread no longer reads one extra byte in certain cases
    @@ -1466,50 +1569,50 @@ Changes in 0.8 (29 April 95)
     
     Changes in 0.71 (14 April 95)
     - Fixed more MSDOS compilation problems :( There is still a bug with
    -  TurboC large model.
    +  TurboC large model
     
     Changes in 0.7 (14 April 95)
    -- Added full inflate support.
    +- Added full inflate support
     - Simplified the crc32() interface. The pre- and post-conditioning
       (one's complement) is now done inside crc32(). WARNING: this is
    -  incompatible with previous versions; see zlib.h for the new usage.
    +  incompatible with previous versions; see zlib.h for the new usage
     
     Changes in 0.61 (12 April 95)
    -- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
    +- workaround for a bug in TurboC. example and minigzip now work on MSDOS
     
     Changes in 0.6 (11 April 95)
     - added minigzip.c
     - added gzdopen to reopen a file descriptor as gzFile
    -- added transparent reading of non-gziped files in gzread.
    +- added transparent reading of non-gziped files in gzread
     - fixed bug in gzread (don't read crc as data)
    -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
    +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose)
     - don't allocate big arrays in the stack (for MSDOS)
     - fix some MSDOS compilation problems
     
     Changes in 0.5:
     - do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
    -  not yet Z_FULL_FLUSH.
    +  not yet Z_FULL_FLUSH
     - support decompression but only in a single step (forced Z_FINISH)
    -- added opaque object for zalloc and zfree.
    +- added opaque object for zalloc and zfree
     - added deflateReset and inflateReset
    -- added a variable zlib_version for consistency checking.
    -- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
    -  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
    +- added a variable zlib_version for consistency checking
    +- renamed the 'filter' parameter of deflateInit2 as 'strategy'
    +  Added Z_FILTERED and Z_HUFFMAN_ONLY constants
     
     Changes in 0.4:
    -- avoid "zip" everywhere, use zlib instead of ziplib.
    +- avoid "zip" everywhere, use zlib instead of ziplib
     - suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
    -  if compression method == 8.
    +  if compression method == 8
     - added adler32 and crc32
     - renamed deflateOptions as deflateInit2, call one or the other but not both
    -- added the method parameter for deflateInit2.
    +- added the method parameter for deflateInit2
     - added inflateInit2
    -- simplied considerably deflateInit and inflateInit by not supporting
    +- simplified considerably deflateInit and inflateInit by not supporting
       user-provided history buffer. This is supported only in deflateInit2
    -  and inflateInit2.
    +  and inflateInit2
     
     Changes in 0.3:
     - prefix all macro names with Z_
    -- use Z_FINISH instead of deflateEnd to finish compression.
    +- use Z_FINISH instead of deflateEnd to finish compression
     - added Z_HUFFMAN_ONLY
     - added gzerror()
    diff --git a/src/java.base/share/native/libzip/zlib/README b/src/java.base/share/native/libzip/zlib/README
    index ba34d1894a9..c5f917540b6 100644
    --- a/src/java.base/share/native/libzip/zlib/README
    +++ b/src/java.base/share/native/libzip/zlib/README
    @@ -1,6 +1,6 @@
     ZLIB DATA COMPRESSION LIBRARY
     
    -zlib 1.2.13 is a general purpose data compression library.  All the code is
    +zlib 1.3.1 is a general purpose data compression library.  All the code is
     thread safe.  The data format used by the zlib library is described by RFCs
     (Request for Comments) 1950 to 1952 in the files
     http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
    @@ -29,18 +29,17 @@ PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
     
     Mark Nelson  wrote an article about zlib for the Jan.  1997
     issue of Dr.  Dobb's Journal; a copy of the article is available at
    -http://marknelson.us/1997/01/01/zlib-engine/ .
    +https://marknelson.us/posts/1997/01/01/zlib-engine.html .
     
    -The changes made in version 1.2.13 are documented in the file ChangeLog.
    +The changes made in version 1.3.1 are documented in the file ChangeLog.
     
     Unsupported third party contributions are provided in directory contrib/ .
     
    -zlib is available in Java using the java.util.zip package, documented at
    -http://java.sun.com/developer/technicalArticles/Programming/compression/ .
    +zlib is available in Java using the java.util.zip package. Follow the API
    +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip .
     
    -A Perl interface to zlib written by Paul Marquess  is available
    -at CPAN (Comprehensive Perl Archive Network) sites, including
    -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
    +A Perl interface to zlib and bzip2 written by Paul Marquess 
    +can be found at https://github.com/pmqs/IO-Compress .
     
     A Python interface to zlib written by A.M. Kuchling  is
     available in Python 1.5 and later versions, see
    @@ -64,7 +63,7 @@ Notes for some targets:
     - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
       when compiled with cc.
     
    -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
    +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is
       necessary to get gzprintf working correctly. This is done by configure.
     
     - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
    @@ -84,7 +83,7 @@ Acknowledgments:
     
     Copyright notice:
     
    - (C) 1995-2022 Jean-loup Gailly and Mark Adler
    + (C) 1995-2024 Jean-loup Gailly and Mark Adler
     
       This software is provided 'as-is', without any express or implied
       warranty.  In no event will the authors be held liable for any damages
    diff --git a/src/java.base/share/native/libzip/zlib/compress.c b/src/java.base/share/native/libzip/zlib/compress.c
    index bc090096785..d7421379673 100644
    --- a/src/java.base/share/native/libzip/zlib/compress.c
    +++ b/src/java.base/share/native/libzip/zlib/compress.c
    @@ -43,13 +43,8 @@
        memory, Z_BUF_ERROR if there was not enough room in the output buffer,
        Z_STREAM_ERROR if the level parameter is invalid.
     */
    -int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
    -    Bytef *dest;
    -    uLongf *destLen;
    -    const Bytef *source;
    -    uLong sourceLen;
    -    int level;
    -{
    +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
    +                      uLong sourceLen, int level) {
         z_stream stream;
         int err;
         const uInt max = (uInt)-1;
    @@ -89,12 +84,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
     
     /* ===========================================================================
      */
    -int ZEXPORT compress(dest, destLen, source, sourceLen)
    -    Bytef *dest;
    -    uLongf *destLen;
    -    const Bytef *source;
    -    uLong sourceLen;
    -{
    +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,
    +                     uLong sourceLen) {
         return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
     }
     
    @@ -102,9 +93,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen)
          If the default memLevel or windowBits for deflateInit() is changed, then
        this function needs to be updated.
      */
    -uLong ZEXPORT compressBound(sourceLen)
    -    uLong sourceLen;
    -{
    +uLong ZEXPORT compressBound(uLong sourceLen) {
         return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
                (sourceLen >> 25) + 13;
     }
    diff --git a/src/java.base/share/native/libzip/zlib/deflate.c b/src/java.base/share/native/libzip/zlib/deflate.c
    index 46d512d4200..57fc6802bb8 100644
    --- a/src/java.base/share/native/libzip/zlib/deflate.c
    +++ b/src/java.base/share/native/libzip/zlib/deflate.c
    @@ -23,7 +23,7 @@
      */
     
     /* deflate.c -- compress data using the deflation algorithm
    - * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
    + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -76,7 +76,7 @@
     #include "deflate.h"
     
     const char deflate_copyright[] =
    -   " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
    +   " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler ";
     /*
       If you use the zlib library in a product, an acknowledgment is welcome
       in the documentation of your product. If for some reason you cannot
    @@ -84,9 +84,6 @@ const char deflate_copyright[] =
       copyright string in the executable of your product.
      */
     
    -/* ===========================================================================
    - *  Function prototypes.
    - */
     typedef enum {
         need_more,      /* block not completed, need more input or more output */
         block_done,     /* block flush performed */
    @@ -94,29 +91,16 @@ typedef enum {
         finish_done     /* finish done, accept no more input or output */
     } block_state;
     
    -typedef block_state (*compress_func) OF((deflate_state *s, int flush));
    +typedef block_state (*compress_func)(deflate_state *s, int flush);
     /* Compression function. Returns the block state after the call. */
     
    -local int deflateStateCheck      OF((z_streamp strm));
    -local void slide_hash     OF((deflate_state *s));
    -local void fill_window    OF((deflate_state *s));
    -local block_state deflate_stored OF((deflate_state *s, int flush));
    -local block_state deflate_fast   OF((deflate_state *s, int flush));
    +local block_state deflate_stored(deflate_state *s, int flush);
    +local block_state deflate_fast(deflate_state *s, int flush);
     #ifndef FASTEST
    -local block_state deflate_slow   OF((deflate_state *s, int flush));
    -#endif
    -local block_state deflate_rle    OF((deflate_state *s, int flush));
    -local block_state deflate_huff   OF((deflate_state *s, int flush));
    -local void lm_init        OF((deflate_state *s));
    -local void putShortMSB    OF((deflate_state *s, uInt b));
    -local void flush_pending  OF((z_streamp strm));
    -local unsigned read_buf   OF((z_streamp strm, Bytef *buf, unsigned size));
    -local uInt longest_match  OF((deflate_state *s, IPos cur_match));
    -
    -#ifdef ZLIB_DEBUG
    -local  void check_match OF((deflate_state *s, IPos start, IPos match,
    -                            int length));
    +local block_state deflate_slow(deflate_state *s, int flush);
     #endif
    +local block_state deflate_rle(deflate_state *s, int flush);
    +local block_state deflate_huff(deflate_state *s, int flush);
     
     /* ===========================================================================
      * Local data
    @@ -219,9 +203,12 @@ local const config configuration_table[10] = {
      * bit values at the expense of memory usage). We slide even when level == 0 to
      * keep the hash table consistent if we switch back to level > 0 later.
      */
    -local void slide_hash(s)
    -    deflate_state *s;
    -{
    +#if defined(__has_feature)
    +#  if __has_feature(memory_sanitizer)
    +     __attribute__((no_sanitize("memory")))
    +#  endif
    +#endif
    +local void slide_hash(deflate_state *s) {
         unsigned n, m;
         Posf *p;
         uInt wsize = s->w_size;
    @@ -245,30 +232,177 @@ local void slide_hash(s)
     #endif
     }
     
    +/* ===========================================================================
    + * Read a new buffer from the current input stream, update the adler32
    + * and total number of bytes read.  All deflate() input goes through
    + * this function so some applications may wish to modify it to avoid
    + * allocating a large strm->next_in buffer and copying from it.
    + * (See also flush_pending()).
    + */
    +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) {
    +    unsigned len = strm->avail_in;
    +
    +    if (len > size) len = size;
    +    if (len == 0) return 0;
    +
    +    strm->avail_in  -= len;
    +
    +    zmemcpy(buf, strm->next_in, len);
    +    if (strm->state->wrap == 1) {
    +        strm->adler = adler32(strm->adler, buf, len);
    +    }
    +#ifdef GZIP
    +    else if (strm->state->wrap == 2) {
    +        strm->adler = crc32(strm->adler, buf, len);
    +    }
    +#endif
    +    strm->next_in  += len;
    +    strm->total_in += len;
    +
    +    return len;
    +}
    +
    +/* ===========================================================================
    + * Fill the window when the lookahead becomes insufficient.
    + * Updates strstart and lookahead.
    + *
    + * IN assertion: lookahead < MIN_LOOKAHEAD
    + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
    + *    At least one byte has been read, or avail_in == 0; reads are
    + *    performed for at least two bytes (required for the zip translate_eol
    + *    option -- not supported here).
    + */
    +local void fill_window(deflate_state *s) {
    +    unsigned n;
    +    unsigned more;    /* Amount of free space at the end of the window. */
    +    uInt wsize = s->w_size;
    +
    +    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
    +
    +    do {
    +        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
    +
    +        /* Deal with !@#$% 64K limit: */
    +        if (sizeof(int) <= 2) {
    +            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
    +                more = wsize;
    +
    +            } else if (more == (unsigned)(-1)) {
    +                /* Very unlikely, but possible on 16 bit machine if
    +                 * strstart == 0 && lookahead == 1 (input done a byte at time)
    +                 */
    +                more--;
    +            }
    +        }
    +
    +        /* If the window is almost full and there is insufficient lookahead,
    +         * move the upper half to the lower one to make room in the upper half.
    +         */
    +        if (s->strstart >= wsize + MAX_DIST(s)) {
    +
    +            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
    +            s->match_start -= wsize;
    +            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
    +            s->block_start -= (long) wsize;
    +            if (s->insert > s->strstart)
    +                s->insert = s->strstart;
    +            slide_hash(s);
    +            more += wsize;
    +        }
    +        if (s->strm->avail_in == 0) break;
    +
    +        /* If there was no sliding:
    +         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
    +         *    more == window_size - lookahead - strstart
    +         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
    +         * => more >= window_size - 2*WSIZE + 2
    +         * In the BIG_MEM or MMAP case (not yet supported),
    +         *   window_size == input_size + MIN_LOOKAHEAD  &&
    +         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
    +         * Otherwise, window_size == 2*WSIZE so more >= 2.
    +         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
    +         */
    +        Assert(more >= 2, "more < 2");
    +
    +        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
    +        s->lookahead += n;
    +
    +        /* Initialize the hash value now that we have some input: */
    +        if (s->lookahead + s->insert >= MIN_MATCH) {
    +            uInt str = s->strstart - s->insert;
    +            s->ins_h = s->window[str];
    +            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
    +#if MIN_MATCH != 3
    +            Call UPDATE_HASH() MIN_MATCH-3 more times
    +#endif
    +            while (s->insert) {
    +                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
    +#ifndef FASTEST
    +                s->prev[str & s->w_mask] = s->head[s->ins_h];
    +#endif
    +                s->head[s->ins_h] = (Pos)str;
    +                str++;
    +                s->insert--;
    +                if (s->lookahead + s->insert < MIN_MATCH)
    +                    break;
    +            }
    +        }
    +        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
    +         * but this is not important since only literal bytes will be emitted.
    +         */
    +
    +    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
    +
    +    /* If the WIN_INIT bytes after the end of the current data have never been
    +     * written, then zero those bytes in order to avoid memory check reports of
    +     * the use of uninitialized (or uninitialised as Julian writes) bytes by
    +     * the longest match routines.  Update the high water mark for the next
    +     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
    +     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
    +     */
    +    if (s->high_water < s->window_size) {
    +        ulg curr = s->strstart + (ulg)(s->lookahead);
    +        ulg init;
    +
    +        if (s->high_water < curr) {
    +            /* Previous high water mark below current data -- zero WIN_INIT
    +             * bytes or up to end of window, whichever is less.
    +             */
    +            init = s->window_size - curr;
    +            if (init > WIN_INIT)
    +                init = WIN_INIT;
    +            zmemzero(s->window + curr, (unsigned)init);
    +            s->high_water = curr + init;
    +        }
    +        else if (s->high_water < (ulg)curr + WIN_INIT) {
    +            /* High water mark at or above current data, but below current data
    +             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
    +             * to end of window, whichever is less.
    +             */
    +            init = (ulg)curr + WIN_INIT - s->high_water;
    +            if (init > s->window_size - s->high_water)
    +                init = s->window_size - s->high_water;
    +            zmemzero(s->window + s->high_water, (unsigned)init);
    +            s->high_water += init;
    +        }
    +    }
    +
    +    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
    +           "not enough room for search");
    +}
    +
     /* ========================================================================= */
    -int ZEXPORT deflateInit_(strm, level, version, stream_size)
    -    z_streamp strm;
    -    int level;
    -    const char *version;
    -    int stream_size;
    -{
    +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version,
    +                         int stream_size) {
         return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
                              Z_DEFAULT_STRATEGY, version, stream_size);
         /* To do: ignore strm->next_in if we use it as window */
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
    -                  version, stream_size)
    -    z_streamp strm;
    -    int  level;
    -    int  method;
    -    int  windowBits;
    -    int  memLevel;
    -    int  strategy;
    -    const char *version;
    -    int stream_size;
    -{
    +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
    +                          int windowBits, int memLevel, int strategy,
    +                          const char *version, int stream_size) {
         deflate_state *s;
         int wrap = 1;
         static const char my_version[] = ZLIB_VERSION;
    @@ -383,7 +517,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
          * symbols from which it is being constructed.
          */
     
    -    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
    +    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS);
         s->pending_buf_size = (ulg)s->lit_bufsize * 4;
     
         if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
    @@ -393,8 +527,14 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
             deflateEnd (strm);
             return Z_MEM_ERROR;
         }
    +#ifdef LIT_MEM
    +    s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
    +    s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
    +    s->sym_end = s->lit_bufsize - 1;
    +#else
         s->sym_buf = s->pending_buf + s->lit_bufsize;
         s->sym_end = (s->lit_bufsize - 1) * 3;
    +#endif
         /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
          * on 16 bit machines and because stored blocks are restricted to
          * 64K-1 bytes.
    @@ -410,9 +550,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
     /* =========================================================================
      * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
      */
    -local int deflateStateCheck(strm)
    -    z_streamp strm;
    -{
    +local int deflateStateCheck(z_streamp strm) {
         deflate_state *s;
         if (strm == Z_NULL ||
             strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
    @@ -433,11 +571,8 @@ local int deflateStateCheck(strm)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
    -    z_streamp strm;
    -    const Bytef *dictionary;
    -    uInt  dictLength;
    -{
    +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary,
    +                                 uInt  dictLength) {
         deflate_state *s;
         uInt str, n;
         int wrap;
    @@ -502,11 +637,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
    -    z_streamp strm;
    -    Bytef *dictionary;
    -    uInt  *dictLength;
    -{
    +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary,
    +                                 uInt *dictLength) {
         deflate_state *s;
         uInt len;
     
    @@ -524,9 +656,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateResetKeep(strm)
    -    z_streamp strm;
    -{
    +int ZEXPORT deflateResetKeep(z_streamp strm) {
         deflate_state *s;
     
         if (deflateStateCheck(strm)) {
    @@ -561,10 +691,32 @@ int ZEXPORT deflateResetKeep(strm)
         return Z_OK;
     }
     
    +/* ===========================================================================
    + * Initialize the "longest match" routines for a new zlib stream
    + */
    +local void lm_init(deflate_state *s) {
    +    s->window_size = (ulg)2L*s->w_size;
    +
    +    CLEAR_HASH(s);
    +
    +    /* Set the default configuration parameters:
    +     */
    +    s->max_lazy_match   = configuration_table[s->level].max_lazy;
    +    s->good_match       = configuration_table[s->level].good_length;
    +    s->nice_match       = configuration_table[s->level].nice_length;
    +    s->max_chain_length = configuration_table[s->level].max_chain;
    +
    +    s->strstart = 0;
    +    s->block_start = 0L;
    +    s->lookahead = 0;
    +    s->insert = 0;
    +    s->match_length = s->prev_length = MIN_MATCH-1;
    +    s->match_available = 0;
    +    s->ins_h = 0;
    +}
    +
     /* ========================================================================= */
    -int ZEXPORT deflateReset(strm)
    -    z_streamp strm;
    -{
    +int ZEXPORT deflateReset(z_streamp strm) {
         int ret;
     
         ret = deflateResetKeep(strm);
    @@ -574,10 +726,7 @@ int ZEXPORT deflateReset(strm)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateSetHeader(strm, head)
    -    z_streamp strm;
    -    gz_headerp head;
    -{
    +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {
         if (deflateStateCheck(strm) || strm->state->wrap != 2)
             return Z_STREAM_ERROR;
         strm->state->gzhead = head;
    @@ -585,11 +734,7 @@ int ZEXPORT deflateSetHeader(strm, head)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflatePending(strm, pending, bits)
    -    unsigned *pending;
    -    int *bits;
    -    z_streamp strm;
    -{
    +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
         if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
         if (pending != Z_NULL)
             *pending = strm->state->pending;
    @@ -599,19 +744,21 @@ int ZEXPORT deflatePending(strm, pending, bits)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflatePrime(strm, bits, value)
    -    z_streamp strm;
    -    int bits;
    -    int value;
    -{
    +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
         deflate_state *s;
         int put;
     
         if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
         s = strm->state;
    +#ifdef LIT_MEM
    +    if (bits < 0 || bits > 16 ||
    +        (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
    +        return Z_BUF_ERROR;
    +#else
         if (bits < 0 || bits > 16 ||
             s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
             return Z_BUF_ERROR;
    +#endif
         do {
             put = Buf_size - s->bi_valid;
             if (put > bits)
    @@ -626,11 +773,7 @@ int ZEXPORT deflatePrime(strm, bits, value)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateParams(strm, level, strategy)
    -    z_streamp strm;
    -    int level;
    -    int strategy;
    -{
    +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) {
         deflate_state *s;
         compress_func func;
     
    @@ -675,13 +818,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
    -    z_streamp strm;
    -    int good_length;
    -    int max_lazy;
    -    int nice_length;
    -    int max_chain;
    -{
    +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy,
    +                        int nice_length, int max_chain) {
         deflate_state *s;
     
         if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -717,10 +855,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
      *
      * Shifts are used to approximate divisions, for speed.
      */
    -uLong ZEXPORT deflateBound(strm, sourceLen)
    -    z_streamp strm;
    -    uLong sourceLen;
    -{
    +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
         deflate_state *s;
         uLong fixedlen, storelen, wraplen;
     
    @@ -776,7 +911,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
     
         /* if not default parameters, return one of the conservative bounds */
         if (s->w_bits != 15 || s->hash_bits != 8 + 7)
    -        return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen;
    +        return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
    +               wraplen;
     
         /* default settings: return tight bound for that case -- ~0.03% overhead
            plus a small constant */
    @@ -789,10 +925,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
      * IN assertion: the stream state is correct and there is enough room in
      * pending_buf.
      */
    -local void putShortMSB(s, b)
    -    deflate_state *s;
    -    uInt b;
    -{
    +local void putShortMSB(deflate_state *s, uInt b) {
         put_byte(s, (Byte)(b >> 8));
         put_byte(s, (Byte)(b & 0xff));
     }
    @@ -803,9 +936,7 @@ local void putShortMSB(s, b)
      * applications may wish to modify it to avoid allocating a large
      * strm->next_out buffer and copying into it. (See also read_buf()).
      */
    -local void flush_pending(strm)
    -    z_streamp strm;
    -{
    +local void flush_pending(z_streamp strm) {
         unsigned len;
         deflate_state *s = strm->state;
     
    @@ -836,10 +967,7 @@ local void flush_pending(strm)
         } while (0)
     
     /* ========================================================================= */
    -int ZEXPORT deflate(strm, flush)
    -    z_streamp strm;
    -    int flush;
    -{
    +int ZEXPORT deflate(z_streamp strm, int flush) {
         int old_flush; /* value of flush param for previous deflate call */
         deflate_state *s;
     
    @@ -1151,9 +1279,7 @@ int ZEXPORT deflate(strm, flush)
     }
     
     /* ========================================================================= */
    -int ZEXPORT deflateEnd(strm)
    -    z_streamp strm;
    -{
    +int ZEXPORT deflateEnd(z_streamp strm) {
         int status;
     
         if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -1177,11 +1303,10 @@ int ZEXPORT deflateEnd(strm)
      * To simplify the source, this is not supported for 16-bit MSDOS (which
      * doesn't have enough memory anyway to duplicate compression states).
      */
    -int ZEXPORT deflateCopy(dest, source)
    -    z_streamp dest;
    -    z_streamp source;
    -{
    +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
     #ifdef MAXSEG_64K
    +    (void)dest;
    +    (void)source;
         return Z_STREAM_ERROR;
     #else
         deflate_state *ds;
    @@ -1205,7 +1330,7 @@ int ZEXPORT deflateCopy(dest, source)
         ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
         ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
         ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
    -    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
    +    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS);
     
         if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
             ds->pending_buf == Z_NULL) {
    @@ -1216,10 +1341,15 @@ int ZEXPORT deflateCopy(dest, source)
         zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
         zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
         zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
    -    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
    +    zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS);
     
         ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
    +#ifdef LIT_MEM
    +    ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
    +    ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
    +#else
         ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
    +#endif
     
         ds->l_desc.dyn_tree = ds->dyn_ltree;
         ds->d_desc.dyn_tree = ds->dyn_dtree;
    @@ -1229,66 +1359,6 @@ int ZEXPORT deflateCopy(dest, source)
     #endif /* MAXSEG_64K */
     }
     
    -/* ===========================================================================
    - * Read a new buffer from the current input stream, update the adler32
    - * and total number of bytes read.  All deflate() input goes through
    - * this function so some applications may wish to modify it to avoid
    - * allocating a large strm->next_in buffer and copying from it.
    - * (See also flush_pending()).
    - */
    -local unsigned read_buf(strm, buf, size)
    -    z_streamp strm;
    -    Bytef *buf;
    -    unsigned size;
    -{
    -    unsigned len = strm->avail_in;
    -
    -    if (len > size) len = size;
    -    if (len == 0) return 0;
    -
    -    strm->avail_in  -= len;
    -
    -    zmemcpy(buf, strm->next_in, len);
    -    if (strm->state->wrap == 1) {
    -        strm->adler = adler32(strm->adler, buf, len);
    -    }
    -#ifdef GZIP
    -    else if (strm->state->wrap == 2) {
    -        strm->adler = crc32(strm->adler, buf, len);
    -    }
    -#endif
    -    strm->next_in  += len;
    -    strm->total_in += len;
    -
    -    return len;
    -}
    -
    -/* ===========================================================================
    - * Initialize the "longest match" routines for a new zlib stream
    - */
    -local void lm_init(s)
    -    deflate_state *s;
    -{
    -    s->window_size = (ulg)2L*s->w_size;
    -
    -    CLEAR_HASH(s);
    -
    -    /* Set the default configuration parameters:
    -     */
    -    s->max_lazy_match   = configuration_table[s->level].max_lazy;
    -    s->good_match       = configuration_table[s->level].good_length;
    -    s->nice_match       = configuration_table[s->level].nice_length;
    -    s->max_chain_length = configuration_table[s->level].max_chain;
    -
    -    s->strstart = 0;
    -    s->block_start = 0L;
    -    s->lookahead = 0;
    -    s->insert = 0;
    -    s->match_length = s->prev_length = MIN_MATCH-1;
    -    s->match_available = 0;
    -    s->ins_h = 0;
    -}
    -
     #ifndef FASTEST
     /* ===========================================================================
      * Set match_start to the longest match starting at the given string and
    @@ -1299,10 +1369,7 @@ local void lm_init(s)
      *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
      * OUT assertion: the match length is not greater than s->lookahead.
      */
    -local uInt longest_match(s, cur_match)
    -    deflate_state *s;
    -    IPos cur_match;                             /* current match */
    -{
    +local uInt longest_match(deflate_state *s, IPos cur_match) {
         unsigned chain_length = s->max_chain_length;/* max hash chain length */
         register Bytef *scan = s->window + s->strstart; /* current string */
         register Bytef *match;                      /* matched string */
    @@ -1450,10 +1517,7 @@ local uInt longest_match(s, cur_match)
     /* ---------------------------------------------------------------------------
      * Optimized version for FASTEST only
      */
    -local uInt longest_match(s, cur_match)
    -    deflate_state *s;
    -    IPos cur_match;                             /* current match */
    -{
    +local uInt longest_match(deflate_state *s, IPos cur_match) {
         register Bytef *scan = s->window + s->strstart; /* current string */
         register Bytef *match;                       /* matched string */
         register int len;                           /* length of current match */
    @@ -1514,19 +1578,23 @@ local uInt longest_match(s, cur_match)
     /* ===========================================================================
      * Check that the match at match_start is indeed a match.
      */
    -local void check_match(s, start, match, length)
    -    deflate_state *s;
    -    IPos start, match;
    -    int length;
    -{
    +local void check_match(deflate_state *s, IPos start, IPos match, int length) {
         /* check that the match is indeed a match */
    -    if (zmemcmp(s->window + match,
    -                s->window + start, length) != EQUAL) {
    -        fprintf(stderr, " start %u, match %u, length %d\n",
    -                start, match, length);
    +    Bytef *back = s->window + (int)match, *here = s->window + start;
    +    IPos len = length;
    +    if (match == (IPos)-1) {
    +        /* match starts one byte before the current window -- just compare the
    +           subsequent length-1 bytes */
    +        back++;
    +        here++;
    +        len--;
    +    }
    +    if (zmemcmp(back, here, len) != EQUAL) {
    +        fprintf(stderr, " start %u, match %d, length %d\n",
    +                start, (int)match, length);
             do {
    -            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
    -        } while (--length != 0);
    +            fprintf(stderr, "(%02x %02x)", *back++, *here++);
    +        } while (--len != 0);
             z_error("invalid match");
         }
         if (z_verbose > 1) {
    @@ -1538,137 +1606,6 @@ local void check_match(s, start, match, length)
     #  define check_match(s, start, match, length)
     #endif /* ZLIB_DEBUG */
     
    -/* ===========================================================================
    - * Fill the window when the lookahead becomes insufficient.
    - * Updates strstart and lookahead.
    - *
    - * IN assertion: lookahead < MIN_LOOKAHEAD
    - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
    - *    At least one byte has been read, or avail_in == 0; reads are
    - *    performed for at least two bytes (required for the zip translate_eol
    - *    option -- not supported here).
    - */
    -local void fill_window(s)
    -    deflate_state *s;
    -{
    -    unsigned n;
    -    unsigned more;    /* Amount of free space at the end of the window. */
    -    uInt wsize = s->w_size;
    -
    -    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
    -
    -    do {
    -        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
    -
    -        /* Deal with !@#$% 64K limit: */
    -        if (sizeof(int) <= 2) {
    -            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
    -                more = wsize;
    -
    -            } else if (more == (unsigned)(-1)) {
    -                /* Very unlikely, but possible on 16 bit machine if
    -                 * strstart == 0 && lookahead == 1 (input done a byte at time)
    -                 */
    -                more--;
    -            }
    -        }
    -
    -        /* If the window is almost full and there is insufficient lookahead,
    -         * move the upper half to the lower one to make room in the upper half.
    -         */
    -        if (s->strstart >= wsize + MAX_DIST(s)) {
    -
    -            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
    -            s->match_start -= wsize;
    -            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
    -            s->block_start -= (long) wsize;
    -            if (s->insert > s->strstart)
    -                s->insert = s->strstart;
    -            slide_hash(s);
    -            more += wsize;
    -        }
    -        if (s->strm->avail_in == 0) break;
    -
    -        /* If there was no sliding:
    -         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
    -         *    more == window_size - lookahead - strstart
    -         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
    -         * => more >= window_size - 2*WSIZE + 2
    -         * In the BIG_MEM or MMAP case (not yet supported),
    -         *   window_size == input_size + MIN_LOOKAHEAD  &&
    -         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
    -         * Otherwise, window_size == 2*WSIZE so more >= 2.
    -         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
    -         */
    -        Assert(more >= 2, "more < 2");
    -
    -        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
    -        s->lookahead += n;
    -
    -        /* Initialize the hash value now that we have some input: */
    -        if (s->lookahead + s->insert >= MIN_MATCH) {
    -            uInt str = s->strstart - s->insert;
    -            s->ins_h = s->window[str];
    -            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
    -#if MIN_MATCH != 3
    -            Call UPDATE_HASH() MIN_MATCH-3 more times
    -#endif
    -            while (s->insert) {
    -                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
    -#ifndef FASTEST
    -                s->prev[str & s->w_mask] = s->head[s->ins_h];
    -#endif
    -                s->head[s->ins_h] = (Pos)str;
    -                str++;
    -                s->insert--;
    -                if (s->lookahead + s->insert < MIN_MATCH)
    -                    break;
    -            }
    -        }
    -        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
    -         * but this is not important since only literal bytes will be emitted.
    -         */
    -
    -    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
    -
    -    /* If the WIN_INIT bytes after the end of the current data have never been
    -     * written, then zero those bytes in order to avoid memory check reports of
    -     * the use of uninitialized (or uninitialised as Julian writes) bytes by
    -     * the longest match routines.  Update the high water mark for the next
    -     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
    -     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
    -     */
    -    if (s->high_water < s->window_size) {
    -        ulg curr = s->strstart + (ulg)(s->lookahead);
    -        ulg init;
    -
    -        if (s->high_water < curr) {
    -            /* Previous high water mark below current data -- zero WIN_INIT
    -             * bytes or up to end of window, whichever is less.
    -             */
    -            init = s->window_size - curr;
    -            if (init > WIN_INIT)
    -                init = WIN_INIT;
    -            zmemzero(s->window + curr, (unsigned)init);
    -            s->high_water = curr + init;
    -        }
    -        else if (s->high_water < (ulg)curr + WIN_INIT) {
    -            /* High water mark at or above current data, but below current data
    -             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
    -             * to end of window, whichever is less.
    -             */
    -            init = (ulg)curr + WIN_INIT - s->high_water;
    -            if (init > s->window_size - s->high_water)
    -                init = s->window_size - s->high_water;
    -            zmemzero(s->window + s->high_water, (unsigned)init);
    -            s->high_water += init;
    -        }
    -    }
    -
    -    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
    -           "not enough room for search");
    -}
    -
     /* ===========================================================================
      * Flush the current block, with given end-of-file flag.
      * IN assertion: strstart is set to the end of the current match.
    @@ -1711,10 +1648,7 @@ local void fill_window(s)
      * copied. It is most efficient with large input and output buffers, which
      * maximizes the opportunities to have a single copy from next_in to next_out.
      */
    -local block_state deflate_stored(s, flush)
    -    deflate_state *s;
    -    int flush;
    -{
    +local block_state deflate_stored(deflate_state *s, int flush) {
         /* Smallest worthy block size when not flushing or finishing. By default
          * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
          * large input and output buffers, the stored block size will be larger.
    @@ -1898,10 +1832,7 @@ local block_state deflate_stored(s, flush)
      * new strings in the dictionary only for unmatched strings or for short
      * matches. It is used only for the fast compression options.
      */
    -local block_state deflate_fast(s, flush)
    -    deflate_state *s;
    -    int flush;
    -{
    +local block_state deflate_fast(deflate_state *s, int flush) {
         IPos hash_head;       /* head of the hash chain */
         int bflush;           /* set if current block must be flushed */
     
    @@ -2000,10 +1931,7 @@ local block_state deflate_fast(s, flush)
      * evaluation for matches: a match is finally adopted only if there is
      * no better match at the next window position.
      */
    -local block_state deflate_slow(s, flush)
    -    deflate_state *s;
    -    int flush;
    -{
    +local block_state deflate_slow(deflate_state *s, int flush) {
         IPos hash_head;          /* head of hash chain */
         int bflush;              /* set if current block must be flushed */
     
    @@ -2131,10 +2059,7 @@ local block_state deflate_slow(s, flush)
      * one.  Do not maintain a hash table.  (It will be regenerated if this run of
      * deflate switches away from Z_RLE.)
      */
    -local block_state deflate_rle(s, flush)
    -    deflate_state *s;
    -    int flush;
    -{
    +local block_state deflate_rle(deflate_state *s, int flush) {
         int bflush;             /* set if current block must be flushed */
         uInt prev;              /* byte at distance one to match */
         Bytef *scan, *strend;   /* scan goes up to strend for length of run */
    @@ -2205,10 +2130,7 @@ local block_state deflate_rle(s, flush)
      * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
      * (It will be regenerated if this run of deflate switches away from Huffman.)
      */
    -local block_state deflate_huff(s, flush)
    -    deflate_state *s;
    -    int flush;
    -{
    +local block_state deflate_huff(deflate_state *s, int flush) {
         int bflush;             /* set if current block must be flushed */
     
         for (;;) {
    diff --git a/src/java.base/share/native/libzip/zlib/deflate.h b/src/java.base/share/native/libzip/zlib/deflate.h
    index b73f5a04e14..830d46b8894 100644
    --- a/src/java.base/share/native/libzip/zlib/deflate.h
    +++ b/src/java.base/share/native/libzip/zlib/deflate.h
    @@ -23,7 +23,7 @@
      */
     
     /* deflate.h -- internal compression state
    - * Copyright (C) 1995-2018 Jean-loup Gailly
    + * Copyright (C) 1995-2024 Jean-loup Gailly
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -47,6 +47,10 @@
     #  define GZIP
     #endif
     
    +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at
    +   the cost of a larger memory footprint */
    +/* #define LIT_MEM */
    +
     /* ===========================================================================
      * Internal compression state.
      */
    @@ -241,7 +245,14 @@ typedef struct internal_state {
         /* Depth of each subtree used as tie breaker for trees of equal frequency
          */
     
    +#ifdef LIT_MEM
    +#   define LIT_BUFS 5
    +    ushf *d_buf;          /* buffer for distances */
    +    uchf *l_buf;          /* buffer for literals/lengths */
    +#else
    +#   define LIT_BUFS 4
         uchf *sym_buf;        /* buffer for distances and literals/lengths */
    +#endif
     
         uInt  lit_bufsize;
         /* Size of match buffer for literals/lengths.  There are 4 reasons for
    @@ -263,7 +274,7 @@ typedef struct internal_state {
          *   - I can't count above 4
          */
     
    -    uInt sym_next;      /* running index in sym_buf */
    +    uInt sym_next;      /* running index in symbol buffer */
         uInt sym_end;       /* symbol table full when sym_next reaches this */
     
         ulg opt_len;        /* bit length of current block with optimal trees */
    @@ -315,14 +326,14 @@ typedef struct internal_state {
        memory checker errors from longest match routines */
     
             /* in trees.c */
    -void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
    -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
    -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
    -                        ulg stored_len, int last));
    -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
    -void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
    -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
    -                        ulg stored_len, int last));
    +void ZLIB_INTERNAL _tr_init(deflate_state *s);
    +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc);
    +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
    +                                   ulg stored_len, int last);
    +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s);
    +void ZLIB_INTERNAL _tr_align(deflate_state *s);
    +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
    +                                    ulg stored_len, int last);
     
     #define d_code(dist) \
        ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
    @@ -342,6 +353,25 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
       extern const uch ZLIB_INTERNAL _dist_code[];
     #endif
     
    +#ifdef LIT_MEM
    +# define _tr_tally_lit(s, c, flush) \
    +  { uch cc = (c); \
    +    s->d_buf[s->sym_next] = 0; \
    +    s->l_buf[s->sym_next++] = cc; \
    +    s->dyn_ltree[cc].Freq++; \
    +    flush = (s->sym_next == s->sym_end); \
    +   }
    +# define _tr_tally_dist(s, distance, length, flush) \
    +  { uch len = (uch)(length); \
    +    ush dist = (ush)(distance); \
    +    s->d_buf[s->sym_next] = dist; \
    +    s->l_buf[s->sym_next++] = len; \
    +    dist--; \
    +    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
    +    s->dyn_dtree[d_code(dist)].Freq++; \
    +    flush = (s->sym_next == s->sym_end); \
    +  }
    +#else
     # define _tr_tally_lit(s, c, flush) \
       { uch cc = (c); \
         s->sym_buf[s->sym_next++] = 0; \
    @@ -361,6 +391,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
         s->dyn_dtree[d_code(dist)].Freq++; \
         flush = (s->sym_next == s->sym_end); \
       }
    +#endif
     #else
     # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
     # define _tr_tally_dist(s, distance, length, flush) \
    diff --git a/src/java.base/share/native/libzip/zlib/gzclose.c b/src/java.base/share/native/libzip/zlib/gzclose.c
    index 5cce4b03d2f..eff53ace042 100644
    --- a/src/java.base/share/native/libzip/zlib/gzclose.c
    +++ b/src/java.base/share/native/libzip/zlib/gzclose.c
    @@ -32,9 +32,7 @@
     /* gzclose() is in a separate file so that it is linked in only if it is used.
        That way the other gzclose functions can be used instead to avoid linking in
        unneeded compression or decompression routines. */
    -int ZEXPORT gzclose(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzclose(gzFile file) {
     #ifndef NO_GZCOMPRESS
         gz_statep state;
     
    diff --git a/src/java.base/share/native/libzip/zlib/gzguts.h b/src/java.base/share/native/libzip/zlib/gzguts.h
    index 81bedce5445..8cce2c69d24 100644
    --- a/src/java.base/share/native/libzip/zlib/gzguts.h
    +++ b/src/java.base/share/native/libzip/zlib/gzguts.h
    @@ -23,7 +23,7 @@
      */
     
     /* gzguts.h -- zlib internal header definitions for gz* operations
    - * Copyright (C) 2004-2019 Mark Adler
    + * Copyright (C) 2004-2024 Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -31,9 +31,8 @@
     #  ifndef _LARGEFILE_SOURCE
     #    define _LARGEFILE_SOURCE 1
     #  endif
    -#  ifdef _FILE_OFFSET_BITS
    -#    undef _FILE_OFFSET_BITS
    -#  endif
    +#  undef _FILE_OFFSET_BITS
    +#  undef _TIME_BITS
     #endif
     
     #ifdef HAVE_HIDDEN
    @@ -143,8 +142,8 @@
     
     /* gz* functions always use library allocation functions */
     #ifndef STDC
    -  extern voidp  malloc OF((uInt size));
    -  extern void   free   OF((voidpf ptr));
    +  extern voidp  malloc(uInt size);
    +  extern void   free(voidpf ptr);
     #endif
     
     /* get errno and strerror definition */
    @@ -162,10 +161,10 @@
     
     /* provide prototypes for these when building zlib without LFS */
     #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
    -    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
    -    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
    -    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
    -    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
    +    ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
    +    ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
    +    ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
    +    ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
     #endif
     
     /* default memLevel */
    @@ -227,17 +226,13 @@ typedef struct {
     typedef gz_state FAR *gz_statep;
     
     /* shared functions */
    -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
    +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *);
     #if defined UNDER_CE
    -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
    +char ZLIB_INTERNAL *gz_strwinerror(DWORD error);
     #endif
     
     /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
        value -- needed when comparing unsigned to z_off64_t, which is signed
        (possible z_off64_t types off_t, off64_t, and long are all signed) */
    -#ifdef INT_MAX
    -#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
    -#else
    -unsigned ZLIB_INTERNAL gz_intmax OF((void));
    -#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
    -#endif
    +unsigned ZLIB_INTERNAL gz_intmax(void);
    +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
    diff --git a/src/java.base/share/native/libzip/zlib/gzlib.c b/src/java.base/share/native/libzip/zlib/gzlib.c
    index 1cbc6d25b16..0f4dfae64a0 100644
    --- a/src/java.base/share/native/libzip/zlib/gzlib.c
    +++ b/src/java.base/share/native/libzip/zlib/gzlib.c
    @@ -23,7 +23,7 @@
      */
     
     /* gzlib.c -- zlib functions common to reading and writing gzip files
    - * Copyright (C) 2004-2019 Mark Adler
    + * Copyright (C) 2004-2024 Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -39,10 +39,6 @@
     #endif
     #endif
     
    -/* Local functions */
    -local void gz_reset OF((gz_statep));
    -local gzFile gz_open OF((const void *, int, const char *));
    -
     #if defined UNDER_CE
     
     /* Map the Windows error number in ERROR to a locale-dependent error message
    @@ -54,9 +50,7 @@ local gzFile gz_open OF((const void *, int, const char *));
     
        The gz_strwinerror function does not change the current setting of
        GetLastError. */
    -char ZLIB_INTERNAL *gz_strwinerror(error)
    -     DWORD error;
    -{
    +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
         static char buf[1024];
     
         wchar_t *msgbuf;
    @@ -96,9 +90,7 @@ char ZLIB_INTERNAL *gz_strwinerror(error)
     #endif /* UNDER_CE */
     
     /* Reset gzip file state */
    -local void gz_reset(state)
    -    gz_statep state;
    -{
    +local void gz_reset(gz_statep state) {
         state->x.have = 0;              /* no output data available */
         if (state->mode == GZ_READ) {   /* for reading ... */
             state->eof = 0;             /* not at end of file */
    @@ -114,11 +106,7 @@ local void gz_reset(state)
     }
     
     /* Open a gzip file either by name or file descriptor. */
    -local gzFile gz_open(path, fd, mode)
    -    const void *path;
    -    int fd;
    -    const char *mode;
    -{
    +local gzFile gz_open(const void *path, int fd, const char *mode) {
         gz_statep state;
         z_size_t len;
         int oflag;
    @@ -293,26 +281,17 @@ local gzFile gz_open(path, fd, mode)
     }
     
     /* -- see zlib.h -- */
    -gzFile ZEXPORT gzopen(path, mode)
    -    const char *path;
    -    const char *mode;
    -{
    +gzFile ZEXPORT gzopen(const char *path, const char *mode) {
         return gz_open(path, -1, mode);
     }
     
     /* -- see zlib.h -- */
    -gzFile ZEXPORT gzopen64(path, mode)
    -    const char *path;
    -    const char *mode;
    -{
    +gzFile ZEXPORT gzopen64(const char *path, const char *mode) {
         return gz_open(path, -1, mode);
     }
     
     /* -- see zlib.h -- */
    -gzFile ZEXPORT gzdopen(fd, mode)
    -    int fd;
    -    const char *mode;
    -{
    +gzFile ZEXPORT gzdopen(int fd, const char *mode) {
         char *path;         /* identifier for error messages */
         gzFile gz;
     
    @@ -330,19 +309,13 @@ gzFile ZEXPORT gzdopen(fd, mode)
     
     /* -- see zlib.h -- */
     #ifdef WIDECHAR
    -gzFile ZEXPORT gzopen_w(path, mode)
    -    const wchar_t *path;
    -    const char *mode;
    -{
    +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {
         return gz_open(path, -2, mode);
     }
     #endif
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzbuffer(file, size)
    -    gzFile file;
    -    unsigned size;
    -{
    +int ZEXPORT gzbuffer(gzFile file, unsigned size) {
         gz_statep state;
     
         /* get internal structure and check integrity */
    @@ -359,16 +332,14 @@ int ZEXPORT gzbuffer(file, size)
         /* check and set requested size */
         if ((size << 1) < size)
             return -1;              /* need to be able to double it */
    -    if (size < 2)
    -        size = 2;               /* need two bytes to check magic header */
    +    if (size < 8)
    +        size = 8;               /* needed to behave well with flushing */
         state->want = size;
         return 0;
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzrewind(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzrewind(gzFile file) {
         gz_statep state;
     
         /* get internal structure */
    @@ -389,11 +360,7 @@ int ZEXPORT gzrewind(file)
     }
     
     /* -- see zlib.h -- */
    -z_off64_t ZEXPORT gzseek64(file, offset, whence)
    -    gzFile file;
    -    z_off64_t offset;
    -    int whence;
    -{
    +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
         unsigned n;
         z_off64_t ret;
         gz_statep state;
    @@ -466,11 +433,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
     }
     
     /* -- see zlib.h -- */
    -z_off_t ZEXPORT gzseek(file, offset, whence)
    -    gzFile file;
    -    z_off_t offset;
    -    int whence;
    -{
    +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {
         z_off64_t ret;
     
         ret = gzseek64(file, (z_off64_t)offset, whence);
    @@ -478,9 +441,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence)
     }
     
     /* -- see zlib.h -- */
    -z_off64_t ZEXPORT gztell64(file)
    -    gzFile file;
    -{
    +z_off64_t ZEXPORT gztell64(gzFile file) {
         gz_statep state;
     
         /* get internal structure and check integrity */
    @@ -495,9 +456,7 @@ z_off64_t ZEXPORT gztell64(file)
     }
     
     /* -- see zlib.h -- */
    -z_off_t ZEXPORT gztell(file)
    -    gzFile file;
    -{
    +z_off_t ZEXPORT gztell(gzFile file) {
         z_off64_t ret;
     
         ret = gztell64(file);
    @@ -505,9 +464,7 @@ z_off_t ZEXPORT gztell(file)
     }
     
     /* -- see zlib.h -- */
    -z_off64_t ZEXPORT gzoffset64(file)
    -    gzFile file;
    -{
    +z_off64_t ZEXPORT gzoffset64(gzFile file) {
         z_off64_t offset;
         gz_statep state;
     
    @@ -528,9 +485,7 @@ z_off64_t ZEXPORT gzoffset64(file)
     }
     
     /* -- see zlib.h -- */
    -z_off_t ZEXPORT gzoffset(file)
    -    gzFile file;
    -{
    +z_off_t ZEXPORT gzoffset(gzFile file) {
         z_off64_t ret;
     
         ret = gzoffset64(file);
    @@ -538,9 +493,7 @@ z_off_t ZEXPORT gzoffset(file)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzeof(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzeof(gzFile file) {
         gz_statep state;
     
         /* get internal structure and check integrity */
    @@ -555,10 +508,7 @@ int ZEXPORT gzeof(file)
     }
     
     /* -- see zlib.h -- */
    -const char * ZEXPORT gzerror(file, errnum)
    -    gzFile file;
    -    int *errnum;
    -{
    +const char * ZEXPORT gzerror(gzFile file, int *errnum) {
         gz_statep state;
     
         /* get internal structure and check integrity */
    @@ -576,9 +526,7 @@ const char * ZEXPORT gzerror(file, errnum)
     }
     
     /* -- see zlib.h -- */
    -void ZEXPORT gzclearerr(file)
    -    gzFile file;
    -{
    +void ZEXPORT gzclearerr(gzFile file) {
         gz_statep state;
     
         /* get internal structure and check integrity */
    @@ -602,11 +550,7 @@ void ZEXPORT gzclearerr(file)
        memory).  Simply save the error message as a static string.  If there is an
        allocation failure constructing the error message, then convert the error to
        out of memory. */
    -void ZLIB_INTERNAL gz_error(state, err, msg)
    -    gz_statep state;
    -    int err;
    -    const char *msg;
    -{
    +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
         /* free previously allocated message and clear */
         if (state->msg != NULL) {
             if (state->err != Z_MEM_ERROR)
    @@ -643,21 +587,20 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
     #endif
     }
     
    -#ifndef INT_MAX
     /* portably return maximum value for an int (when limits.h presumed not
        available) -- we need to do this to cover cases where 2's complement not
        used, since C standard permits 1's complement and sign-bit representations,
        otherwise we could just use ((unsigned)-1) >> 1 */
    -unsigned ZLIB_INTERNAL gz_intmax()
    -{
    -    unsigned p, q;
    -
    -    p = 1;
    +unsigned ZLIB_INTERNAL gz_intmax(void) {
    +#ifdef INT_MAX
    +    return INT_MAX;
    +#else
    +    unsigned p = 1, q;
         do {
             q = p;
             p <<= 1;
             p++;
         } while (p > q);
         return q >> 1;
    -}
     #endif
    +}
    diff --git a/src/java.base/share/native/libzip/zlib/gzread.c b/src/java.base/share/native/libzip/zlib/gzread.c
    index fbe4281b4e0..7b9c9df5fa1 100644
    --- a/src/java.base/share/native/libzip/zlib/gzread.c
    +++ b/src/java.base/share/native/libzip/zlib/gzread.c
    @@ -29,25 +29,12 @@
     
     #include "gzguts.h"
     
    -/* Local functions */
    -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
    -local int gz_avail OF((gz_statep));
    -local int gz_look OF((gz_statep));
    -local int gz_decomp OF((gz_statep));
    -local int gz_fetch OF((gz_statep));
    -local int gz_skip OF((gz_statep, z_off64_t));
    -local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
    -
     /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
        state->fd, and update state->eof, state->err, and state->msg as appropriate.
        This function needs to loop on read(), since read() is not guaranteed to
        read the number of bytes requested, depending on the type of descriptor. */
    -local int gz_load(state, buf, len, have)
    -    gz_statep state;
    -    unsigned char *buf;
    -    unsigned len;
    -    unsigned *have;
    -{
    +local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
    +                  unsigned *have) {
         int ret;
         unsigned get, max = ((unsigned)-1 >> 2) + 1;
     
    @@ -77,9 +64,7 @@ local int gz_load(state, buf, len, have)
        If strm->avail_in != 0, then the current data is moved to the beginning of
        the input buffer, and then the remainder of the buffer is loaded with the
        available data from the input file. */
    -local int gz_avail(state)
    -    gz_statep state;
    -{
    +local int gz_avail(gz_statep state) {
         unsigned got;
         z_streamp strm = &(state->strm);
     
    @@ -112,9 +97,7 @@ local int gz_avail(state)
        case, all further file reads will be directly to either the output buffer or
        a user buffer.  If decompressing, the inflate state will be initialized.
        gz_look() will return 0 on success or -1 on failure. */
    -local int gz_look(state)
    -    gz_statep state;
    -{
    +local int gz_look(gz_statep state) {
         z_streamp strm = &(state->strm);
     
         /* allocate read buffers and inflate memory */
    @@ -194,9 +177,7 @@ local int gz_look(state)
        data.  If the gzip stream completes, state->how is reset to LOOK to look for
        the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
        on success, -1 on failure. */
    -local int gz_decomp(state)
    -    gz_statep state;
    -{
    +local int gz_decomp(gz_statep state) {
         int ret = Z_OK;
         unsigned had;
         z_streamp strm = &(state->strm);
    @@ -248,9 +229,7 @@ local int gz_decomp(state)
        looked for to determine whether to copy or decompress.  Returns -1 on error,
        otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
        end of the input file has been reached and all data has been processed.  */
    -local int gz_fetch(state)
    -    gz_statep state;
    -{
    +local int gz_fetch(gz_statep state) {
         z_streamp strm = &(state->strm);
     
         do {
    @@ -278,10 +257,7 @@ local int gz_fetch(state)
     }
     
     /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
    -local int gz_skip(state, len)
    -    gz_statep state;
    -    z_off64_t len;
    -{
    +local int gz_skip(gz_statep state, z_off64_t len) {
         unsigned n;
     
         /* skip over len bytes or reach end-of-file, whichever comes first */
    @@ -313,11 +289,7 @@ local int gz_skip(state, len)
        input.  Return the number of bytes read.  If zero is returned, either the
        end of file was reached, or there was an error.  state->err must be
        consulted in that case to determine which. */
    -local z_size_t gz_read(state, buf, len)
    -    gz_statep state;
    -    voidp buf;
    -    z_size_t len;
    -{
    +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
         z_size_t got;
         unsigned n;
     
    @@ -394,11 +366,7 @@ local z_size_t gz_read(state, buf, len)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzread(file, buf, len)
    -    gzFile file;
    -    voidp buf;
    -    unsigned len;
    -{
    +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
         gz_statep state;
     
         /* get internal structure */
    @@ -430,12 +398,7 @@ int ZEXPORT gzread(file, buf, len)
     }
     
     /* -- see zlib.h -- */
    -z_size_t ZEXPORT gzfread(buf, size, nitems, file)
    -    voidp buf;
    -    z_size_t size;
    -    z_size_t nitems;
    -    gzFile file;
    -{
    +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) {
         z_size_t len;
         gz_statep state;
     
    @@ -466,9 +429,7 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
     #else
     #  undef gzgetc
     #endif
    -int ZEXPORT gzgetc(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzgetc(gzFile file) {
         unsigned char buf[1];
         gz_statep state;
     
    @@ -493,17 +454,12 @@ int ZEXPORT gzgetc(file)
         return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
     }
     
    -int ZEXPORT gzgetc_(file)
    -gzFile file;
    -{
    +int ZEXPORT gzgetc_(gzFile file) {
         return gzgetc(file);
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzungetc(c, file)
    -    int c;
    -    gzFile file;
    -{
    +int ZEXPORT gzungetc(int c, gzFile file) {
         gz_statep state;
     
         /* get internal structure */
    @@ -511,6 +467,10 @@ int ZEXPORT gzungetc(c, file)
             return -1;
         state = (gz_statep)file;
     
    +    /* in case this was just opened, set up the input buffer */
    +    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
    +        (void)gz_look(state);
    +
         /* check that we're reading and that there's no (serious) error */
         if (state->mode != GZ_READ ||
             (state->err != Z_OK && state->err != Z_BUF_ERROR))
    @@ -560,11 +520,7 @@ int ZEXPORT gzungetc(c, file)
     }
     
     /* -- see zlib.h -- */
    -char * ZEXPORT gzgets(file, buf, len)
    -    gzFile file;
    -    char *buf;
    -    int len;
    -{
    +char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
         unsigned left, n;
         char *str;
         unsigned char *eol;
    @@ -624,9 +580,7 @@ char * ZEXPORT gzgets(file, buf, len)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzdirect(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzdirect(gzFile file) {
         gz_statep state;
     
         /* get internal structure */
    @@ -644,9 +598,7 @@ int ZEXPORT gzdirect(file)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzclose_r(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzclose_r(gzFile file) {
         int ret, err;
         gz_statep state;
     
    diff --git a/src/java.base/share/native/libzip/zlib/gzwrite.c b/src/java.base/share/native/libzip/zlib/gzwrite.c
    index 3aff44cc940..008b03e7021 100644
    --- a/src/java.base/share/native/libzip/zlib/gzwrite.c
    +++ b/src/java.base/share/native/libzip/zlib/gzwrite.c
    @@ -29,18 +29,10 @@
     
     #include "gzguts.h"
     
    -/* Local functions */
    -local int gz_init OF((gz_statep));
    -local int gz_comp OF((gz_statep, int));
    -local int gz_zero OF((gz_statep, z_off64_t));
    -local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
    -
     /* Initialize state for writing a gzip file.  Mark initialization by setting
        state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
        success. */
    -local int gz_init(state)
    -    gz_statep state;
    -{
    +local int gz_init(gz_statep state) {
         int ret;
         z_streamp strm = &(state->strm);
     
    @@ -94,10 +86,7 @@ local int gz_init(state)
        deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
        reset to start a new gzip stream.  If gz->direct is true, then simply write
        to the output file without compressing, and ignore flush. */
    -local int gz_comp(state, flush)
    -    gz_statep state;
    -    int flush;
    -{
    +local int gz_comp(gz_statep state, int flush) {
         int ret, writ;
         unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
         z_streamp strm = &(state->strm);
    @@ -175,10 +164,7 @@ local int gz_comp(state, flush)
     
     /* Compress len zeros to output.  Return -1 on a write error or memory
        allocation failure by gz_comp(), or 0 on success. */
    -local int gz_zero(state, len)
    -    gz_statep state;
    -    z_off64_t len;
    -{
    +local int gz_zero(gz_statep state, z_off64_t len) {
         int first;
         unsigned n;
         z_streamp strm = &(state->strm);
    @@ -208,11 +194,7 @@ local int gz_zero(state, len)
     
     /* Write len bytes from buf to file.  Return the number of bytes written.  If
        the returned value is less than len, then there was an error. */
    -local z_size_t gz_write(state, buf, len)
    -    gz_statep state;
    -    voidpc buf;
    -    z_size_t len;
    -{
    +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
         z_size_t put = len;
     
         /* if len is zero, avoid unnecessary operations */
    @@ -276,11 +258,7 @@ local z_size_t gz_write(state, buf, len)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzwrite(file, buf, len)
    -    gzFile file;
    -    voidpc buf;
    -    unsigned len;
    -{
    +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
         gz_statep state;
     
         /* get internal structure */
    @@ -304,12 +282,8 @@ int ZEXPORT gzwrite(file, buf, len)
     }
     
     /* -- see zlib.h -- */
    -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
    -    voidpc buf;
    -    z_size_t size;
    -    z_size_t nitems;
    -    gzFile file;
    -{
    +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
    +                          gzFile file) {
         z_size_t len;
         gz_statep state;
     
    @@ -334,10 +308,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzputc(file, c)
    -    gzFile file;
    -    int c;
    -{
    +int ZEXPORT gzputc(gzFile file, int c) {
         unsigned have;
         unsigned char buf[1];
         gz_statep state;
    @@ -382,10 +353,7 @@ int ZEXPORT gzputc(file, c)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzputs(file, s)
    -    gzFile file;
    -    const char *s;
    -{
    +int ZEXPORT gzputs(gzFile file, const char *s) {
         z_size_t len, put;
         gz_statep state;
     
    @@ -412,8 +380,7 @@ int ZEXPORT gzputs(file, s)
     #include 
     
     /* -- see zlib.h -- */
    -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
    -{
    +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
         int len;
         unsigned left;
         char *next;
    @@ -484,8 +451,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
         return len;
     }
     
    -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
    -{
    +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
         va_list va;
         int ret;
     
    @@ -498,13 +464,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
     #else /* !STDC && !Z_HAVE_STDARG_H */
     
     /* -- see zlib.h -- */
    -int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
    -                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
    -    gzFile file;
    -    const char *format;
    -    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
    -        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
    -{
    +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
    +                       int a4, int a5, int a6, int a7, int a8, int a9, int a10,
    +                       int a11, int a12, int a13, int a14, int a15, int a16,
    +                       int a17, int a18, int a19, int a20) {
         unsigned len, left;
         char *next;
         gz_statep state;
    @@ -586,10 +549,7 @@ int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
     #endif
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzflush(file, flush)
    -    gzFile file;
    -    int flush;
    -{
    +int ZEXPORT gzflush(gzFile file, int flush) {
         gz_statep state;
     
         /* get internal structure */
    @@ -618,11 +578,7 @@ int ZEXPORT gzflush(file, flush)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzsetparams(file, level, strategy)
    -    gzFile file;
    -    int level;
    -    int strategy;
    -{
    +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
         gz_statep state;
         z_streamp strm;
     
    @@ -633,7 +589,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
         strm = &(state->strm);
     
         /* check that we're writing and that there's no error */
    -    if (state->mode != GZ_WRITE || state->err != Z_OK)
    +    if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct)
             return Z_STREAM_ERROR;
     
         /* if no change is requested, then do nothing */
    @@ -660,9 +616,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
     }
     
     /* -- see zlib.h -- */
    -int ZEXPORT gzclose_w(file)
    -    gzFile file;
    -{
    +int ZEXPORT gzclose_w(gzFile file) {
         int ret = Z_OK;
         gz_statep state;
     
    diff --git a/src/java.base/share/native/libzip/zlib/infback.c b/src/java.base/share/native/libzip/zlib/infback.c
    index ea7ea83d8d2..f680e2cdbdc 100644
    --- a/src/java.base/share/native/libzip/zlib/infback.c
    +++ b/src/java.base/share/native/libzip/zlib/infback.c
    @@ -39,9 +39,6 @@
     #include "inflate.h"
     #include "inffast.h"
     
    -/* function prototypes */
    -local void fixedtables OF((struct inflate_state FAR *state));
    -
     /*
        strm provides memory allocation functions in zalloc and zfree, or
        Z_NULL to use the library memory allocation functions.
    @@ -49,13 +46,9 @@ local void fixedtables OF((struct inflate_state FAR *state));
        windowBits is in the range 8..15, and window is a user-supplied
        window and output buffer that is 2**windowBits bytes.
      */
    -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
    -z_streamp strm;
    -int windowBits;
    -unsigned char FAR *window;
    -const char *version;
    -int stream_size;
    -{
    +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
    +                             unsigned char FAR *window, const char *version,
    +                             int stream_size) {
         struct inflate_state FAR *state;
     
         if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
    @@ -104,9 +97,7 @@ int stream_size;
        used for threaded applications, since the rewriting of the tables and virgin
        may not be thread-safe.
      */
    -local void fixedtables(state)
    -struct inflate_state FAR *state;
    -{
    +local void fixedtables(struct inflate_state FAR *state) {
     #ifdef BUILDFIXED
         static int virgin = 1;
         static code *lenfix, *distfix;
    @@ -272,13 +263,8 @@ struct inflate_state FAR *state;
        inflateBack() can also return Z_STREAM_ERROR if the input parameters
        are not correct, i.e. strm is Z_NULL or the state was not initialized.
      */
    -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
    -z_streamp strm;
    -in_func in;
    -void FAR *in_desc;
    -out_func out;
    -void FAR *out_desc;
    -{
    +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
    +                        out_func out, void FAR *out_desc) {
         struct inflate_state FAR *state;
         z_const unsigned char FAR *next;    /* next input */
         unsigned char FAR *put;     /* next output */
    @@ -656,9 +642,7 @@ void FAR *out_desc;
         return ret;
     }
     
    -int ZEXPORT inflateBackEnd(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateBackEnd(z_streamp strm) {
         if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
             return Z_STREAM_ERROR;
         ZFREE(strm, strm->state);
    diff --git a/src/java.base/share/native/libzip/zlib/inffast.c b/src/java.base/share/native/libzip/zlib/inffast.c
    index 45aa17d201f..e86dd78d801 100644
    --- a/src/java.base/share/native/libzip/zlib/inffast.c
    +++ b/src/java.base/share/native/libzip/zlib/inffast.c
    @@ -71,10 +71,7 @@
           requires strm->avail_out >= 258 for each loop to avoid checking for
           output space.
      */
    -void ZLIB_INTERNAL inflate_fast(strm, start)
    -z_streamp strm;
    -unsigned start;         /* inflate()'s starting value for strm->avail_out */
    -{
    +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
         struct inflate_state FAR *state;
         z_const unsigned char FAR *in;      /* local strm->next_in */
         z_const unsigned char FAR *last;    /* have enough input while in < last */
    diff --git a/src/java.base/share/native/libzip/zlib/inffast.h b/src/java.base/share/native/libzip/zlib/inffast.h
    index b8da8bb757a..bc4fb6b0df8 100644
    --- a/src/java.base/share/native/libzip/zlib/inffast.h
    +++ b/src/java.base/share/native/libzip/zlib/inffast.h
    @@ -32,4 +32,4 @@
        subject to change. Applications should only use zlib.h.
      */
     
    -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
    +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start);
    diff --git a/src/java.base/share/native/libzip/zlib/inflate.c b/src/java.base/share/native/libzip/zlib/inflate.c
    index b236dcafd80..3370cfe9565 100644
    --- a/src/java.base/share/native/libzip/zlib/inflate.c
    +++ b/src/java.base/share/native/libzip/zlib/inflate.c
    @@ -115,20 +115,7 @@
     #  endif
     #endif
     
    -/* function prototypes */
    -local int inflateStateCheck OF((z_streamp strm));
    -local void fixedtables OF((struct inflate_state FAR *state));
    -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
    -                           unsigned copy));
    -#ifdef BUILDFIXED
    -   void makefixed OF((void));
    -#endif
    -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
    -                              unsigned len));
    -
    -local int inflateStateCheck(strm)
    -z_streamp strm;
    -{
    +local int inflateStateCheck(z_streamp strm) {
         struct inflate_state FAR *state;
         if (strm == Z_NULL ||
             strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
    @@ -140,9 +127,7 @@ z_streamp strm;
         return 0;
     }
     
    -int ZEXPORT inflateResetKeep(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateResetKeep(z_streamp strm) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -166,9 +151,7 @@ z_streamp strm;
         return Z_OK;
     }
     
    -int ZEXPORT inflateReset(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateReset(z_streamp strm) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -179,10 +162,7 @@ z_streamp strm;
         return inflateResetKeep(strm);
     }
     
    -int ZEXPORT inflateReset2(strm, windowBits)
    -z_streamp strm;
    -int windowBits;
    -{
    +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
         int wrap;
         struct inflate_state FAR *state;
     
    @@ -219,12 +199,8 @@ int windowBits;
         return inflateReset(strm);
     }
     
    -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
    -z_streamp strm;
    -int windowBits;
    -const char *version;
    -int stream_size;
    -{
    +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
    +                          const char *version, int stream_size) {
         int ret;
         struct inflate_state FAR *state;
     
    @@ -263,22 +239,17 @@ int stream_size;
         return ret;
     }
     
    -int ZEXPORT inflateInit_(strm, version, stream_size)
    -z_streamp strm;
    -const char *version;
    -int stream_size;
    -{
    +int ZEXPORT inflateInit_(z_streamp strm, const char *version,
    +                         int stream_size) {
         return inflateInit2_(strm, DEF_WBITS, version, stream_size);
     }
     
    -int ZEXPORT inflatePrime(strm, bits, value)
    -z_streamp strm;
    -int bits;
    -int value;
    -{
    +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    +    if (bits == 0)
    +        return Z_OK;
         state = (struct inflate_state FAR *)strm->state;
         if (bits < 0) {
             state->hold = 0;
    @@ -302,9 +273,7 @@ int value;
        used for threaded applications, since the rewriting of the tables and virgin
        may not be thread-safe.
      */
    -local void fixedtables(state)
    -struct inflate_state FAR *state;
    -{
    +local void fixedtables(struct inflate_state FAR *state) {
     #ifdef BUILDFIXED
         static int virgin = 1;
         static code *lenfix, *distfix;
    @@ -366,7 +335,7 @@ struct inflate_state FAR *state;
     
         a.out > inffixed.h
      */
    -void makefixed()
    +void makefixed(void)
     {
         unsigned low, size;
         struct inflate_state state;
    @@ -420,11 +389,7 @@ void makefixed()
        output will fall in the output data, making match copies simpler and faster.
        The advantage may be dependent on the size of the processor's data caches.
      */
    -local int updatewindow(strm, end, copy)
    -z_streamp strm;
    -const Bytef *end;
    -unsigned copy;
    -{
    +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {
         struct inflate_state FAR *state;
         unsigned dist;
     
    @@ -646,10 +611,7 @@ unsigned copy;
        will return Z_BUF_ERROR if it has not reached the end of the stream.
      */
     
    -int ZEXPORT inflate(strm, flush)
    -z_streamp strm;
    -int flush;
    -{
    +int ZEXPORT inflate(z_streamp strm, int flush) {
         struct inflate_state FAR *state;
         z_const unsigned char FAR *next;    /* next input */
         unsigned char FAR *put;     /* next output */
    @@ -1325,9 +1287,7 @@ int flush;
         return ret;
     }
     
    -int ZEXPORT inflateEnd(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateEnd(z_streamp strm) {
         struct inflate_state FAR *state;
         if (inflateStateCheck(strm))
             return Z_STREAM_ERROR;
    @@ -1339,11 +1299,8 @@ z_streamp strm;
         return Z_OK;
     }
     
    -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
    -z_streamp strm;
    -Bytef *dictionary;
    -uInt *dictLength;
    -{
    +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,
    +                                 uInt *dictLength) {
         struct inflate_state FAR *state;
     
         /* check state */
    @@ -1362,11 +1319,8 @@ uInt *dictLength;
         return Z_OK;
     }
     
    -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
    -z_streamp strm;
    -const Bytef *dictionary;
    -uInt dictLength;
    -{
    +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
    +                                 uInt dictLength) {
         struct inflate_state FAR *state;
         unsigned long dictid;
         int ret;
    @@ -1397,10 +1351,7 @@ uInt dictLength;
         return Z_OK;
     }
     
    -int ZEXPORT inflateGetHeader(strm, head)
    -z_streamp strm;
    -gz_headerp head;
    -{
    +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {
         struct inflate_state FAR *state;
     
         /* check state */
    @@ -1425,11 +1376,8 @@ gz_headerp head;
        called again with more data and the *have state.  *have is initialized to
        zero for the first call.
      */
    -local unsigned syncsearch(have, buf, len)
    -unsigned FAR *have;
    -const unsigned char FAR *buf;
    -unsigned len;
    -{
    +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
    +                          unsigned len) {
         unsigned got;
         unsigned next;
     
    @@ -1448,9 +1396,7 @@ unsigned len;
         return next;
     }
     
    -int ZEXPORT inflateSync(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateSync(z_streamp strm) {
         unsigned len;               /* number of bytes to look at or looked at */
         int flags;                  /* temporary to save header status */
         unsigned long in, out;      /* temporary to save total_in and total_out */
    @@ -1465,7 +1411,7 @@ z_streamp strm;
         /* if first time, start search in bit buffer */
         if (state->mode != SYNC) {
             state->mode = SYNC;
    -        state->hold <<= state->bits & 7;
    +        state->hold >>= state->bits & 7;
             state->bits -= state->bits & 7;
             len = 0;
             while (state->bits >= 8) {
    @@ -1506,9 +1452,7 @@ z_streamp strm;
        block. When decompressing, PPP checks that at the end of input packet,
        inflate is waiting for these length bytes.
      */
    -int ZEXPORT inflateSyncPoint(strm)
    -z_streamp strm;
    -{
    +int ZEXPORT inflateSyncPoint(z_streamp strm) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -1516,10 +1460,7 @@ z_streamp strm;
         return state->mode == STORED && state->bits == 0;
     }
     
    -int ZEXPORT inflateCopy(dest, source)
    -z_streamp dest;
    -z_streamp source;
    -{
    +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
         struct inflate_state FAR *state;
         struct inflate_state FAR *copy;
         unsigned char FAR *window;
    @@ -1563,10 +1504,7 @@ z_streamp source;
         return Z_OK;
     }
     
    -int ZEXPORT inflateUndermine(strm, subvert)
    -z_streamp strm;
    -int subvert;
    -{
    +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -1581,10 +1519,7 @@ int subvert;
     #endif
     }
     
    -int ZEXPORT inflateValidate(strm, check)
    -z_streamp strm;
    -int check;
    -{
    +int ZEXPORT inflateValidate(z_streamp strm, int check) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
    @@ -1596,9 +1531,7 @@ int check;
         return Z_OK;
     }
     
    -long ZEXPORT inflateMark(strm)
    -z_streamp strm;
    -{
    +long ZEXPORT inflateMark(z_streamp strm) {
         struct inflate_state FAR *state;
     
         if (inflateStateCheck(strm))
    @@ -1609,9 +1542,7 @@ z_streamp strm;
                 (state->mode == MATCH ? state->was - state->length : 0));
     }
     
    -unsigned long ZEXPORT inflateCodesUsed(strm)
    -z_streamp strm;
    -{
    +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) {
         struct inflate_state FAR *state;
         if (inflateStateCheck(strm)) return (unsigned long)-1;
         state = (struct inflate_state FAR *)strm->state;
    diff --git a/src/java.base/share/native/libzip/zlib/inftrees.c b/src/java.base/share/native/libzip/zlib/inftrees.c
    index a60b1bfb393..c4913bc4359 100644
    --- a/src/java.base/share/native/libzip/zlib/inftrees.c
    +++ b/src/java.base/share/native/libzip/zlib/inftrees.c
    @@ -23,7 +23,7 @@
      */
     
     /* inftrees.c -- generate Huffman trees for efficient decoding
    - * Copyright (C) 1995-2022 Mark Adler
    + * Copyright (C) 1995-2024 Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -33,7 +33,7 @@
     #define MAXBITS 15
     
     const char inflate_copyright[] =
    -   " inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
    +   " inflate 1.3.1 Copyright 1995-2024 Mark Adler ";
     /*
       If you use the zlib library in a product, an acknowledgment is welcome
       in the documentation of your product. If for some reason you cannot
    @@ -53,14 +53,9 @@ const char inflate_copyright[] =
        table index bits.  It will differ if the request is greater than the
        longest code or if it is less than the shortest code.
      */
    -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
    -codetype type;
    -unsigned short FAR *lens;
    -unsigned codes;
    -code FAR * FAR *table;
    -unsigned FAR *bits;
    -unsigned short FAR *work;
    -{
    +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
    +                                unsigned codes, code FAR * FAR *table,
    +                                unsigned FAR *bits, unsigned short FAR *work) {
         unsigned len;               /* a code's length in bits */
         unsigned sym;               /* index of code symbols */
         unsigned min, max;          /* minimum and maximum code lengths */
    @@ -86,7 +81,7 @@ unsigned short FAR *work;
             35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
         static const unsigned short lext[31] = { /* Length codes 257..285 extra */
             16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
    -        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65};
    +        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77};
         static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
             1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
             257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
    diff --git a/src/java.base/share/native/libzip/zlib/inftrees.h b/src/java.base/share/native/libzip/zlib/inftrees.h
    index a05314fefbd..3e2e889301d 100644
    --- a/src/java.base/share/native/libzip/zlib/inftrees.h
    +++ b/src/java.base/share/native/libzip/zlib/inftrees.h
    @@ -65,8 +65,8 @@ typedef struct {
        examples/enough.c found in the zlib distribution.  The arguments to that
        program are the number of symbols, the initial root table size, and the
        maximum bit length of a code.  "enough 286 9 15" for literal/length codes
    -   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
    -   The initial root table size (9 or 6) is found in the fifth argument of the
    +   returns 852, and "enough 30 6 15" for distance codes returns 592. The
    +   initial root table size (9 or 6) is found in the fifth argument of the
        inflate_table() calls in inflate.c and infback.c.  If the root table size is
        changed, then these maximum sizes would be need to be recalculated and
        updated. */
    @@ -81,6 +81,6 @@ typedef enum {
         DISTS
     } codetype;
     
    -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
    -                             unsigned codes, code FAR * FAR *table,
    -                             unsigned FAR *bits, unsigned short FAR *work));
    +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
    +                                unsigned codes, code FAR * FAR *table,
    +                                unsigned FAR *bits, unsigned short FAR *work);
    diff --git a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
    index ff48fdaea06..3296c5f2fad 100644
    --- a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
    +++ b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
    @@ -1,4 +1,4 @@
    -Changes from zlib 1.2.13
    +Changes from zlib 1.3.1
     
     (1) renamed adler32.c -> zadler32.c, crc32c -> zcrc32.c
     
    diff --git a/src/java.base/share/native/libzip/zlib/trees.c b/src/java.base/share/native/libzip/zlib/trees.c
    index 7214373826f..bbfa9deee5b 100644
    --- a/src/java.base/share/native/libzip/zlib/trees.c
    +++ b/src/java.base/share/native/libzip/zlib/trees.c
    @@ -23,7 +23,7 @@
      */
     
     /* trees.c -- output deflated data using Huffman coding
    - * Copyright (C) 1995-2021 Jean-loup Gailly
    + * Copyright (C) 1995-2024 Jean-loup Gailly
      * detect_data_type() function provided freely by Cosmin Truta, 2006
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
    @@ -146,39 +146,116 @@ struct static_tree_desc_s {
         int     max_length;          /* max bit length for the codes */
     };
     
    -local const static_tree_desc  static_l_desc =
    +#ifdef NO_INIT_GLOBAL_POINTERS
    +#  define TCONST
    +#else
    +#  define TCONST const
    +#endif
    +
    +local TCONST static_tree_desc static_l_desc =
     {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
     
    -local const static_tree_desc  static_d_desc =
    +local TCONST static_tree_desc static_d_desc =
     {static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
     
    -local const static_tree_desc  static_bl_desc =
    +local TCONST static_tree_desc static_bl_desc =
     {(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
     
     /* ===========================================================================
    - * Local (static) routines in this file.
    + * Output a short LSB first on the stream.
    + * IN assertion: there is enough room in pendingBuf.
    + */
    +#define put_short(s, w) { \
    +    put_byte(s, (uch)((w) & 0xff)); \
    +    put_byte(s, (uch)((ush)(w) >> 8)); \
    +}
    +
    +/* ===========================================================================
    + * Reverse the first len bits of a code, using straightforward code (a faster
    + * method would use a table)
    + * IN assertion: 1 <= len <= 15
      */
    +local unsigned bi_reverse(unsigned code, int len) {
    +    register unsigned res = 0;
    +    do {
    +        res |= code & 1;
    +        code >>= 1, res <<= 1;
    +    } while (--len > 0);
    +    return res >> 1;
    +}
     
    -local void tr_static_init OF((void));
    -local void init_block     OF((deflate_state *s));
    -local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
    -local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
    -local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
    -local void build_tree     OF((deflate_state *s, tree_desc *desc));
    -local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
    -local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
    -local int  build_bl_tree  OF((deflate_state *s));
    -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
    -                              int blcodes));
    -local void compress_block OF((deflate_state *s, const ct_data *ltree,
    -                              const ct_data *dtree));
    -local int  detect_data_type OF((deflate_state *s));
    -local unsigned bi_reverse OF((unsigned code, int len));
    -local void bi_windup      OF((deflate_state *s));
    -local void bi_flush       OF((deflate_state *s));
    +/* ===========================================================================
    + * Flush the bit buffer, keeping at most 7 bits in it.
    + */
    +local void bi_flush(deflate_state *s) {
    +    if (s->bi_valid == 16) {
    +        put_short(s, s->bi_buf);
    +        s->bi_buf = 0;
    +        s->bi_valid = 0;
    +    } else if (s->bi_valid >= 8) {
    +        put_byte(s, (Byte)s->bi_buf);
    +        s->bi_buf >>= 8;
    +        s->bi_valid -= 8;
    +    }
    +}
    +
    +/* ===========================================================================
    + * Flush the bit buffer and align the output on a byte boundary
    + */
    +local void bi_windup(deflate_state *s) {
    +    if (s->bi_valid > 8) {
    +        put_short(s, s->bi_buf);
    +    } else if (s->bi_valid > 0) {
    +        put_byte(s, (Byte)s->bi_buf);
    +    }
    +    s->bi_buf = 0;
    +    s->bi_valid = 0;
    +#ifdef ZLIB_DEBUG
    +    s->bits_sent = (s->bits_sent + 7) & ~7;
    +#endif
    +}
    +
    +/* ===========================================================================
    + * Generate the codes for a given tree and bit counts (which need not be
    + * optimal).
    + * IN assertion: the array bl_count contains the bit length statistics for
    + * the given tree and the field len is set for all tree elements.
    + * OUT assertion: the field code is set for all tree elements of non
    + *     zero code length.
    + */
    +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) {
    +    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
    +    unsigned code = 0;         /* running code value */
    +    int bits;                  /* bit index */
    +    int n;                     /* code index */
    +
    +    /* The distribution counts are first used to generate the code values
    +     * without bit reversal.
    +     */
    +    for (bits = 1; bits <= MAX_BITS; bits++) {
    +        code = (code + bl_count[bits - 1]) << 1;
    +        next_code[bits] = (ush)code;
    +    }
    +    /* Check that the bit counts in bl_count are consistent. The last code
    +     * must be all ones.
    +     */
    +    Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
    +            "inconsistent bit counts");
    +    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
    +
    +    for (n = 0;  n <= max_code; n++) {
    +        int len = tree[n].Len;
    +        if (len == 0) continue;
    +        /* Now reverse the bits */
    +        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
    +
    +        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
    +            n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
    +    }
    +}
     
     #ifdef GEN_TREES_H
    -local void gen_trees_header OF((void));
    +local void gen_trees_header(void);
     #endif
     
     #ifndef ZLIB_DEBUG
    @@ -191,27 +268,12 @@ local void gen_trees_header OF((void));
            send_bits(s, tree[c].Code, tree[c].Len); }
     #endif
     
    -/* ===========================================================================
    - * Output a short LSB first on the stream.
    - * IN assertion: there is enough room in pendingBuf.
    - */
    -#define put_short(s, w) { \
    -    put_byte(s, (uch)((w) & 0xff)); \
    -    put_byte(s, (uch)((ush)(w) >> 8)); \
    -}
    -
     /* ===========================================================================
      * Send a value on a given number of bits.
      * IN assertion: length <= 16 and value fits in length bits.
      */
     #ifdef ZLIB_DEBUG
    -local void send_bits      OF((deflate_state *s, int value, int length));
    -
    -local void send_bits(s, value, length)
    -    deflate_state *s;
    -    int value;  /* value to send */
    -    int length; /* number of bits */
    -{
    +local void send_bits(deflate_state *s, int value, int length) {
         Tracevv((stderr," l %2d v %4x ", length, value));
         Assert(length > 0 && length <= 15, "invalid length");
         s->bits_sent += (ulg)length;
    @@ -253,8 +315,7 @@ local void send_bits(s, value, length)
     /* ===========================================================================
      * Initialize the various 'constant' tables.
      */
    -local void tr_static_init()
    -{
    +local void tr_static_init(void) {
     #if defined(GEN_TREES_H) || !defined(STDC)
         static int static_init_done = 0;
         int n;        /* iterates over tree elements */
    @@ -347,8 +408,7 @@ local void tr_static_init()
           ((i) == (last)? "\n};\n\n" :    \
            ((i) % (width) == (width) - 1 ? ",\n" : ", "))
     
    -void gen_trees_header()
    -{
    +void gen_trees_header(void) {
         FILE *header = fopen("trees.h", "w");
         int i;
     
    @@ -397,12 +457,26 @@ void gen_trees_header()
     }
     #endif /* GEN_TREES_H */
     
    +/* ===========================================================================
    + * Initialize a new block.
    + */
    +local void init_block(deflate_state *s) {
    +    int n; /* iterates over tree elements */
    +
    +    /* Initialize the trees. */
    +    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
    +    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
    +    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
    +
    +    s->dyn_ltree[END_BLOCK].Freq = 1;
    +    s->opt_len = s->static_len = 0L;
    +    s->sym_next = s->matches = 0;
    +}
    +
     /* ===========================================================================
      * Initialize the tree data structures for a new zlib stream.
      */
    -void ZLIB_INTERNAL _tr_init(s)
    -    deflate_state *s;
    -{
    +void ZLIB_INTERNAL _tr_init(deflate_state *s) {
         tr_static_init();
     
         s->l_desc.dyn_tree = s->dyn_ltree;
    @@ -425,24 +499,6 @@ void ZLIB_INTERNAL _tr_init(s)
         init_block(s);
     }
     
    -/* ===========================================================================
    - * Initialize a new block.
    - */
    -local void init_block(s)
    -    deflate_state *s;
    -{
    -    int n; /* iterates over tree elements */
    -
    -    /* Initialize the trees. */
    -    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
    -    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
    -    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
    -
    -    s->dyn_ltree[END_BLOCK].Freq = 1;
    -    s->opt_len = s->static_len = 0L;
    -    s->sym_next = s->matches = 0;
    -}
    -
     #define SMALLEST 1
     /* Index within the heap array of least frequent node in the Huffman tree */
     
    @@ -472,11 +528,7 @@ local void init_block(s)
      * when the heap property is re-established (each father smaller than its
      * two sons).
      */
    -local void pqdownheap(s, tree, k)
    -    deflate_state *s;
    -    ct_data *tree;  /* the tree to restore */
    -    int k;               /* node to move down */
    -{
    +local void pqdownheap(deflate_state *s, ct_data *tree, int k) {
         int v = s->heap[k];
         int j = k << 1;  /* left son of k */
         while (j <= s->heap_len) {
    @@ -507,10 +559,7 @@ local void pqdownheap(s, tree, k)
      *     The length opt_len is updated; static_len is also updated if stree is
      *     not null.
      */
    -local void gen_bitlen(s, desc)
    -    deflate_state *s;
    -    tree_desc *desc;    /* the tree descriptor */
    -{
    +local void gen_bitlen(deflate_state *s, tree_desc *desc) {
         ct_data *tree        = desc->dyn_tree;
         int max_code         = desc->max_code;
         const ct_data *stree = desc->stat_desc->static_tree;
    @@ -585,48 +634,9 @@ local void gen_bitlen(s, desc)
         }
     }
     
    -/* ===========================================================================
    - * Generate the codes for a given tree and bit counts (which need not be
    - * optimal).
    - * IN assertion: the array bl_count contains the bit length statistics for
    - * the given tree and the field len is set for all tree elements.
    - * OUT assertion: the field code is set for all tree elements of non
    - *     zero code length.
    - */
    -local void gen_codes(tree, max_code, bl_count)
    -    ct_data *tree;             /* the tree to decorate */
    -    int max_code;              /* largest code with non zero frequency */
    -    ushf *bl_count;            /* number of codes at each bit length */
    -{
    -    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
    -    unsigned code = 0;         /* running code value */
    -    int bits;                  /* bit index */
    -    int n;                     /* code index */
    -
    -    /* The distribution counts are first used to generate the code values
    -     * without bit reversal.
    -     */
    -    for (bits = 1; bits <= MAX_BITS; bits++) {
    -        code = (code + bl_count[bits - 1]) << 1;
    -        next_code[bits] = (ush)code;
    -    }
    -    /* Check that the bit counts in bl_count are consistent. The last code
    -     * must be all ones.
    -     */
    -    Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
    -            "inconsistent bit counts");
    -    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
    -
    -    for (n = 0;  n <= max_code; n++) {
    -        int len = tree[n].Len;
    -        if (len == 0) continue;
    -        /* Now reverse the bits */
    -        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
    -
    -        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
    -            n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
    -    }
    -}
    +#ifdef DUMP_BL_TREE
    +#  include 
    +#endif
     
     /* ===========================================================================
      * Construct one Huffman tree and assigns the code bit strings and lengths.
    @@ -636,10 +646,7 @@ local void gen_codes(tree, max_code, bl_count)
      *     and corresponding code. The length opt_len is updated; static_len is
      *     also updated if stree is not null. The field max_code is set.
      */
    -local void build_tree(s, desc)
    -    deflate_state *s;
    -    tree_desc *desc; /* the tree descriptor */
    -{
    +local void build_tree(deflate_state *s, tree_desc *desc) {
         ct_data *tree         = desc->dyn_tree;
         const ct_data *stree  = desc->stat_desc->static_tree;
         int elems             = desc->stat_desc->elems;
    @@ -724,11 +731,7 @@ local void build_tree(s, desc)
      * Scan a literal or distance tree to determine the frequencies of the codes
      * in the bit length tree.
      */
    -local void scan_tree(s, tree, max_code)
    -    deflate_state *s;
    -    ct_data *tree;   /* the tree to be scanned */
    -    int max_code;    /* and its largest code of non zero frequency */
    -{
    +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) {
         int n;                     /* iterates over all tree elements */
         int prevlen = -1;          /* last emitted length */
         int curlen;                /* length of current code */
    @@ -769,11 +772,7 @@ local void scan_tree(s, tree, max_code)
      * Send a literal or distance tree in compressed form, using the codes in
      * bl_tree.
      */
    -local void send_tree(s, tree, max_code)
    -    deflate_state *s;
    -    ct_data *tree; /* the tree to be scanned */
    -    int max_code;       /* and its largest code of non zero frequency */
    -{
    +local void send_tree(deflate_state *s, ct_data *tree, int max_code) {
         int n;                     /* iterates over all tree elements */
         int prevlen = -1;          /* last emitted length */
         int curlen;                /* length of current code */
    @@ -820,9 +819,7 @@ local void send_tree(s, tree, max_code)
      * Construct the Huffman tree for the bit lengths and return the index in
      * bl_order of the last bit length code to send.
      */
    -local int build_bl_tree(s)
    -    deflate_state *s;
    -{
    +local int build_bl_tree(deflate_state *s) {
         int max_blindex;  /* index of last bit length code of non zero freq */
     
         /* Determine the bit length frequencies for literal and distance trees */
    @@ -855,10 +852,8 @@ local int build_bl_tree(s)
      * lengths of the bit length codes, the literal tree and the distance tree.
      * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
      */
    -local void send_all_trees(s, lcodes, dcodes, blcodes)
    -    deflate_state *s;
    -    int lcodes, dcodes, blcodes; /* number of codes for each tree */
    -{
    +local void send_all_trees(deflate_state *s, int lcodes, int dcodes,
    +                          int blcodes) {
         int rank;                    /* index in bl_order */
     
         Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
    @@ -884,12 +879,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
     /* ===========================================================================
      * Send a stored block
      */
    -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
    -    deflate_state *s;
    -    charf *buf;       /* input block */
    -    ulg stored_len;   /* length of input block */
    -    int last;         /* one if this is the last block for a file */
    -{
    +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
    +                                    ulg stored_len, int last) {
         send_bits(s, (STORED_BLOCK<<1) + last, 3);  /* send block type */
         bi_windup(s);        /* align on byte boundary */
         put_short(s, (ush)stored_len);
    @@ -908,9 +899,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
     /* ===========================================================================
      * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
      */
    -void ZLIB_INTERNAL _tr_flush_bits(s)
    -    deflate_state *s;
    -{
    +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) {
         bi_flush(s);
     }
     
    @@ -918,9 +907,7 @@ void ZLIB_INTERNAL _tr_flush_bits(s)
      * Send one empty static block to give enough lookahead for inflate.
      * This takes 10 bits, of which 7 may remain in the bit buffer.
      */
    -void ZLIB_INTERNAL _tr_align(s)
    -    deflate_state *s;
    -{
    +void ZLIB_INTERNAL _tr_align(deflate_state *s) {
         send_bits(s, STATIC_TREES<<1, 3);
         send_code(s, END_BLOCK, static_ltree);
     #ifdef ZLIB_DEBUG
    @@ -929,16 +916,108 @@ void ZLIB_INTERNAL _tr_align(s)
         bi_flush(s);
     }
     
    +/* ===========================================================================
    + * Send the block data compressed using the given Huffman trees
    + */
    +local void compress_block(deflate_state *s, const ct_data *ltree,
    +                          const ct_data *dtree) {
    +    unsigned dist;      /* distance of matched string */
    +    int lc;             /* match length or unmatched char (if dist == 0) */
    +    unsigned sx = 0;    /* running index in symbol buffers */
    +    unsigned code;      /* the code to send */
    +    int extra;          /* number of extra bits to send */
    +
    +    if (s->sym_next != 0) do {
    +#ifdef LIT_MEM
    +        dist = s->d_buf[sx];
    +        lc = s->l_buf[sx++];
    +#else
    +        dist = s->sym_buf[sx++] & 0xff;
    +        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
    +        lc = s->sym_buf[sx++];
    +#endif
    +        if (dist == 0) {
    +            send_code(s, lc, ltree); /* send a literal byte */
    +            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
    +        } else {
    +            /* Here, lc is the match length - MIN_MATCH */
    +            code = _length_code[lc];
    +            send_code(s, code + LITERALS + 1, ltree);   /* send length code */
    +            extra = extra_lbits[code];
    +            if (extra != 0) {
    +                lc -= base_length[code];
    +                send_bits(s, lc, extra);       /* send the extra length bits */
    +            }
    +            dist--; /* dist is now the match distance - 1 */
    +            code = d_code(dist);
    +            Assert (code < D_CODES, "bad d_code");
    +
    +            send_code(s, code, dtree);       /* send the distance code */
    +            extra = extra_dbits[code];
    +            if (extra != 0) {
    +                dist -= (unsigned)base_dist[code];
    +                send_bits(s, dist, extra);   /* send the extra distance bits */
    +            }
    +        } /* literal or match pair ? */
    +
    +        /* Check for no overlay of pending_buf on needed symbols */
    +#ifdef LIT_MEM
    +        Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow");
    +#else
    +        Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
    +#endif
    +
    +    } while (sx < s->sym_next);
    +
    +    send_code(s, END_BLOCK, ltree);
    +}
    +
    +/* ===========================================================================
    + * Check if the data type is TEXT or BINARY, using the following algorithm:
    + * - TEXT if the two conditions below are satisfied:
    + *    a) There are no non-portable control characters belonging to the
    + *       "block list" (0..6, 14..25, 28..31).
    + *    b) There is at least one printable character belonging to the
    + *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
    + * - BINARY otherwise.
    + * - The following partially-portable control characters form a
    + *   "gray list" that is ignored in this detection algorithm:
    + *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
    + * IN assertion: the fields Freq of dyn_ltree are set.
    + */
    +local int detect_data_type(deflate_state *s) {
    +    /* block_mask is the bit mask of block-listed bytes
    +     * set bits 0..6, 14..25, and 28..31
    +     * 0xf3ffc07f = binary 11110011111111111100000001111111
    +     */
    +    unsigned long block_mask = 0xf3ffc07fUL;
    +    int n;
    +
    +    /* Check for non-textual ("block-listed") bytes. */
    +    for (n = 0; n <= 31; n++, block_mask >>= 1)
    +        if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
    +            return Z_BINARY;
    +
    +    /* Check for textual ("allow-listed") bytes. */
    +    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
    +            || s->dyn_ltree[13].Freq != 0)
    +        return Z_TEXT;
    +    for (n = 32; n < LITERALS; n++)
    +        if (s->dyn_ltree[n].Freq != 0)
    +            return Z_TEXT;
    +
    +    /* There are no "block-listed" or "allow-listed" bytes:
    +     * this stream either is empty or has tolerated ("gray-listed") bytes only.
    +     */
    +    return Z_BINARY;
    +}
    +
     /* ===========================================================================
      * Determine the best encoding for the current block: dynamic trees, static
      * trees or store, and write out the encoded block.
      */
    -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
    -    deflate_state *s;
    -    charf *buf;       /* input block, or NULL if too old */
    -    ulg stored_len;   /* length of input block */
    -    int last;         /* one if this is the last block for a file */
    -{
    +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
    +                                   ulg stored_len, int last) {
         ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
         int max_blindex = 0;  /* index of last bit length code of non zero freq */
     
    @@ -1035,14 +1114,15 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
      * Save the match info and tally the frequency counts. Return true if
      * the current block must be flushed.
      */
    -int ZLIB_INTERNAL _tr_tally(s, dist, lc)
    -    deflate_state *s;
    -    unsigned dist;  /* distance of matched string */
    -    unsigned lc;    /* match length - MIN_MATCH or unmatched char (dist==0) */
    -{
    +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
    +#ifdef LIT_MEM
    +    s->d_buf[s->sym_next] = (ush)dist;
    +    s->l_buf[s->sym_next++] = (uch)lc;
    +#else
         s->sym_buf[s->sym_next++] = (uch)dist;
         s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
         s->sym_buf[s->sym_next++] = (uch)lc;
    +#endif
         if (dist == 0) {
             /* lc is the unmatched char */
             s->dyn_ltree[lc].Freq++;
    @@ -1059,147 +1139,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc)
         }
         return (s->sym_next == s->sym_end);
     }
    -
    -/* ===========================================================================
    - * Send the block data compressed using the given Huffman trees
    - */
    -local void compress_block(s, ltree, dtree)
    -    deflate_state *s;
    -    const ct_data *ltree; /* literal tree */
    -    const ct_data *dtree; /* distance tree */
    -{
    -    unsigned dist;      /* distance of matched string */
    -    int lc;             /* match length or unmatched char (if dist == 0) */
    -    unsigned sx = 0;    /* running index in sym_buf */
    -    unsigned code;      /* the code to send */
    -    int extra;          /* number of extra bits to send */
    -
    -    if (s->sym_next != 0) do {
    -        dist = s->sym_buf[sx++] & 0xff;
    -        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
    -        lc = s->sym_buf[sx++];
    -        if (dist == 0) {
    -            send_code(s, lc, ltree); /* send a literal byte */
    -            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
    -        } else {
    -            /* Here, lc is the match length - MIN_MATCH */
    -            code = _length_code[lc];
    -            send_code(s, code + LITERALS + 1, ltree);   /* send length code */
    -            extra = extra_lbits[code];
    -            if (extra != 0) {
    -                lc -= base_length[code];
    -                send_bits(s, lc, extra);       /* send the extra length bits */
    -            }
    -            dist--; /* dist is now the match distance - 1 */
    -            code = d_code(dist);
    -            Assert (code < D_CODES, "bad d_code");
    -
    -            send_code(s, code, dtree);       /* send the distance code */
    -            extra = extra_dbits[code];
    -            if (extra != 0) {
    -                dist -= (unsigned)base_dist[code];
    -                send_bits(s, dist, extra);   /* send the extra distance bits */
    -            }
    -        } /* literal or match pair ? */
    -
    -        /* Check that the overlay between pending_buf and sym_buf is ok: */
    -        Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
    -
    -    } while (sx < s->sym_next);
    -
    -    send_code(s, END_BLOCK, ltree);
    -}
    -
    -/* ===========================================================================
    - * Check if the data type is TEXT or BINARY, using the following algorithm:
    - * - TEXT if the two conditions below are satisfied:
    - *    a) There are no non-portable control characters belonging to the
    - *       "block list" (0..6, 14..25, 28..31).
    - *    b) There is at least one printable character belonging to the
    - *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
    - * - BINARY otherwise.
    - * - The following partially-portable control characters form a
    - *   "gray list" that is ignored in this detection algorithm:
    - *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
    - * IN assertion: the fields Freq of dyn_ltree are set.
    - */
    -local int detect_data_type(s)
    -    deflate_state *s;
    -{
    -    /* block_mask is the bit mask of block-listed bytes
    -     * set bits 0..6, 14..25, and 28..31
    -     * 0xf3ffc07f = binary 11110011111111111100000001111111
    -     */
    -    unsigned long block_mask = 0xf3ffc07fUL;
    -    int n;
    -
    -    /* Check for non-textual ("block-listed") bytes. */
    -    for (n = 0; n <= 31; n++, block_mask >>= 1)
    -        if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
    -            return Z_BINARY;
    -
    -    /* Check for textual ("allow-listed") bytes. */
    -    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
    -            || s->dyn_ltree[13].Freq != 0)
    -        return Z_TEXT;
    -    for (n = 32; n < LITERALS; n++)
    -        if (s->dyn_ltree[n].Freq != 0)
    -            return Z_TEXT;
    -
    -    /* There are no "block-listed" or "allow-listed" bytes:
    -     * this stream either is empty or has tolerated ("gray-listed") bytes only.
    -     */
    -    return Z_BINARY;
    -}
    -
    -/* ===========================================================================
    - * Reverse the first len bits of a code, using straightforward code (a faster
    - * method would use a table)
    - * IN assertion: 1 <= len <= 15
    - */
    -local unsigned bi_reverse(code, len)
    -    unsigned code; /* the value to invert */
    -    int len;       /* its bit length */
    -{
    -    register unsigned res = 0;
    -    do {
    -        res |= code & 1;
    -        code >>= 1, res <<= 1;
    -    } while (--len > 0);
    -    return res >> 1;
    -}
    -
    -/* ===========================================================================
    - * Flush the bit buffer, keeping at most 7 bits in it.
    - */
    -local void bi_flush(s)
    -    deflate_state *s;
    -{
    -    if (s->bi_valid == 16) {
    -        put_short(s, s->bi_buf);
    -        s->bi_buf = 0;
    -        s->bi_valid = 0;
    -    } else if (s->bi_valid >= 8) {
    -        put_byte(s, (Byte)s->bi_buf);
    -        s->bi_buf >>= 8;
    -        s->bi_valid -= 8;
    -    }
    -}
    -
    -/* ===========================================================================
    - * Flush the bit buffer and align the output on a byte boundary
    - */
    -local void bi_windup(s)
    -    deflate_state *s;
    -{
    -    if (s->bi_valid > 8) {
    -        put_short(s, s->bi_buf);
    -    } else if (s->bi_valid > 0) {
    -        put_byte(s, (Byte)s->bi_buf);
    -    }
    -    s->bi_buf = 0;
    -    s->bi_valid = 0;
    -#ifdef ZLIB_DEBUG
    -    s->bits_sent = (s->bits_sent + 7) & ~7;
    -#endif
    -}
    diff --git a/src/java.base/share/native/libzip/zlib/uncompr.c b/src/java.base/share/native/libzip/zlib/uncompr.c
    index 24af8d2453f..219c1d264d5 100644
    --- a/src/java.base/share/native/libzip/zlib/uncompr.c
    +++ b/src/java.base/share/native/libzip/zlib/uncompr.c
    @@ -48,12 +48,8 @@
        Z_DATA_ERROR if the input data was corrupted, including if the input data is
        an incomplete zlib stream.
     */
    -int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
    -    Bytef *dest;
    -    uLongf *destLen;
    -    const Bytef *source;
    -    uLong *sourceLen;
    -{
    +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
    +                        uLong *sourceLen) {
         z_stream stream;
         int err;
         const uInt max = (uInt)-1;
    @@ -107,11 +103,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
                err;
     }
     
    -int ZEXPORT uncompress(dest, destLen, source, sourceLen)
    -    Bytef *dest;
    -    uLongf *destLen;
    -    const Bytef *source;
    -    uLong sourceLen;
    -{
    +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
    +                       uLong sourceLen) {
         return uncompress2(dest, destLen, source, &sourceLen);
     }
    diff --git a/src/java.base/share/native/libzip/zlib/zadler32.c b/src/java.base/share/native/libzip/zlib/zadler32.c
    index e1480226310..acfd75b908e 100644
    --- a/src/java.base/share/native/libzip/zlib/zadler32.c
    +++ b/src/java.base/share/native/libzip/zlib/zadler32.c
    @@ -31,8 +31,6 @@
     
     #include "zutil.h"
     
    -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
    -
     #define BASE 65521U     /* largest prime smaller than 65536 */
     #define NMAX 5552
     /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
    @@ -84,11 +82,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
     #endif
     
     /* ========================================================================= */
    -uLong ZEXPORT adler32_z(adler, buf, len)
    -    uLong adler;
    -    const Bytef *buf;
    -    z_size_t len;
    -{
    +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {
         unsigned long sum2;
         unsigned n;
     
    @@ -155,20 +149,12 @@ uLong ZEXPORT adler32_z(adler, buf, len)
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT adler32(adler, buf, len)
    -    uLong adler;
    -    const Bytef *buf;
    -    uInt len;
    -{
    +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) {
         return adler32_z(adler, buf, len);
     }
     
     /* ========================================================================= */
    -local uLong adler32_combine_(adler1, adler2, len2)
    -    uLong adler1;
    -    uLong adler2;
    -    z_off64_t len2;
    -{
    +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) {
         unsigned long sum1;
         unsigned long sum2;
         unsigned rem;
    @@ -193,18 +179,10 @@ local uLong adler32_combine_(adler1, adler2, len2)
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT adler32_combine(adler1, adler2, len2)
    -    uLong adler1;
    -    uLong adler2;
    -    z_off_t len2;
    -{
    +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) {
         return adler32_combine_(adler1, adler2, len2);
     }
     
    -uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
    -    uLong adler1;
    -    uLong adler2;
    -    z_off64_t len2;
    -{
    +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) {
         return adler32_combine_(adler1, adler2, len2);
     }
    diff --git a/src/java.base/share/native/libzip/zlib/zconf.h b/src/java.base/share/native/libzip/zlib/zconf.h
    index 92b7eb23886..46204222f5d 100644
    --- a/src/java.base/share/native/libzip/zlib/zconf.h
    +++ b/src/java.base/share/native/libzip/zlib/zconf.h
    @@ -23,7 +23,7 @@
      */
     
     /* zconf.h -- configuration of the zlib compression library
    - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
    + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -265,7 +265,11 @@
     #endif
     
     #ifdef Z_SOLO
    -   typedef unsigned long z_size_t;
    +#  ifdef _WIN64
    +     typedef unsigned long long z_size_t;
    +#  else
    +     typedef unsigned long z_size_t;
    +#  endif
     #else
     #  define z_longlong long long
     #  if defined(NO_SIZE_T)
    @@ -320,14 +324,6 @@
     #  endif
     #endif
     
    -#ifndef Z_ARG /* function prototypes for stdarg */
    -#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
    -#    define Z_ARG(args)  args
    -#  else
    -#    define Z_ARG(args)  ()
    -#  endif
    -#endif
    -
     /* The following definitions for FAR are needed only for MSDOS mixed
      * model programming (small or medium model with some far allocations).
      * This was tested only with MSC; for other MSDOS compilers you may have
    @@ -544,7 +540,7 @@ typedef uLong FAR uLongf;
     #if !defined(_WIN32) && defined(Z_LARGE64)
     #  define z_off64_t off64_t
     #else
    -#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
    +#  if defined(_WIN32) && !defined(__GNUC__)
     #    define z_off64_t __int64
     #  else
     #    define z_off64_t z_off_t
    diff --git a/src/java.base/share/native/libzip/zlib/zcrc32.c b/src/java.base/share/native/libzip/zlib/zcrc32.c
    index 24f2350b55d..3f918f76b7c 100644
    --- a/src/java.base/share/native/libzip/zlib/zcrc32.c
    +++ b/src/java.base/share/native/libzip/zlib/zcrc32.c
    @@ -127,19 +127,6 @@
     #  define ARMCRC32
     #endif
     
    -/* Local functions. */
    -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
    -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
    -
    -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
    -    local z_word_t byte_swap OF((z_word_t word));
    -#endif
    -
    -#if defined(W) && !defined(ARMCRC32)
    -    local z_crc_t crc_word OF((z_word_t data));
    -    local z_word_t crc_word_big OF((z_word_t data));
    -#endif
    -
     #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
     /*
       Swap the bytes in a z_word_t to convert between little and big endian. Any
    @@ -147,9 +134,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
       instruction, if one is available. This assumes that word_t is either 32 bits
       or 64 bits.
      */
    -local z_word_t byte_swap(word)
    -    z_word_t word;
    -{
    +local z_word_t byte_swap(z_word_t word) {
     #  if W == 8
         return
             (word & 0xff00000000000000) >> 56 |
    @@ -170,24 +155,77 @@ local z_word_t byte_swap(word)
     }
     #endif
     
    +#ifdef DYNAMIC_CRC_TABLE
    +/* =========================================================================
    + * Table of powers of x for combining CRC-32s, filled in by make_crc_table()
    + * below.
    + */
    +   local z_crc_t FAR x2n_table[32];
    +#else
    +/* =========================================================================
    + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
    + * of x for combining CRC-32s, all made by make_crc_table().
    + */
    +#  include "crc32.h"
    +#endif
    +
     /* CRC polynomial. */
     #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
     
    -#ifdef DYNAMIC_CRC_TABLE
    +/*
    +  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
    +  reflected. For speed, this requires that a not be zero.
    + */
    +local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
    +    z_crc_t m, p;
    +
    +    m = (z_crc_t)1 << 31;
    +    p = 0;
    +    for (;;) {
    +        if (a & m) {
    +            p ^= b;
    +            if ((a & (m - 1)) == 0)
    +                break;
    +        }
    +        m >>= 1;
    +        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
    +    }
    +    return p;
    +}
     
    +/*
    +  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
    +  initialized.
    + */
    +local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
    +    z_crc_t p;
    +
    +    p = (z_crc_t)1 << 31;           /* x^0 == 1 */
    +    while (n) {
    +        if (n & 1)
    +            p = multmodp(x2n_table[k & 31], p);
    +        n >>= 1;
    +        k++;
    +    }
    +    return p;
    +}
    +
    +#ifdef DYNAMIC_CRC_TABLE
    +/* =========================================================================
    + * Build the tables for byte-wise and braided CRC-32 calculations, and a table
    + * of powers of x for combining CRC-32s.
    + */
     local z_crc_t FAR crc_table[256];
    -local z_crc_t FAR x2n_table[32];
    -local void make_crc_table OF((void));
     #ifdef W
        local z_word_t FAR crc_big_table[256];
        local z_crc_t FAR crc_braid_table[W][256];
        local z_word_t FAR crc_braid_big_table[W][256];
    -   local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
    +   local void braid(z_crc_t [][256], z_word_t [][256], int, int);
     #endif
     #ifdef MAKECRCH
    -   local void write_table OF((FILE *, const z_crc_t FAR *, int));
    -   local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
    -   local void write_table64 OF((FILE *, const z_word_t FAR *, int));
    +   local void write_table(FILE *, const z_crc_t FAR *, int);
    +   local void write_table32hi(FILE *, const z_word_t FAR *, int);
    +   local void write_table64(FILE *, const z_word_t FAR *, int);
     #endif /* MAKECRCH */
     
     /*
    @@ -200,7 +238,6 @@ local void make_crc_table OF((void));
     
     /* Definition of once functionality. */
     typedef struct once_s once_t;
    -local void once OF((once_t *, void (*)(void)));
     
     /* Check for the availability of atomics. */
     #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
    @@ -220,10 +257,7 @@ struct once_s {
       invoke once() at the same time. The state must be a once_t initialized with
       ONCE_INIT.
      */
    -local void once(state, init)
    -    once_t *state;
    -    void (*init)(void);
    -{
    +local void once(once_t *state, void (*init)(void)) {
         if (!atomic_load(&state->done)) {
             if (atomic_flag_test_and_set(&state->begun))
                 while (!atomic_load(&state->done))
    @@ -246,10 +280,7 @@ struct once_s {
     
     /* Test and set. Alas, not atomic, but tries to minimize the period of
        vulnerability. */
    -local int test_and_set OF((int volatile *));
    -local int test_and_set(flag)
    -    int volatile *flag;
    -{
    +local int test_and_set(int volatile *flag) {
         int was;
     
         was = *flag;
    @@ -258,10 +289,7 @@ local int test_and_set(flag)
     }
     
     /* Run the provided init() function once. This is not thread-safe. */
    -local void once(state, init)
    -    once_t *state;
    -    void (*init)(void);
    -{
    +local void once(once_t *state, void (*init)(void)) {
         if (!state->done) {
             if (test_and_set(&state->begun))
                 while (!state->done)
    @@ -303,8 +331,7 @@ local once_t made = ONCE_INIT;
       combinations of CRC register values and incoming bytes.
      */
     
    -local void make_crc_table()
    -{
    +local void make_crc_table(void) {
         unsigned i, j, n;
         z_crc_t p;
     
    @@ -471,11 +498,7 @@ local void make_crc_table()
        Write the 32-bit values in table[0..k-1] to out, five per line in
        hexadecimal separated by commas.
      */
    -local void write_table(out, table, k)
    -    FILE *out;
    -    const z_crc_t FAR *table;
    -    int k;
    -{
    +local void write_table(FILE *out, const z_crc_t FAR *table, int k) {
         int n;
     
         for (n = 0; n < k; n++)
    @@ -488,11 +511,7 @@ local void write_table(out, table, k)
        Write the high 32-bits of each value in table[0..k-1] to out, five per line
        in hexadecimal separated by commas.
      */
    -local void write_table32hi(out, table, k)
    -FILE *out;
    -const z_word_t FAR *table;
    -int k;
    -{
    +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {
         int n;
     
         for (n = 0; n < k; n++)
    @@ -508,11 +527,7 @@ int k;
       bits. If not, then the type cast and format string can be adjusted
       accordingly.
      */
    -local void write_table64(out, table, k)
    -    FILE *out;
    -    const z_word_t FAR *table;
    -    int k;
    -{
    +local void write_table64(FILE *out, const z_word_t FAR *table, int k) {
         int n;
     
         for (n = 0; n < k; n++)
    @@ -522,8 +537,7 @@ local void write_table64(out, table, k)
     }
     
     /* Actually do the deed. */
    -int main()
    -{
    +int main(void) {
         make_crc_table();
         return 0;
     }
    @@ -535,12 +549,7 @@ int main()
       Generate the little and big-endian braid tables for the given n and z_word_t
       size w. Each array must have room for w blocks of 256 elements.
      */
    -local void braid(ltl, big, n, w)
    -    z_crc_t ltl[][256];
    -    z_word_t big[][256];
    -    int n;
    -    int w;
    -{
    +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
         int k;
         z_crc_t i, p, q;
         for (k = 0; k < w; k++) {
    @@ -555,69 +564,13 @@ local void braid(ltl, big, n, w)
     }
     #endif
     
    -#else /* !DYNAMIC_CRC_TABLE */
    -/* ========================================================================
    - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
    - * of x for combining CRC-32s, all made by make_crc_table().
    - */
    -#include "crc32.h"
     #endif /* DYNAMIC_CRC_TABLE */
     
    -/* ========================================================================
    - * Routines used for CRC calculation. Some are also required for the table
    - * generation above.
    - */
    -
    -/*
    -  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
    -  reflected. For speed, this requires that a not be zero.
    - */
    -local z_crc_t multmodp(a, b)
    -    z_crc_t a;
    -    z_crc_t b;
    -{
    -    z_crc_t m, p;
    -
    -    m = (z_crc_t)1 << 31;
    -    p = 0;
    -    for (;;) {
    -        if (a & m) {
    -            p ^= b;
    -            if ((a & (m - 1)) == 0)
    -                break;
    -        }
    -        m >>= 1;
    -        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
    -    }
    -    return p;
    -}
    -
    -/*
    -  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
    -  initialized.
    - */
    -local z_crc_t x2nmodp(n, k)
    -    z_off64_t n;
    -    unsigned k;
    -{
    -    z_crc_t p;
    -
    -    p = (z_crc_t)1 << 31;           /* x^0 == 1 */
    -    while (n) {
    -        if (n & 1)
    -            p = multmodp(x2n_table[k & 31], p);
    -        n >>= 1;
    -        k++;
    -    }
    -    return p;
    -}
    -
     /* =========================================================================
      * This function can be used by asm versions of crc32(), and to force the
      * generation of the CRC tables in a threaded application.
      */
    -const z_crc_t FAR * ZEXPORT get_crc_table()
    -{
    +const z_crc_t FAR * ZEXPORT get_crc_table(void) {
     #ifdef DYNAMIC_CRC_TABLE
         once(&made, make_crc_table);
     #endif /* DYNAMIC_CRC_TABLE */
    @@ -643,11 +596,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
     #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
     #define Z_BATCH_MIN 800             /* fewest words in a final batch */
     
    -unsigned long ZEXPORT crc32_z(crc, buf, len)
    -    unsigned long crc;
    -    const unsigned char FAR *buf;
    -    z_size_t len;
    -{
    +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
    +                              z_size_t len) {
         z_crc_t val;
         z_word_t crc1, crc2;
         const z_word_t *word;
    @@ -747,18 +697,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
       least-significant byte of the word as the first byte of data, without any pre
       or post conditioning. This is used to combine the CRCs of each braid.
      */
    -local z_crc_t crc_word(data)
    -    z_word_t data;
    -{
    +local z_crc_t crc_word(z_word_t data) {
         int k;
         for (k = 0; k < W; k++)
             data = (data >> 8) ^ crc_table[data & 0xff];
         return (z_crc_t)data;
     }
     
    -local z_word_t crc_word_big(data)
    -    z_word_t data;
    -{
    +local z_word_t crc_word_big(z_word_t data) {
         int k;
         for (k = 0; k < W; k++)
             data = (data << 8) ^
    @@ -769,11 +715,8 @@ local z_word_t crc_word_big(data)
     #endif
     
     /* ========================================================================= */
    -unsigned long ZEXPORT crc32_z(crc, buf, len)
    -    unsigned long crc;
    -    const unsigned char FAR *buf;
    -    z_size_t len;
    -{
    +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
    +                              z_size_t len) {
         /* Return initial CRC, if requested. */
         if (buf == Z_NULL) return 0;
     
    @@ -805,8 +748,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
             words = (z_word_t const *)buf;
     
             /* Do endian check at execution time instead of compile time, since ARM
    -           processors can change the endianess at execution time. If the
    -           compiler knows what the endianess will be, it can optimize out the
    +           processors can change the endianness at execution time. If the
    +           compiler knows what the endianness will be, it can optimize out the
                check and the unused branch. */
             endian = 1;
             if (*(unsigned char *)&endian) {
    @@ -1093,20 +1036,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
     #endif
     
     /* ========================================================================= */
    -unsigned long ZEXPORT crc32(crc, buf, len)
    -    unsigned long crc;
    -    const unsigned char FAR *buf;
    -    uInt len;
    -{
    +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
    +                            uInt len) {
         return crc32_z(crc, buf, len);
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
    -    uLong crc1;
    -    uLong crc2;
    -    z_off64_t len2;
    -{
    +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
     #ifdef DYNAMIC_CRC_TABLE
         once(&made, make_crc_table);
     #endif /* DYNAMIC_CRC_TABLE */
    @@ -1114,18 +1050,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT crc32_combine(crc1, crc2, len2)
    -    uLong crc1;
    -    uLong crc2;
    -    z_off_t len2;
    -{
    +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
         return crc32_combine64(crc1, crc2, (z_off64_t)len2);
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT crc32_combine_gen64(len2)
    -    z_off64_t len2;
    -{
    +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
     #ifdef DYNAMIC_CRC_TABLE
         once(&made, make_crc_table);
     #endif /* DYNAMIC_CRC_TABLE */
    @@ -1133,17 +1063,11 @@ uLong ZEXPORT crc32_combine_gen64(len2)
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT crc32_combine_gen(len2)
    -    z_off_t len2;
    -{
    +uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
         return crc32_combine_gen64((z_off64_t)len2);
     }
     
     /* ========================================================================= */
    -uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
    -    uLong crc1;
    -    uLong crc2;
    -    uLong op;
    -{
    +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
         return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
     }
    diff --git a/src/java.base/share/native/libzip/zlib/zlib.h b/src/java.base/share/native/libzip/zlib/zlib.h
    index 10146088795..07496b5f981 100644
    --- a/src/java.base/share/native/libzip/zlib/zlib.h
    +++ b/src/java.base/share/native/libzip/zlib/zlib.h
    @@ -23,9 +23,9 @@
      */
     
     /* zlib.h -- interface of the 'zlib' general purpose compression library
    -  version 1.2.13, October 13th, 2022
    +  version 1.3.1, January 22nd, 2024
     
    -  Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
    +  Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
     
       This software is provided 'as-is', without any express or implied
       warranty.  In no event will the authors be held liable for any damages
    @@ -61,11 +61,11 @@
     extern "C" {
     #endif
     
    -#define ZLIB_VERSION "1.2.13"
    -#define ZLIB_VERNUM 0x12d0
    +#define ZLIB_VERSION "1.3.1"
    +#define ZLIB_VERNUM 0x1310
     #define ZLIB_VER_MAJOR 1
    -#define ZLIB_VER_MINOR 2
    -#define ZLIB_VER_REVISION 13
    +#define ZLIB_VER_MINOR 3
    +#define ZLIB_VER_REVISION 1
     #define ZLIB_VER_SUBREVISION 0
     
     /*
    @@ -102,8 +102,8 @@ extern "C" {
       even in the case of corrupted input.
     */
     
    -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
    -typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
    +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size);
    +typedef void   (*free_func)(voidpf opaque, voidpf address);
     
     struct internal_state;
     
    @@ -241,7 +241,7 @@ typedef gz_header FAR *gz_headerp;
     
                             /* basic functions */
     
    -ZEXTERN const char * ZEXPORT zlibVersion OF((void));
    +ZEXTERN const char * ZEXPORT zlibVersion(void);
     /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
        If the first character differs, the library code actually used is not
        compatible with the zlib.h header file used by the application.  This check
    @@ -249,12 +249,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void));
      */
     
     /*
    -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
    +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level);
     
          Initializes the internal stream state for compression.  The fields
        zalloc, zfree and opaque must be initialized before by the caller.  If
        zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
    -   allocation functions.
    +   allocation functions.  total_in, total_out, adler, and msg are initialized.
     
          The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
        1 gives best speed, 9 gives best compression, 0 gives no compression at all
    @@ -271,7 +271,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
     */
     
     
    -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
    +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush);
     /*
         deflate compresses as much data as possible, and stops when the input
       buffer becomes empty or the output buffer becomes full.  It may introduce
    @@ -344,8 +344,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
       with the same value of the flush parameter and more output space (updated
       avail_out), until the flush is complete (deflate returns with non-zero
       avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
    -  avail_out is greater than six to avoid repeated flush markers due to
    -  avail_out == 0 on return.
    +  avail_out is greater than six when the flush marker begins, in order to avoid
    +  repeated flush markers upon calling deflate() again when avail_out == 0.
     
         If the parameter flush is set to Z_FINISH, pending input is processed,
       pending output is flushed and deflate returns with Z_STREAM_END if there was
    @@ -384,7 +384,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
     */
     
     
    -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
    +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm);
     /*
          All dynamically allocated data structures for this stream are freed.
        This function discards any unprocessed input and does not flush any pending
    @@ -399,7 +399,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
     
     
     /*
    -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
    +ZEXTERN int ZEXPORT inflateInit(z_streamp strm);
     
          Initializes the internal stream state for decompression.  The fields
        next_in, avail_in, zalloc, zfree and opaque must be initialized before by
    @@ -407,7 +407,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
        read or consumed.  The allocation of a sliding window will be deferred to
        the first call of inflate (if the decompression does not complete on the
        first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates
    -   them to use default allocation functions.
    +   them to use default allocation functions.  total_in, total_out, adler, and
    +   msg are initialized.
     
          inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
        memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
    @@ -421,7 +422,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
     */
     
     
    -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
    +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush);
     /*
         inflate decompresses as much data as possible, and stops when the input
       buffer becomes empty or the output buffer becomes full.  It may introduce
    @@ -541,7 +542,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
     */
     
     
    -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
    +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm);
     /*
          All dynamically allocated data structures for this stream are freed.
        This function discards any unprocessed input and does not flush any pending
    @@ -559,12 +560,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
     */
     
     /*
    -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
    -                                     int  level,
    -                                     int  method,
    -                                     int  windowBits,
    -                                     int  memLevel,
    -                                     int  strategy));
    +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm,
    +                                 int level,
    +                                 int method,
    +                                 int windowBits,
    +                                 int memLevel,
    +                                 int strategy);
     
          This is another version of deflateInit with more compression options.  The
        fields zalloc, zfree and opaque must be initialized before by the caller.
    @@ -631,9 +632,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
        compression: this will be done by deflate().
     */
     
    -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
    -                                             const Bytef *dictionary,
    -                                             uInt  dictLength));
    +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm,
    +                                         const Bytef *dictionary,
    +                                         uInt  dictLength);
     /*
          Initializes the compression dictionary from the given byte sequence
        without producing any compressed output.  When using the zlib format, this
    @@ -675,9 +676,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
        not perform any compression: this will be done by deflate().
     */
     
    -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
    -                                             Bytef *dictionary,
    -                                             uInt  *dictLength));
    +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm,
    +                                         Bytef *dictionary,
    +                                         uInt  *dictLength);
     /*
          Returns the sliding dictionary being maintained by deflate.  dictLength is
        set to the number of bytes in the dictionary, and that many bytes are copied
    @@ -697,8 +698,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
        stream state is inconsistent.
     */
     
    -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
    -                                    z_streamp source));
    +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest,
    +                                z_streamp source);
     /*
          Sets the destination stream as a complete copy of the source stream.
     
    @@ -715,20 +716,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
        destination.
     */
     
    -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
    +ZEXTERN int ZEXPORT deflateReset(z_streamp strm);
     /*
          This function is equivalent to deflateEnd followed by deflateInit, but
        does not free and reallocate the internal compression state.  The stream
        will leave the compression level and any other attributes that may have been
    -   set unchanged.
    +   set unchanged.  total_in, total_out, adler, and msg are initialized.
     
          deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
        stream state was inconsistent (such as zalloc or state being Z_NULL).
     */
     
    -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
    -                                      int level,
    -                                      int strategy));
    +ZEXTERN int ZEXPORT deflateParams(z_streamp strm,
    +                                  int level,
    +                                  int strategy);
     /*
          Dynamically update the compression level and compression strategy.  The
        interpretation of level and strategy is as in deflateInit2().  This can be
    @@ -753,7 +754,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
        Then no more input data should be provided before the deflateParams() call.
        If this is done, the old level and strategy will be applied to the data
        compressed before deflateParams(), and the new level and strategy will be
    -   applied to the the data compressed after deflateParams().
    +   applied to the data compressed after deflateParams().
     
          deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
        state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
    @@ -764,11 +765,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
        retried with more output space.
     */
     
    -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
    -                                    int good_length,
    -                                    int max_lazy,
    -                                    int nice_length,
    -                                    int max_chain));
    +ZEXTERN int ZEXPORT deflateTune(z_streamp strm,
    +                                int good_length,
    +                                int max_lazy,
    +                                int nice_length,
    +                                int max_chain);
     /*
          Fine tune deflate's internal compression parameters.  This should only be
        used by someone who understands the algorithm used by zlib's deflate for
    @@ -781,8 +782,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
        returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
      */
     
    -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
    -                                       uLong sourceLen));
    +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm,
    +                                   uLong sourceLen);
     /*
          deflateBound() returns an upper bound on the compressed size after
        deflation of sourceLen bytes.  It must be called after deflateInit() or
    @@ -796,9 +797,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
        than Z_FINISH or Z_NO_FLUSH are used.
     */
     
    -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
    -                                       unsigned *pending,
    -                                       int *bits));
    +ZEXTERN int ZEXPORT deflatePending(z_streamp strm,
    +                                   unsigned *pending,
    +                                   int *bits);
     /*
          deflatePending() returns the number of bytes and bits of output that have
        been generated, but not yet provided in the available output.  The bytes not
    @@ -811,9 +812,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
        stream state was inconsistent.
      */
     
    -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
    -                                     int bits,
    -                                     int value));
    +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm,
    +                                 int bits,
    +                                 int value);
     /*
          deflatePrime() inserts bits in the deflate output stream.  The intent
        is that this function is used to start off the deflate output with the bits
    @@ -828,8 +829,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
        source stream state was inconsistent.
     */
     
    -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
    -                                         gz_headerp head));
    +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm,
    +                                     gz_headerp head);
     /*
          deflateSetHeader() provides gzip header information for when a gzip
        stream is requested by deflateInit2().  deflateSetHeader() may be called
    @@ -845,16 +846,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
        gzip file" and give up.
     
          If deflateSetHeader is not used, the default gzip header has text false,
    -   the time set to zero, and os set to 255, with no extra, name, or comment
    -   fields.  The gzip header is returned to the default state by deflateReset().
    +   the time set to zero, and os set to the current operating system, with no
    +   extra, name, or comment fields.  The gzip header is returned to the default
    +   state by deflateReset().
     
          deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
        stream state was inconsistent.
     */
     
     /*
    -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
    -                                     int  windowBits));
    +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm,
    +                                 int windowBits);
     
          This is another version of inflateInit with an extra parameter.  The
        fields next_in, avail_in, zalloc, zfree and opaque must be initialized
    @@ -907,9 +909,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
        deferred until inflate() is called.
     */
     
    -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
    -                                             const Bytef *dictionary,
    -                                             uInt  dictLength));
    +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm,
    +                                         const Bytef *dictionary,
    +                                         uInt  dictLength);
     /*
          Initializes the decompression dictionary from the given uncompressed byte
        sequence.  This function must be called immediately after a call of inflate,
    @@ -930,9 +932,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
        inflate().
     */
     
    -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
    -                                             Bytef *dictionary,
    -                                             uInt  *dictLength));
    +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm,
    +                                         Bytef *dictionary,
    +                                         uInt  *dictLength);
     /*
          Returns the sliding dictionary being maintained by inflate.  dictLength is
        set to the number of bytes in the dictionary, and that many bytes are copied
    @@ -945,7 +947,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
        stream state is inconsistent.
     */
     
    -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
    +ZEXTERN int ZEXPORT inflateSync(z_streamp strm);
     /*
          Skips invalid compressed data until a possible full flush point (see above
        for the description of deflate with Z_FULL_FLUSH) can be found, or until all
    @@ -958,14 +960,14 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
          inflateSync returns Z_OK if a possible full flush point has been found,
        Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
        has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
    -   In the success case, the application may save the current current value of
    -   total_in which indicates where valid compressed data was found.  In the
    -   error case, the application may repeatedly call inflateSync, providing more
    -   input each time, until success or end of the input data.
    +   In the success case, the application may save the current value of total_in
    +   which indicates where valid compressed data was found.  In the error case,
    +   the application may repeatedly call inflateSync, providing more input each
    +   time, until success or end of the input data.
     */
     
    -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
    -                                    z_streamp source));
    +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest,
    +                                z_streamp source);
     /*
          Sets the destination stream as a complete copy of the source stream.
     
    @@ -980,18 +982,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
        destination.
     */
     
    -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
    +ZEXTERN int ZEXPORT inflateReset(z_streamp strm);
     /*
          This function is equivalent to inflateEnd followed by inflateInit,
        but does not free and reallocate the internal decompression state.  The
        stream will keep attributes that may have been set by inflateInit2.
    +   total_in, total_out, adler, and msg are initialized.
     
          inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
        stream state was inconsistent (such as zalloc or state being Z_NULL).
     */
     
    -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
    -                                      int windowBits));
    +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm,
    +                                  int windowBits);
     /*
          This function is the same as inflateReset, but it also permits changing
        the wrap and window size requests.  The windowBits parameter is interpreted
    @@ -1004,9 +1007,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
        the windowBits parameter is invalid.
     */
     
    -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
    -                                     int bits,
    -                                     int value));
    +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm,
    +                                 int bits,
    +                                 int value);
     /*
          This function inserts bits in the inflate input stream.  The intent is
        that this function is used to start inflating at a bit position in the
    @@ -1025,7 +1028,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
        stream state was inconsistent.
     */
     
    -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
    +ZEXTERN long ZEXPORT inflateMark(z_streamp strm);
     /*
          This function returns two values, one in the lower 16 bits of the return
        value, and the other in the remaining upper bits, obtained by shifting the
    @@ -1053,8 +1056,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
        source stream state was inconsistent.
     */
     
    -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
    -                                         gz_headerp head));
    +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm,
    +                                     gz_headerp head);
     /*
          inflateGetHeader() requests that gzip header information be stored in the
        provided gz_header structure.  inflateGetHeader() may be called after
    @@ -1094,8 +1097,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
     */
     
     /*
    -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
    -                                        unsigned char FAR *window));
    +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits,
    +                                    unsigned char FAR *window);
     
          Initialize the internal stream state for decompression using inflateBack()
        calls.  The fields zalloc, zfree and opaque in strm must be initialized
    @@ -1115,13 +1118,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
        the version of the header file.
     */
     
    -typedef unsigned (*in_func) OF((void FAR *,
    -                                z_const unsigned char FAR * FAR *));
    -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
    +typedef unsigned (*in_func)(void FAR *,
    +                            z_const unsigned char FAR * FAR *);
    +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned);
     
    -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
    -                                    in_func in, void FAR *in_desc,
    -                                    out_func out, void FAR *out_desc));
    +ZEXTERN int ZEXPORT inflateBack(z_streamp strm,
    +                                in_func in, void FAR *in_desc,
    +                                out_func out, void FAR *out_desc);
     /*
          inflateBack() does a raw inflate with a single call using a call-back
        interface for input and output.  This is potentially more efficient than
    @@ -1189,7 +1192,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
        cannot return Z_OK.
     */
     
    -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
    +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm);
     /*
          All memory allocated by inflateBackInit() is freed.
     
    @@ -1197,7 +1200,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
        state was inconsistent.
     */
     
    -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
    +ZEXTERN uLong ZEXPORT zlibCompileFlags(void);
     /* Return flags indicating compile-time options.
     
         Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
    @@ -1250,8 +1253,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
        you need special options.
     */
     
    -ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
    -                                 const Bytef *source, uLong sourceLen));
    +ZEXTERN int ZEXPORT compress(Bytef *dest,   uLongf *destLen,
    +                             const Bytef *source, uLong sourceLen);
     /*
          Compresses the source buffer into the destination buffer.  sourceLen is
        the byte length of the source buffer.  Upon entry, destLen is the total size
    @@ -1265,9 +1268,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
        buffer.
     */
     
    -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
    -                                  const Bytef *source, uLong sourceLen,
    -                                  int level));
    +ZEXTERN int ZEXPORT compress2(Bytef *dest,   uLongf *destLen,
    +                              const Bytef *source, uLong sourceLen,
    +                              int level);
     /*
          Compresses the source buffer into the destination buffer.  The level
        parameter has the same meaning as in deflateInit.  sourceLen is the byte
    @@ -1281,15 +1284,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
        Z_STREAM_ERROR if the level parameter is invalid.
     */
     
    -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
    +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen);
     /*
          compressBound() returns an upper bound on the compressed size after
        compress() or compress2() on sourceLen bytes.  It would be used before a
        compress() or compress2() call to allocate the destination buffer.
     */
     
    -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
    -                                   const Bytef *source, uLong sourceLen));
    +ZEXTERN int ZEXPORT uncompress(Bytef *dest,   uLongf *destLen,
    +                               const Bytef *source, uLong sourceLen);
     /*
          Decompresses the source buffer into the destination buffer.  sourceLen is
        the byte length of the source buffer.  Upon entry, destLen is the total size
    @@ -1306,8 +1309,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
        buffer with the uncompressed data up to that point.
     */
     
    -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
    -                                    const Bytef *source, uLong *sourceLen));
    +ZEXTERN int ZEXPORT uncompress2(Bytef *dest,   uLongf *destLen,
    +                                const Bytef *source, uLong *sourceLen);
     /*
          Same as uncompress, except that sourceLen is a pointer, where the
        length of the source is *sourceLen.  On return, *sourceLen is the number of
    @@ -1326,7 +1329,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
     typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
     
     /*
    -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
    +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);
     
          Open the gzip (.gz) file at path for reading and decompressing, or
        compressing and writing.  The mode parameter is as in fopen ("rb" or "wb")
    @@ -1363,7 +1366,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
        file could not be opened.
     */
     
    -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
    +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode);
     /*
          Associate a gzFile with the file descriptor fd.  File descriptors are
        obtained from calls like open, dup, creat, pipe or fileno (if the file has
    @@ -1386,7 +1389,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
        will not detect if fd is invalid (unless fd is -1).
     */
     
    -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
    +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size);
     /*
          Set the internal buffer size used by this library's functions for file to
        size.  The default buffer size is 8192 bytes.  This function must be called
    @@ -1402,7 +1405,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
        too late.
     */
     
    -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
    +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy);
     /*
          Dynamically update the compression level and strategy for file.  See the
        description of deflateInit2 for the meaning of these parameters. Previously
    @@ -1413,7 +1416,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
        or Z_MEM_ERROR if there is a memory allocation error.
     */
     
    -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
    +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len);
     /*
          Read and decompress up to len uncompressed bytes from file into buf.  If
        the input file is not in gzip format, gzread copies the given number of
    @@ -1443,8 +1446,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
        Z_STREAM_ERROR.
     */
     
    -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
    -                                     gzFile file));
    +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
    +                                 gzFile file);
     /*
          Read and decompress up to nitems items of size size from file into buf,
        otherwise operating as gzread() does.  This duplicates the interface of
    @@ -1469,14 +1472,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
        file, resetting and retrying on end-of-file, when size is not 1.
     */
     
    -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
    +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len);
     /*
          Compress and write the len uncompressed bytes at buf to file. gzwrite
        returns the number of uncompressed bytes written or 0 in case of error.
     */
     
    -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
    -                                      z_size_t nitems, gzFile file));
    +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,
    +                                  z_size_t nitems, gzFile file);
     /*
          Compress and write nitems items of size size from buf to file, duplicating
        the interface of stdio's fwrite(), with size_t request and return types.  If
    @@ -1489,7 +1492,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
        is returned, and the error state is set to Z_STREAM_ERROR.
     */
     
    -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
    +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);
     /*
          Convert, format, compress, and write the arguments (...) to file under
        control of the string format, as in fprintf.  gzprintf returns the number of
    @@ -1504,7 +1507,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
        This can be determined using zlibCompileFlags().
     */
     
    -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
    +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);
     /*
          Compress and write the given null-terminated string s to file, excluding
        the terminating null character.
    @@ -1512,7 +1515,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
          gzputs returns the number of characters written, or -1 in case of error.
     */
     
    -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
    +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);
     /*
          Read and decompress bytes from file into buf, until len-1 characters are
        read, or until a newline character is read and transferred to buf, or an
    @@ -1526,13 +1529,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
        buf are indeterminate.
     */
     
    -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
    +ZEXTERN int ZEXPORT gzputc(gzFile file, int c);
     /*
          Compress and write c, converted to an unsigned char, into file.  gzputc
        returns the value that was written, or -1 in case of error.
     */
     
    -ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
    +ZEXTERN int ZEXPORT gzgetc(gzFile file);
     /*
          Read and decompress one byte from file.  gzgetc returns this byte or -1
        in case of end of file or error.  This is implemented as a macro for speed.
    @@ -1541,7 +1544,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
        points to has been clobbered or not.
     */
     
    -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
    +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file);
     /*
          Push c back onto the stream for file to be read as the first character on
        the next read.  At least one character of push-back is always allowed.
    @@ -1553,7 +1556,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
        gzseek() or gzrewind().
     */
     
    -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
    +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush);
     /*
          Flush all pending output to file.  The parameter flush is as in the
        deflate() function.  The return value is the zlib error number (see function
    @@ -1569,8 +1572,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
     */
     
     /*
    -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
    -                                   z_off_t offset, int whence));
    +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file,
    +                               z_off_t offset, int whence);
     
          Set the starting position to offset relative to whence for the next gzread
        or gzwrite on file.  The offset represents a number of bytes in the
    @@ -1588,7 +1591,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
        would be before the current position.
     */
     
    -ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
    +ZEXTERN int ZEXPORT    gzrewind(gzFile file);
     /*
          Rewind file. This function is supported only for reading.
     
    @@ -1596,7 +1599,7 @@ ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
     */
     
     /*
    -ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
    +ZEXTERN z_off_t ZEXPORT    gztell(gzFile file);
     
          Return the starting position for the next gzread or gzwrite on file.
        This position represents a number of bytes in the uncompressed data stream,
    @@ -1607,7 +1610,7 @@ ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
     */
     
     /*
    -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
    +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file);
     
          Return the current compressed (actual) read or write offset of file.  This
        offset includes the count of bytes that precede the gzip stream, for example
    @@ -1616,7 +1619,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
        be used for a progress indicator.  On error, gzoffset() returns -1.
     */
     
    -ZEXTERN int ZEXPORT gzeof OF((gzFile file));
    +ZEXTERN int ZEXPORT gzeof(gzFile file);
     /*
          Return true (1) if the end-of-file indicator for file has been set while
        reading, false (0) otherwise.  Note that the end-of-file indicator is set
    @@ -1631,7 +1634,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
        has grown since the previous end of file was detected.
     */
     
    -ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
    +ZEXTERN int ZEXPORT gzdirect(gzFile file);
     /*
          Return true (1) if file is being copied directly while reading, or false
        (0) if file is a gzip stream being decompressed.
    @@ -1652,7 +1655,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
        gzip file reading and decompression, which may not be desired.)
     */
     
    -ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
    +ZEXTERN int ZEXPORT    gzclose(gzFile file);
     /*
          Flush all pending output for file, if necessary, close file and
        deallocate the (de)compression state.  Note that once file is closed, you
    @@ -1665,8 +1668,8 @@ ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
        last read ended in the middle of a gzip stream, or Z_OK on success.
     */
     
    -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
    -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
    +ZEXTERN int ZEXPORT gzclose_r(gzFile file);
    +ZEXTERN int ZEXPORT gzclose_w(gzFile file);
     /*
          Same as gzclose(), but gzclose_r() is only for use when reading, and
        gzclose_w() is only for use when writing or appending.  The advantage to
    @@ -1677,7 +1680,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
        zlib library.
     */
     
    -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
    +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum);
     /*
          Return the error message for the last error which occurred on file.
        errnum is set to zlib error number.  If an error occurred in the file system
    @@ -1693,7 +1696,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
        functions above that do not distinguish those cases in their return values.
     */
     
    -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
    +ZEXTERN void ZEXPORT gzclearerr(gzFile file);
     /*
          Clear the error and end-of-file flags for file.  This is analogous to the
        clearerr() function in stdio.  This is useful for continuing to read a gzip
    @@ -1710,7 +1713,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
        library.
     */
     
    -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
    +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);
     /*
          Update a running Adler-32 checksum with the bytes buf[0..len-1] and
        return the updated checksum. An Adler-32 value is in the range of a 32-bit
    @@ -1730,15 +1733,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
          if (adler != original_adler) error();
     */
     
    -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
    -                                    z_size_t len));
    +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf,
    +                                z_size_t len);
     /*
          Same as adler32(), but with a size_t length.
     */
     
     /*
    -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
    -                                          z_off_t len2));
    +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2,
    +                                      z_off_t len2);
     
          Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
        and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
    @@ -1748,7 +1751,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
        negative, the result has no meaning or utility.
     */
     
    -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
    +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len);
     /*
          Update a running CRC-32 with the bytes buf[0..len-1] and return the
        updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
    @@ -1766,30 +1769,30 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
          if (crc != original_crc) error();
     */
     
    -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
    -                                  z_size_t len));
    +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf,
    +                              z_size_t len);
     /*
          Same as crc32(), but with a size_t length.
     */
     
     /*
    -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
    +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2);
     
          Combine two CRC-32 check values into one.  For two sequences of bytes,
        seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
        calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
        check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
    -   len2.
    +   len2. len2 must be non-negative.
     */
     
     /*
    -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
    +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2);
     
          Return the operator corresponding to length len2, to be used with
    -   crc32_combine_op().
    +   crc32_combine_op(). len2 must be non-negative.
     */
     
    -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
    +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op);
     /*
          Give the same result as crc32_combine(), using op in place of len2. op is
        is generated from len2 by crc32_combine_gen(). This will be faster than
    @@ -1802,20 +1805,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
     /* deflateInit and inflateInit are macros to allow checking the zlib version
      * and the compiler's view of z_stream:
      */
    -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
    -                                     const char *version, int stream_size));
    -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
    -                                     const char *version, int stream_size));
    -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
    -                                      int windowBits, int memLevel,
    -                                      int strategy, const char *version,
    -                                      int stream_size));
    -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
    -                                      const char *version, int stream_size));
    -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
    -                                         unsigned char FAR *window,
    -                                         const char *version,
    -                                         int stream_size));
    +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level,
    +                                 const char *version, int stream_size);
    +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm,
    +                                 const char *version, int stream_size);
    +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int  level, int  method,
    +                                  int windowBits, int memLevel,
    +                                  int strategy, const char *version,
    +                                  int stream_size);
    +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int  windowBits,
    +                                  const char *version, int stream_size);
    +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
    +                                     unsigned char FAR *window,
    +                                     const char *version,
    +                                     int stream_size);
     #ifdef Z_PREFIX_SET
     #  define z_deflateInit(strm, level) \
               deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
    @@ -1860,7 +1863,7 @@ struct gzFile_s {
         unsigned char *next;
         z_off64_t pos;
     };
    -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
    +ZEXTERN int ZEXPORT gzgetc_(gzFile file);       /* backward compatibility */
     #ifdef Z_PREFIX_SET
     #  undef z_gzgetc
     #  define z_gzgetc(g) \
    @@ -1877,13 +1880,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
      * without large file support, _LFS64_LARGEFILE must also be true
      */
     #ifdef Z_LARGE64
    -   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
    -   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
    -   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
    -   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
    -   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
    +   ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
    +   ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
    +   ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
    +   ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
    +   ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);
     #endif
     
     #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
    @@ -1905,50 +1908,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
     #    define crc32_combine_gen crc32_combine_gen64
     #  endif
     #  ifndef Z_LARGE64
    -     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
    -     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
    -     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
    -     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
    -     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
    -     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
    -     ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
    +     ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
    +     ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int);
    +     ZEXTERN z_off_t ZEXPORT gztell64(gzFile);
    +     ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile);
    +     ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
    +     ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
    +     ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t);
     #  endif
     #else
    -   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
    -   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
    -   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
    -   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
    -   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
    +   ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *);
    +   ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int);
    +   ZEXTERN z_off_t ZEXPORT gztell(gzFile);
    +   ZEXTERN z_off_t ZEXPORT gzoffset(gzFile);
    +   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);
     #endif
     
     #else /* Z_SOLO */
     
    -   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
    -   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
    +   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
    +   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);
     
     #endif /* !Z_SOLO */
     
     /* undocumented functions */
    -ZEXTERN const char   * ZEXPORT zError           OF((int));
    -ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
    -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
    -ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
    -ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
    -ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF((z_streamp));
    -ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
    -ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
    +ZEXTERN const char   * ZEXPORT zError(int);
    +ZEXTERN int            ZEXPORT inflateSyncPoint(z_streamp);
    +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void);
    +ZEXTERN int            ZEXPORT inflateUndermine(z_streamp, int);
    +ZEXTERN int            ZEXPORT inflateValidate(z_streamp, int);
    +ZEXTERN unsigned long  ZEXPORT inflateCodesUsed(z_streamp);
    +ZEXTERN int            ZEXPORT inflateResetKeep(z_streamp);
    +ZEXTERN int            ZEXPORT deflateResetKeep(z_streamp);
     #if defined(_WIN32) && !defined(Z_SOLO)
    -ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
    -                                            const char *mode));
    +ZEXTERN gzFile         ZEXPORT gzopen_w(const wchar_t *path,
    +                                        const char *mode);
     #endif
     #if defined(STDC) || defined(Z_HAVE_STDARG_H)
     #  ifndef Z_SOLO
    -ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
    -                                                  const char *format,
    -                                                  va_list va));
    +ZEXTERN int            ZEXPORTVA gzvprintf(gzFile file,
    +                                           const char *format,
    +                                           va_list va);
     #  endif
     #endif
     
    diff --git a/src/java.base/share/native/libzip/zlib/zutil.c b/src/java.base/share/native/libzip/zlib/zutil.c
    index ae147967861..92dda78497b 100644
    --- a/src/java.base/share/native/libzip/zlib/zutil.c
    +++ b/src/java.base/share/native/libzip/zlib/zutil.c
    @@ -48,13 +48,11 @@ z_const char * const z_errmsg[10] = {
     };
     
     
    -const char * ZEXPORT zlibVersion()
    -{
    +const char * ZEXPORT zlibVersion(void) {
         return ZLIB_VERSION;
     }
     
    -uLong ZEXPORT zlibCompileFlags()
    -{
    +uLong ZEXPORT zlibCompileFlags(void) {
         uLong flags;
     
         flags = 0;
    @@ -145,9 +143,7 @@ uLong ZEXPORT zlibCompileFlags()
     #  endif
     int ZLIB_INTERNAL z_verbose = verbose;
     
    -void ZLIB_INTERNAL z_error(m)
    -    char *m;
    -{
    +void ZLIB_INTERNAL z_error(char *m) {
         fprintf(stderr, "%s\n", m);
         exit(1);
     }
    @@ -156,9 +152,7 @@ void ZLIB_INTERNAL z_error(m)
     /* exported to allow conversion of error code to string for compress() and
      * uncompress()
      */
    -const char * ZEXPORT zError(err)
    -    int err;
    -{
    +const char * ZEXPORT zError(int err) {
         return ERR_MSG(err);
     }
     
    @@ -172,22 +166,14 @@ const char * ZEXPORT zError(err)
     
     #ifndef HAVE_MEMCPY
     
    -void ZLIB_INTERNAL zmemcpy(dest, source, len)
    -    Bytef* dest;
    -    const Bytef* source;
    -    uInt  len;
    -{
    +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) {
         if (len == 0) return;
         do {
             *dest++ = *source++; /* ??? to be unrolled */
         } while (--len != 0);
     }
     
    -int ZLIB_INTERNAL zmemcmp(s1, s2, len)
    -    const Bytef* s1;
    -    const Bytef* s2;
    -    uInt  len;
    -{
    +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) {
         uInt j;
     
         for (j = 0; j < len; j++) {
    @@ -196,10 +182,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len)
         return 0;
     }
     
    -void ZLIB_INTERNAL zmemzero(dest, len)
    -    Bytef* dest;
    -    uInt  len;
    -{
    +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) {
         if (len == 0) return;
         do {
             *dest++ = 0;  /* ??? to be unrolled */
    @@ -240,8 +223,7 @@ local ptr_table table[MAX_PTR];
      * a protected system like OS/2. Use Microsoft C instead.
      */
     
    -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
    -{
    +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
         voidpf buf;
         ulg bsize = (ulg)items*size;
     
    @@ -266,8 +248,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
         return buf;
     }
     
    -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
    -{
    +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
         int n;
     
         (void)opaque;
    @@ -303,14 +284,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
     #  define _hfree   hfree
     #endif
     
    -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
    -{
    +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) {
         (void)opaque;
         return _halloc((long)items, size);
     }
     
    -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
    -{
    +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
         (void)opaque;
         _hfree(ptr);
     }
    @@ -323,25 +302,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
     #ifndef MY_ZCALLOC /* Any system without a special alloc function */
     
     #ifndef STDC
    -extern voidp  malloc OF((uInt size));
    -extern voidp  calloc OF((uInt items, uInt size));
    -extern void   free   OF((voidpf ptr));
    +extern voidp malloc(uInt size);
    +extern voidp calloc(uInt items, uInt size);
    +extern void free(voidpf ptr);
     #endif
     
    -voidpf ZLIB_INTERNAL zcalloc(opaque, items, size)
    -    voidpf opaque;
    -    unsigned items;
    -    unsigned size;
    -{
    +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
         (void)opaque;
         return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
                                   (voidpf)calloc(items, size);
     }
     
    -void ZLIB_INTERNAL zcfree(opaque, ptr)
    -    voidpf opaque;
    -    voidpf ptr;
    -{
    +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
         (void)opaque;
         free(ptr);
     }
    diff --git a/src/java.base/share/native/libzip/zlib/zutil.h b/src/java.base/share/native/libzip/zlib/zutil.h
    index a7c842d26df..2b7e697bef9 100644
    --- a/src/java.base/share/native/libzip/zlib/zutil.h
    +++ b/src/java.base/share/native/libzip/zlib/zutil.h
    @@ -23,7 +23,7 @@
      */
     
     /* zutil.h -- internal interface and configuration of the compression library
    - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
    + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
      * For conditions of distribution and use, see copyright notice in zlib.h
      */
     
    @@ -80,7 +80,7 @@ typedef unsigned long  ulg;
     extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     /* (size given to avoid silly warnings with Visual C++) */
     
    -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
    +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)]
     
     #define ERR_RETURN(strm,err) \
       return (strm->msg = ERR_MSG(err), (err))
    @@ -161,17 +161,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     #  endif
     #endif
     
    -#if defined(MACOS) || defined(TARGET_OS_MAC)
    +#if defined(MACOS)
     #  define OS_CODE  7
    -#  ifndef Z_SOLO
    -#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
    -#      include  /* for fdopen */
    -#    else
    -#      ifndef fdopen
    -#        define fdopen(fd,mode) NULL /* No fdopen() */
    -#      endif
    -#    endif
    -#  endif
     #endif
     
     #ifdef __acorn
    @@ -194,18 +185,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     #  define OS_CODE 19
     #endif
     
    -#if defined(_BEOS_) || defined(RISCOS)
    -#  define fdopen(fd,mode) NULL /* No fdopen() */
    -#endif
    -
    -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
    -#  if defined(_WIN32_WCE)
    -#    define fdopen(fd,mode) NULL /* No fdopen() */
    -#  else
    -#    define fdopen(fd,type)  _fdopen(fd,type)
    -#  endif
    -#endif
    -
     #if defined(__BORLANDC__) && !defined(MSDOS)
       #pragma warn -8004
       #pragma warn -8008
    @@ -215,9 +194,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     /* provide prototypes for these when building zlib without LFS */
     #if !defined(_WIN32) && \
         (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
    -    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
    -    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
    -    ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
    +    ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
    +    ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
    +    ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t);
     #endif
     
             /* common defaults */
    @@ -256,16 +235,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     #    define zmemzero(dest, len) memset(dest, 0, len)
     #  endif
     #else
    -   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
    -   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
    -   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
    +   void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len);
    +   int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len);
    +   void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len);
     #endif
     
     /* Diagnostic functions */
     #ifdef ZLIB_DEBUG
     #  include 
        extern int ZLIB_INTERNAL z_verbose;
    -   extern void ZLIB_INTERNAL z_error OF((char *m));
    +   extern void ZLIB_INTERNAL z_error(char *m);
     #  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
     #  define Trace(x) {if (z_verbose>=0) fprintf x ;}
     #  define Tracev(x) {if (z_verbose>0) fprintf x ;}
    @@ -282,9 +261,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
     #endif
     
     #ifndef Z_SOLO
    -   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
    -                                    unsigned size));
    -   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
    +   voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items,
    +                                unsigned size);
    +   void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr);
     #endif
     
     #define ZALLOC(strm, items, size) \
    
    From cc65d0da5384d85ecf241c5b089cae4f40df0c00 Mon Sep 17 00:00:00 2001
    From: Dan Lutker 
    Date: Thu, 14 Mar 2024 22:18:52 +0000
    Subject: [PATCH 073/298] 8325372: Shenandoah: SIGSEGV crash in
     unnecessary_acquire due to LoadStore split through phi
    
    Reviewed-by: shade
    Backport-of: 5d414da50459b7a1e6f0f537ff3b318854b2c427
    ---
     .../gc/shenandoah/c2/shenandoahSupport.cpp    | 17 +++-
     .../gc/shenandoah/c2/shenandoahSupport.hpp    |  1 +
     src/hotspot/share/opto/memnode.cpp            |  1 +
     ...tUnsafeLoadStoreMergedHeapStableTests.java | 82 +++++++++++++++++++
     4 files changed, 100 insertions(+), 1 deletion(-)
     create mode 100644 test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java
    
    diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
    index da75706ac4c..acf4b8f0860 100644
    --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
    +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
    @@ -1728,11 +1728,26 @@ bool ShenandoahBarrierC2Support::identical_backtoback_ifs(Node* n, PhaseIdealLoo
       return true;
     }
     
    +bool ShenandoahBarrierC2Support::merge_point_safe(Node* region) {
    +  for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
    +    Node* n = region->fast_out(i);
    +    if (n->is_LoadStore()) {
    +      // Splitting a LoadStore node through phi, causes it to lose its SCMemProj: the split if code doesn't have support
    +      // for a LoadStore at the region the if is split through because that's not expected to happen (LoadStore nodes
    +      // should be between barrier nodes). It does however happen with Shenandoah though because barriers can get
    +      // expanded around a LoadStore node.
    +      return false;
    +    }
    +  }
    +  return true;
    +}
    +
    +
     void ShenandoahBarrierC2Support::merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase) {
       assert(is_heap_stable_test(n), "no other tests");
       if (identical_backtoback_ifs(n, phase)) {
         Node* n_ctrl = n->in(0);
    -    if (phase->can_split_if(n_ctrl)) {
    +    if (phase->can_split_if(n_ctrl) && merge_point_safe(n_ctrl)) {
           IfNode* dom_if = phase->idom(n_ctrl)->as_If();
           if (is_heap_stable_test(n)) {
             Node* gc_state_load = n->in(1)->in(1)->in(1)->in(1);
    diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
    index 032f338aa88..7a6ed74f563 100644
    --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
    +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
    @@ -65,6 +65,7 @@ class ShenandoahBarrierC2Support : public AllStatic {
       static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
       static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
       static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
    +  static bool merge_point_safe(Node* region);
       static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
       static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
       static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase);
    diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp
    index 76ed95c4a78..89a064a03b7 100644
    --- a/src/hotspot/share/opto/memnode.cpp
    +++ b/src/hotspot/share/opto/memnode.cpp
    @@ -3336,6 +3336,7 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
               my_mem = load_node;
             } else {
               assert(my_mem->unique_out() == this, "sanity");
    +          assert(!trailing_load_store(), "load store node can't be eliminated");
               del_req(Precedent);
               phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later
               my_mem = nullptr;
    diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java
    new file mode 100644
    index 00000000000..e7f9c777ef8
    --- /dev/null
    +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java
    @@ -0,0 +1,82 @@
    +/*
    + * Copyright (c) 2024, Red Hat, Inc. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * @test
    + * @bug 8325372
    + * @summary fusion of heap stable test causes GetAndSet node to be removed
    + * @requires vm.gc.Shenandoah
    + * @modules java.base/jdk.internal.misc:+open
    + *
    + * @run main/othervm -XX:+UseShenandoahGC -XX:-BackgroundCompilation TestUnsafeLoadStoreMergedHeapStableTests
    + */
    +
    +import jdk.internal.misc.Unsafe;
    +
    +import java.lang.reflect.Field;
    +
    +public class TestUnsafeLoadStoreMergedHeapStableTests {
    +
    +    static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
    +    static long F_OFFSET;
    +
    +    static class A {
    +        Object f;
    +    }
    +
    +    static {
    +        try {
    +            Field fField = A.class.getDeclaredField("f");
    +            F_OFFSET = UNSAFE.objectFieldOffset(fField);
    +        } catch (Exception e) {
    +            throw new RuntimeException(e);
    +        }
    +    }
    +
    +    static Object testHelper(boolean flag, Object o, long offset, Object x) {
    +        if (flag) {
    +            return UNSAFE.getAndSetObject(o, offset, x);
    +        }
    +        return null;
    +    }
    +
    +    static Object field;
    +
    +
    +    static Object test1(boolean flag, Object o, long offset) {
    +        return testHelper(flag, null, offset, field);
    +    }
    +
    +    static Object test2(Object o, long offset) {
    +        return UNSAFE.getAndSetObject(o, offset, field);
    +    }
    +
    +    static public void main(String[] args) {
    +        A a = new A();
    +        for (int i = 0; i < 20_000; i++) {
    +            testHelper(true, a, F_OFFSET, null);
    +            test1(false, a, F_OFFSET);
    +            test2(a, F_OFFSET);
    +        }
    +    }
    +}
    
    From d1af31b6098f4c55d05aa8693ff09f6dcc1e118a Mon Sep 17 00:00:00 2001
    From: Aleksey Shipilev 
    Date: Mon, 18 Mar 2024 08:59:10 +0000
    Subject: [PATCH 074/298] 8318757: VM_ThreadDump asserts in interleaved
     ObjectMonitor::deflate_monitor calls 8319896: Remove monitor deflation from
     final audit 8320515: assert(monitor->object_peek() != nullptr) failed: Owned
     monitors should not have a dead object 8325437: Safepoint polling in monitor
     deflation can cause massive logs
    
    Reviewed-by: stefank, adinn
    Backport-of: 87be6b69fe985eee01fc3344f9153d774db792c1
    ---
     make/test/JtregNativeHotspot.gmk              |   3 +-
     src/hotspot/share/prims/jvmtiEnvBase.cpp      |  11 +-
     src/hotspot/share/prims/whitebox.cpp          |   2 +-
     .../share/runtime/monitorDeflationThread.cpp  |   2 +-
     src/hotspot/share/runtime/objectMonitor.cpp   |  10 -
     src/hotspot/share/runtime/synchronizer.cpp    | 226 ++++++------------
     src/hotspot/share/runtime/synchronizer.hpp    |  92 +++----
     src/hotspot/share/runtime/vmOperations.cpp    | 137 ++++++++++-
     src/hotspot/share/runtime/vmOperations.hpp    |   4 +-
     src/hotspot/share/services/threadService.cpp  |  19 +-
     src/hotspot/share/services/threadService.hpp  |   6 +-
     test/hotspot/jtreg/TEST.groups                |   1 +
     .../runtime/Monitor/ConcurrentDeflation.java  |  81 +++++++
     .../Monitor/MonitorWithDeadObjectTest.java    |  99 ++++++++
     .../Monitor/libMonitorWithDeadObjectTest.c    | 172 +++++++++++++
     .../GetOwnedMonitorInfoTest.java              |  35 ++-
     .../libGetOwnedMonitorInfoTest.c              |   9 +
     17 files changed, 642 insertions(+), 267 deletions(-)
     create mode 100644 test/hotspot/jtreg/runtime/Monitor/ConcurrentDeflation.java
     create mode 100644 test/hotspot/jtreg/runtime/Monitor/MonitorWithDeadObjectTest.java
     create mode 100644 test/hotspot/jtreg/runtime/Monitor/libMonitorWithDeadObjectTest.c
    
    diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk
    index 5d998a4d4b1..219537f7412 100644
    --- a/make/test/JtregNativeHotspot.gmk
    +++ b/make/test/JtregNativeHotspot.gmk
    @@ -867,7 +867,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
     
     ifeq ($(call isTargetOs, windows), true)
       BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
    -  BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libTestPsig.c libnativeStack.c exeGetCreatedJavaVMs.c
    +  BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c libnativeStack.c exeGetCreatedJavaVMs.c
       BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib
       BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exedaemonDestroy := jvm.lib
     else
    @@ -1508,6 +1508,7 @@ else
       BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread
       BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm
       BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCompleteExit += -lpthread
    +  BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMonitorWithDeadObjectTest += -lpthread
       BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread
       BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -ljvm -lpthread
     endif
    diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp
    index 105902b9642..7c67a0eebfa 100644
    --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp
    +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
    @@ -988,7 +988,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_th
     
       // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
       JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
    -  ObjectSynchronizer::monitors_iterate(&jmc, java_thread);
    +  ObjectSynchronizer::owned_monitors_iterate(&jmc, java_thread);
       err = jmc.error();
     
       return err;
    @@ -1015,7 +1015,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread* calling_thread, JavaThread* java_th
     
       // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
       JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
    -  ObjectSynchronizer::monitors_iterate(&jmc, java_thread);
    +  ObjectSynchronizer::owned_monitors_iterate(&jmc, java_thread);
       err = jmc.error();
     
       return err;
    @@ -2178,6 +2178,13 @@ JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
       }
       // Filter out on stack monitors collected during stack walk.
       oop obj = mon->object();
    +
    +  if (obj == nullptr) {
    +    // This can happen if JNI code drops all references to the
    +    // owning object.
    +    return;
    +  }
    +
       bool found = false;
       for (int j = 0; j < _owned_monitors_list->length(); j++) {
         jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor;
    diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
    index f68147fea4f..4a7e69ca8b4 100644
    --- a/src/hotspot/share/prims/whitebox.cpp
    +++ b/src/hotspot/share/prims/whitebox.cpp
    @@ -1833,7 +1833,7 @@ WB_END
     
     WB_ENTRY(jboolean, WB_DeflateIdleMonitors(JNIEnv* env, jobject wb))
       log_info(monitorinflation)("WhiteBox initiated DeflateIdleMonitors");
    -  return ObjectSynchronizer::request_deflate_idle_monitors();
    +  return ObjectSynchronizer::request_deflate_idle_monitors_from_wb();
     WB_END
     
     WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb))
    diff --git a/src/hotspot/share/runtime/monitorDeflationThread.cpp b/src/hotspot/share/runtime/monitorDeflationThread.cpp
    index 01b33182973..3f2dcc6a673 100644
    --- a/src/hotspot/share/runtime/monitorDeflationThread.cpp
    +++ b/src/hotspot/share/runtime/monitorDeflationThread.cpp
    @@ -94,6 +94,6 @@ void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAP
           }
         }
     
    -    (void)ObjectSynchronizer::deflate_idle_monitors(/* ObjectMonitorsHashtable is not needed here */ nullptr);
    +    (void)ObjectSynchronizer::deflate_idle_monitors();
       }
     }
    diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp
    index c8952cf8af3..ee0f754b865 100644
    --- a/src/hotspot/share/runtime/objectMonitor.cpp
    +++ b/src/hotspot/share/runtime/objectMonitor.cpp
    @@ -509,16 +509,6 @@ bool ObjectMonitor::deflate_monitor() {
         return false;
       }
     
    -  if (ObjectSynchronizer::is_final_audit() && owner_is_DEFLATER_MARKER()) {
    -    // The final audit can see an already deflated ObjectMonitor on the
    -    // in-use list because MonitorList::unlink_deflated() might have
    -    // blocked for the final safepoint before unlinking all the deflated
    -    // monitors.
    -    assert(contentions() < 0, "must be negative: contentions=%d", contentions());
    -    // Already returned 'true' when it was originally deflated.
    -    return false;
    -  }
    -
       const oop obj = object_peek();
     
       if (obj == nullptr) {
    diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
    index 6e6f2115e1e..dd10a6e361f 100644
    --- a/src/hotspot/share/runtime/synchronizer.cpp
    +++ b/src/hotspot/share/runtime/synchronizer.cpp
    @@ -63,45 +63,6 @@
     #include "utilities/linkedlist.hpp"
     #include "utilities/preserveException.hpp"
     
    -class ObjectMonitorsHashtable::PtrList :
    -  public LinkedListImpl {};
    -
    -class CleanupObjectMonitorsHashtable: StackObj {
    - public:
    -  bool do_entry(void*& key, ObjectMonitorsHashtable::PtrList*& list) {
    -    list->clear();  // clear the LinkListNodes
    -    delete list;    // then delete the LinkedList
    -    return true;
    -  }
    -};
    -
    -ObjectMonitorsHashtable::~ObjectMonitorsHashtable() {
    -  CleanupObjectMonitorsHashtable cleanup;
    -  _ptrs->unlink(&cleanup);  // cleanup the LinkedLists
    -  delete _ptrs;             // then delete the hash table
    -}
    -
    -void ObjectMonitorsHashtable::add_entry(void* key, ObjectMonitor* om) {
    -  ObjectMonitorsHashtable::PtrList* list = get_entry(key);
    -  if (list == nullptr) {
    -    // Create new list and add it to the hash table:
    -    list = new (mtThread) ObjectMonitorsHashtable::PtrList;
    -    add_entry(key, list);
    -  }
    -  list->add(om);  // Add the ObjectMonitor to the list.
    -  _om_count++;
    -}
    -
    -bool ObjectMonitorsHashtable::has_entry(void* key, ObjectMonitor* om) {
    -  ObjectMonitorsHashtable::PtrList* list = get_entry(key);
    -  if (list == nullptr || list->find(om) == nullptr) {
    -    return false;
    -  }
    -  return true;
    -}
    -
     void MonitorList::add(ObjectMonitor* m) {
       ObjectMonitor* head;
       do {
    @@ -1099,57 +1060,46 @@ JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_ob
     
     // Visitors ...
     
    -// Iterate ObjectMonitors where the owner == thread; this does NOT include
    -// ObjectMonitors where owner is set to a stack-lock address in thread.
    -//
    -// This version of monitors_iterate() works with the in-use monitor list.
    -//
    -void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, JavaThread* thread) {
    +// Iterate over all ObjectMonitors.
    +template 
    +void ObjectSynchronizer::monitors_iterate(Function function) {
       MonitorList::Iterator iter = _in_use_list.iterator();
       while (iter.has_next()) {
    -    ObjectMonitor* mid = iter.next();
    -    if (mid->owner() != thread) {
    -      // Not owned by the target thread and intentionally skips when owner
    -      // is set to a stack-lock address in the target thread.
    -      continue;
    -    }
    -    if (!mid->is_being_async_deflated() && mid->object_peek() != nullptr) {
    -      // Only process with closure if the object is set.
    -
    -      // monitors_iterate() is only called at a safepoint or when the
    -      // target thread is suspended or when the target thread is
    -      // operating on itself. The current closures in use today are
    -      // only interested in an owned ObjectMonitor and ownership
    -      // cannot be dropped under the calling contexts so the
    -      // ObjectMonitor cannot be async deflated.
    -      closure->do_monitor(mid);
    -    }
    +    ObjectMonitor* monitor = iter.next();
    +    function(monitor);
       }
     }
     
    -// This version of monitors_iterate() works with the specified linked list.
    -//
    -void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure,
    -                                          ObjectMonitorsHashtable::PtrList* list,
    -                                          JavaThread* thread) {
    -  typedef LinkedListIterator ObjectMonitorIterator;
    -  ObjectMonitorIterator iter(list->head());
    -  while (!iter.is_empty()) {
    -    ObjectMonitor* mid = *iter.next();
    -    // Owner set to a stack-lock address in thread should never be seen here:
    -    assert(mid->owner() == thread, "must be");
    -    if (!mid->is_being_async_deflated() && mid->object_peek() != nullptr) {
    -      // Only process with closure if the object is set.
    -
    -      // monitors_iterate() is only called at a safepoint or when the
    -      // target thread is suspended or when the target thread is
    -      // operating on itself. The current closures in use today are
    -      // only interested in an owned ObjectMonitor and ownership
    -      // cannot be dropped under the calling contexts so the
    -      // ObjectMonitor cannot be async deflated.
    -      closure->do_monitor(mid);
    +// Iterate ObjectMonitors owned by any thread and where the owner `filter`
    +// returns true.
    +template 
    +void ObjectSynchronizer::owned_monitors_iterate_filtered(MonitorClosure* closure, OwnerFilter filter) {
    +  monitors_iterate([&](ObjectMonitor* monitor) {
    +    // This function is only called at a safepoint or when the
    +    // target thread is suspended or when the target thread is
    +    // operating on itself. The current closures in use today are
    +    // only interested in an owned ObjectMonitor and ownership
    +    // cannot be dropped under the calling contexts so the
    +    // ObjectMonitor cannot be async deflated.
    +    if (monitor->has_owner() && filter(monitor->owner_raw())) {
    +      assert(!monitor->is_being_async_deflated(), "Owned monitors should not be deflating");
    +
    +      closure->do_monitor(monitor);
         }
    -  }
    +  });
    +}
    +
    +// Iterate ObjectMonitors where the owner == thread; this does NOT include
    +// ObjectMonitors where owner is set to a stack-lock address in thread.
    +void ObjectSynchronizer::owned_monitors_iterate(MonitorClosure* closure, JavaThread* thread) {
    +  auto thread_filter = [&](void* owner) { return owner == thread; };
    +  return owned_monitors_iterate_filtered(closure, thread_filter);
    +}
    +
    +// Iterate ObjectMonitors owned by any thread.
    +void ObjectSynchronizer::owned_monitors_iterate(MonitorClosure* closure) {
    +  auto all_filter = [&](void* owner) { return true; };
    +  return owned_monitors_iterate_filtered(closure, all_filter);
     }
     
     static bool monitors_used_above_threshold(MonitorList* list) {
    @@ -1256,16 +1206,20 @@ bool ObjectSynchronizer::is_async_deflation_needed() {
       return false;
     }
     
    -bool ObjectSynchronizer::request_deflate_idle_monitors() {
    +void ObjectSynchronizer::request_deflate_idle_monitors() {
    +  MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag);
    +  set_is_async_deflation_requested(true);
    +  ml.notify_all();
    +}
    +
    +bool ObjectSynchronizer::request_deflate_idle_monitors_from_wb() {
       JavaThread* current = JavaThread::current();
       bool ret_code = false;
     
       jlong last_time = last_async_deflation_time_ns();
    -  set_is_async_deflation_requested(true);
    -  {
    -    MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag);
    -    ml.notify_all();
    -  }
    +
    +  request_deflate_idle_monitors();
    +
       const int N_CHECKS = 5;
       for (int i = 0; i < N_CHECKS; i++) {  // sleep for at most 5 seconds
         if (last_async_deflation_time_ns() > last_time) {
    @@ -1582,16 +1536,8 @@ void ObjectSynchronizer::chk_for_block_req(JavaThread* current, const char* op_n
     // Walk the in-use list and deflate (at most MonitorDeflationMax) idle
     // ObjectMonitors. Returns the number of deflated ObjectMonitors.
     //
    -// If table != nullptr, we gather owned ObjectMonitors indexed by the
    -// owner in the table. Please note that ObjectMonitors where the owner
    -// is set to a stack-lock address are NOT associated with the JavaThread
    -// that holds that stack-lock. All of the current consumers of
    -// ObjectMonitorsHashtable info only care about JNI locked monitors and
    -// those do not have the owner set to a stack-lock address.
    -//
     size_t ObjectSynchronizer::deflate_monitor_list(Thread* current, LogStream* ls,
    -                                                elapsedTimer* timer_p,
    -                                                ObjectMonitorsHashtable* table) {
    +                                                elapsedTimer* timer_p) {
       MonitorList::Iterator iter = _in_use_list.iterator();
       size_t deflated_count = 0;
     
    @@ -1602,18 +1548,6 @@ size_t ObjectSynchronizer::deflate_monitor_list(Thread* current, LogStream* ls,
         ObjectMonitor* mid = iter.next();
         if (mid->deflate_monitor()) {
           deflated_count++;
    -    } else if (table != nullptr) {
    -      // The caller is interested in the owned ObjectMonitors. This does
    -      // not include when owner is set to a stack-lock address in thread.
    -      // This also does not capture unowned ObjectMonitors that cannot be
    -      // deflated because of a waiter.
    -      void* key = mid->owner();
    -      // Since deflate_idle_monitors() and deflate_monitor_list() can be
    -      // called more than once, we have to make sure the entry has not
    -      // already been added.
    -      if (key != nullptr && !table->has_entry(key, mid)) {
    -        table->add_entry(key, mid);
    -      }
         }
     
         if (current->is_Java_thread()) {
    @@ -1663,9 +1597,8 @@ static size_t delete_monitors(Thread* current, GrowableArray* de
     }
     
     // This function is called by the MonitorDeflationThread to deflate
    -// ObjectMonitors. It is also called via do_final_audit_and_print_stats()
    -// and VM_ThreadDump::doit() by the VMThread.
    -size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table) {
    +// ObjectMonitors.
    +size_t ObjectSynchronizer::deflate_idle_monitors() {
       Thread* current = Thread::current();
       if (current->is_Java_thread()) {
         // The async deflation request has been processed.
    @@ -1690,14 +1623,11 @@ size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table)
       }
     
       // Deflate some idle ObjectMonitors.
    -  size_t deflated_count = deflate_monitor_list(current, ls, &timer, table);
    +  size_t deflated_count = deflate_monitor_list(current, ls, &timer);
       size_t unlinked_count = 0;
       size_t deleted_count = 0;
    -  if (deflated_count > 0 || is_final_audit()) {
    -    // There are ObjectMonitors that have been deflated or this is the
    -    // final audit and all the remaining ObjectMonitors have been
    -    // deflated, BUT the MonitorDeflationThread blocked for the final
    -    // safepoint during unlinking.
    +  if (deflated_count > 0) {
    +    // There are ObjectMonitors that have been deflated.
     
         // Unlink deflated ObjectMonitors from the in-use list.
         ResourceMark rm;
    @@ -1749,10 +1679,6 @@ size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table)
         }
         ls->print_cr("end deflating: in_use_list stats: ceiling=" SIZE_FORMAT ", count=" SIZE_FORMAT ", max=" SIZE_FORMAT,
                      in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max());
    -    if (table != nullptr) {
    -      ls->print_cr("ObjectMonitorsHashtable: key_count=" SIZE_FORMAT ", om_count=" SIZE_FORMAT,
    -                   table->key_count(), table->om_count());
    -    }
       }
     
       OM_PERFDATA_OP(MonExtant, set_value(_in_use_list.count()));
    @@ -1805,7 +1731,7 @@ void ObjectSynchronizer::release_monitors_owned_by_thread(JavaThread* current) {
       assert(current == JavaThread::current(), "must be current Java thread");
       NoSafepointVerifier nsv;
       ReleaseJavaMonitorsClosure rjmc(current);
    -  ObjectSynchronizer::monitors_iterate(&rjmc, current);
    +  ObjectSynchronizer::owned_monitors_iterate(&rjmc, current);
       assert(!current->has_pending_exception(), "Should not be possible");
       current->clear_pending_exception();
       assert(current->held_monitor_count() == 0, "Should not be possible");
    @@ -1859,12 +1785,6 @@ void ObjectSynchronizer::do_final_audit_and_print_stats() {
       log_info(monitorinflation)("Starting the final audit.");
     
       if (log_is_enabled(Info, monitorinflation)) {
    -    // Do deflations in order to reduce the in-use monitor population
    -    // that is reported by ObjectSynchronizer::log_in_use_monitor_details()
    -    // which is called by ObjectSynchronizer::audit_and_print_stats().
    -    while (deflate_idle_monitors(/* ObjectMonitorsHashtable is not needed here */ nullptr) > 0) {
    -      ; // empty
    -    }
         // The other audit_and_print_stats() call is done at the Debug
         // level at a safepoint in SafepointSynchronize::do_cleanup_tasks.
         audit_and_print_stats(true /* on_exit */);
    @@ -1913,7 +1833,7 @@ void ObjectSynchronizer::audit_and_print_stats(bool on_exit) {
         // When exiting this log output is at the Info level. When called
         // at a safepoint, this log output is at the Trace level since
         // there can be a lot of it.
    -    log_in_use_monitor_details(ls);
    +    log_in_use_monitor_details(ls, !on_exit /* log_all */);
       }
     
       ls->flush();
    @@ -1959,11 +1879,10 @@ void ObjectSynchronizer::chk_in_use_list(outputStream* out, int *error_cnt_p) {
     void ObjectSynchronizer::chk_in_use_entry(ObjectMonitor* n, outputStream* out,
                                               int* error_cnt_p) {
       if (n->owner_is_DEFLATER_MARKER()) {
    -    // This should not happen, but if it does, it is not fatal.
    -    out->print_cr("WARNING: monitor=" INTPTR_FORMAT ": in-use monitor is "
    -                  "deflated.", p2i(n));
    +    // This could happen when monitor deflation blocks for a safepoint.
         return;
       }
    +
       if (n->header().value() == 0) {
         out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use monitor must "
                       "have non-null _header field.", p2i(n));
    @@ -1993,29 +1912,34 @@ void ObjectSynchronizer::chk_in_use_entry(ObjectMonitor* n, outputStream* out,
     // Log details about ObjectMonitors on the in_use_list. The 'BHL'
     // flags indicate why the entry is in-use, 'object' and 'object type'
     // indicate the associated object and its type.
    -void ObjectSynchronizer::log_in_use_monitor_details(outputStream* out) {
    -  stringStream ss;
    +void ObjectSynchronizer::log_in_use_monitor_details(outputStream* out, bool log_all) {
       if (_in_use_list.count() > 0) {
    +    stringStream ss;
         out->print_cr("In-use monitor info:");
         out->print_cr("(B -> is_busy, H -> has hash code, L -> lock status)");
         out->print_cr("%18s  %s  %18s  %18s",
                       "monitor", "BHL", "object", "object type");
         out->print_cr("==================  ===  ==================  ==================");
    -    MonitorList::Iterator iter = _in_use_list.iterator();
    -    while (iter.has_next()) {
    -      ObjectMonitor* mid = iter.next();
    -      const oop obj = mid->object_peek();
    -      const markWord mark = mid->header();
    -      ResourceMark rm;
    -      out->print(INTPTR_FORMAT "  %d%d%d  " INTPTR_FORMAT "  %s", p2i(mid),
    -                 mid->is_busy(), mark.hash() != 0, mid->owner() != nullptr,
    -                 p2i(obj), obj == nullptr ? "" : obj->klass()->external_name());
    -      if (mid->is_busy()) {
    -        out->print(" (%s)", mid->is_busy_to_string(&ss));
    -        ss.reset();
    +
    +    auto is_interesting = [&](ObjectMonitor* monitor) {
    +      return log_all || monitor->has_owner() || monitor->is_busy();
    +    };
    +
    +    monitors_iterate([&](ObjectMonitor* monitor) {
    +      if (is_interesting(monitor)) {
    +        const oop obj = monitor->object_peek();
    +        const markWord mark = monitor->header();
    +        ResourceMark rm;
    +        out->print(INTPTR_FORMAT "  %d%d%d  " INTPTR_FORMAT "  %s", p2i(monitor),
    +                   monitor->is_busy(), mark.hash() != 0, monitor->owner() != nullptr,
    +                   p2i(obj), obj == nullptr ? "" : obj->klass()->external_name());
    +        if (monitor->is_busy()) {
    +          out->print(" (%s)", monitor->is_busy_to_string(&ss));
    +          ss.reset();
    +        }
    +        out->cr();
           }
    -      out->cr();
    -    }
    +    });
       }
     
       out->flush();
    diff --git a/src/hotspot/share/runtime/synchronizer.hpp b/src/hotspot/share/runtime/synchronizer.hpp
    index 66d08a9d998..d65a1e14bfa 100644
    --- a/src/hotspot/share/runtime/synchronizer.hpp
    +++ b/src/hotspot/share/runtime/synchronizer.hpp
    @@ -36,55 +36,6 @@ class LogStream;
     class ObjectMonitor;
     class ThreadsList;
     
    -// Hash table of void* to a list of ObjectMonitor* owned by the JavaThread.
    -// The JavaThread's owner key is either a JavaThread* or a stack lock
    -// address in the JavaThread so we use "void*".
    -//
    -class ObjectMonitorsHashtable {
    - private:
    -  static unsigned int ptr_hash(void* const& s1) {
    -    // 2654435761 = 2^32 * Phi (golden ratio)
    -    return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
    -  }
    -
    - public:
    -  class PtrList;
    -
    - private:
    -  // ResourceHashtable SIZE is specified at compile time so we
    -  // use 1031 which is the first prime after 1024.
    -  typedef ResourceHashtable PtrTable;
    -  PtrTable* _ptrs;
    -  size_t _key_count;
    -  size_t _om_count;
    -
    - public:
    -  // ResourceHashtable is passed to various functions and populated in
    -  // different places so we allocate it using C_HEAP to make it immune
    -  // from any ResourceMarks that happen to be in the code paths.
    -  ObjectMonitorsHashtable() : _ptrs(new (mtThread) PtrTable), _key_count(0), _om_count(0) {}
    -
    -  ~ObjectMonitorsHashtable();
    -
    -  void add_entry(void* key, ObjectMonitor* om);
    -
    -  void add_entry(void* key, PtrList* list) {
    -    _ptrs->put(key, list);
    -    _key_count++;
    -  }
    -
    -  PtrList* get_entry(void* key) {
    -    PtrList** listpp = _ptrs->get(key);
    -    return (listpp == nullptr) ? nullptr : *listpp;
    -  }
    -
    -  bool has_entry(void* key, ObjectMonitor* om);
    -
    -  size_t key_count() { return _key_count; }
    -  size_t om_count() { return _om_count; }
    -};
    -
     class MonitorList {
       friend class VMStructs;
     
    @@ -172,29 +123,34 @@ class ObjectSynchronizer : AllStatic {
       // JNI detach support
       static void release_monitors_owned_by_thread(JavaThread* current);
     
    +  // Iterate over all ObjectMonitors.
    +  template 
    +  static void monitors_iterate(Function function);
    +
    +  // Iterate ObjectMonitors owned by any thread and where the owner `filter`
    +  // returns true.
    +  template 
    +  static void owned_monitors_iterate_filtered(MonitorClosure* closure, OwnerFilter filter);
    +
       // Iterate ObjectMonitors where the owner == thread; this does NOT include
    -  // ObjectMonitors where owner is set to a stack lock address in thread:
    -  //
    -  // This version of monitors_iterate() works with the in-use monitor list.
    -  static void monitors_iterate(MonitorClosure* m, JavaThread* thread);
    -  // This version of monitors_iterate() works with the specified linked list.
    -  static void monitors_iterate(MonitorClosure* closure,
    -                               ObjectMonitorsHashtable::PtrList* list,
    -                               JavaThread* thread);
    +  // ObjectMonitors where owner is set to a stack lock address in thread.
    +  static void owned_monitors_iterate(MonitorClosure* m, JavaThread* thread);
    +
    +  // Iterate ObjectMonitors owned by any thread.
    +  static void owned_monitors_iterate(MonitorClosure* closure);
     
       // Initialize the gInflationLocks
       static void initialize();
     
    -  // GC: we currently use aggressive monitor deflation policy
    -  // Basically we try to deflate all monitors that are not busy.
    -  static size_t deflate_idle_monitors(ObjectMonitorsHashtable* table);
    +  // We currently use aggressive monitor deflation policy;
    +  // basically we try to deflate all monitors that are not busy.
    +  static size_t deflate_idle_monitors();
     
       // Deflate idle monitors:
       static void chk_for_block_req(JavaThread* current, const char* op_name,
                                     const char* cnt_name, size_t cnt, LogStream* ls,
                                     elapsedTimer* timer_p);
    -  static size_t deflate_monitor_list(Thread* current, LogStream* ls, elapsedTimer* timer_p,
    -                                     ObjectMonitorsHashtable* table);
    +  static size_t deflate_monitor_list(Thread* current, LogStream* ls, elapsedTimer* timer_p);
       static size_t in_use_list_ceiling();
       static void dec_in_use_list_ceiling();
       static void inc_in_use_list_ceiling();
    @@ -204,7 +160,8 @@ class ObjectSynchronizer : AllStatic {
       static bool is_final_audit() { return _is_final_audit; }
       static void set_is_final_audit() { _is_final_audit = true; }
       static jlong last_async_deflation_time_ns() { return _last_async_deflation_time_ns; }
    -  static bool request_deflate_idle_monitors();  // for whitebox test support
    +  static void request_deflate_idle_monitors();
    +  static bool request_deflate_idle_monitors_from_wb();  // for whitebox test support
       static void set_is_async_deflation_requested(bool new_value) { _is_async_deflation_requested = new_value; }
       static jlong time_since_last_async_deflation_ms();
     
    @@ -214,7 +171,7 @@ class ObjectSynchronizer : AllStatic {
       static void chk_in_use_entry(ObjectMonitor* n, outputStream* out,
                                    int* error_cnt_p);
       static void do_final_audit_and_print_stats();
    -  static void log_in_use_monitor_details(outputStream* out);
    +  static void log_in_use_monitor_details(outputStream* out, bool log_all);
     
      private:
       friend class SynchronizerTest;
    @@ -252,4 +209,11 @@ class ObjectLocker : public StackObj {
       void notify_all(TRAPS)  { ObjectSynchronizer::notifyall(_obj, CHECK); }
     };
     
    +// Interface to visit monitors
    +class ObjectMonitorsView {
    +public:
    +  // Visit monitors that belong to the given thread
    +  virtual void visit(MonitorClosure* closure, JavaThread* thread) = 0;
    +};
    +
     #endif // SHARE_RUNTIME_SYNCHRONIZER_HPP
    diff --git a/src/hotspot/share/runtime/vmOperations.cpp b/src/hotspot/share/runtime/vmOperations.cpp
    index fefb96acc7a..04ed1d5f66d 100644
    --- a/src/hotspot/share/runtime/vmOperations.cpp
    +++ b/src/hotspot/share/runtime/vmOperations.cpp
    @@ -43,12 +43,14 @@
     #include "runtime/interfaceSupport.inline.hpp"
     #include "runtime/javaThread.inline.hpp"
     #include "runtime/jniHandles.hpp"
    +#include "runtime/objectMonitor.inline.hpp"
     #include "runtime/stackFrameStream.inline.hpp"
     #include "runtime/synchronizer.hpp"
     #include "runtime/threads.hpp"
     #include "runtime/threadSMR.inline.hpp"
     #include "runtime/vmOperations.hpp"
     #include "services/threadService.hpp"
    +#include "utilities/ticks.hpp"
     
     #define VM_OP_NAME_INITIALIZE(name) #name,
     
    @@ -265,6 +267,111 @@ void VM_ThreadDump::doit_epilogue() {
       }
     }
     
    +// Hash table of void* to a list of ObjectMonitor* owned by the JavaThread.
    +// The JavaThread's owner key is either a JavaThread* or a stack lock
    +// address in the JavaThread so we use "void*".
    +//
    +class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView {
    + private:
    +  static unsigned int ptr_hash(void* const& s1) {
    +    // 2654435761 = 2^32 * Phi (golden ratio)
    +    return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
    +  }
    +
    + private:
    +  class ObjectMonitorLinkedList :
    +    public LinkedListImpl {};
    +
    +  // ResourceHashtable SIZE is specified at compile time so we
    +  // use 1031 which is the first prime after 1024.
    +  typedef ResourceHashtable PtrTable;
    +  PtrTable* _ptrs;
    +  size_t _key_count;
    +  size_t _om_count;
    +
    +  void add_list(void* key, ObjectMonitorLinkedList* list) {
    +    _ptrs->put(key, list);
    +    _key_count++;
    +  }
    +
    +  ObjectMonitorLinkedList* get_list(void* key) {
    +    ObjectMonitorLinkedList** listpp = _ptrs->get(key);
    +    return (listpp == nullptr) ? nullptr : *listpp;
    +  }
    +
    +  void add(ObjectMonitor* monitor) {
    +    void* key = monitor->owner();
    +
    +    ObjectMonitorLinkedList* list = get_list(key);
    +    if (list == nullptr) {
    +      // Create new list and add it to the hash table:
    +      list = new (mtThread) ObjectMonitorLinkedList;
    +      _ptrs->put(key, list);
    +      _key_count++;
    +    }
    +
    +    assert(list->find(monitor) == nullptr, "Should not contain duplicates");
    +    list->add(monitor);  // Add the ObjectMonitor to the list.
    +    _om_count++;
    +  }
    +
    + public:
    +  // ResourceHashtable is passed to various functions and populated in
    +  // different places so we allocate it using C_HEAP to make it immune
    +  // from any ResourceMarks that happen to be in the code paths.
    +  ObjectMonitorsDump() : _ptrs(new (mtThread) PtrTable), _key_count(0), _om_count(0) {}
    +
    +  ~ObjectMonitorsDump() {
    +    class CleanupObjectMonitorsDump: StackObj {
    +     public:
    +      bool do_entry(void*& key, ObjectMonitorLinkedList*& list) {
    +        list->clear();  // clear the LinkListNodes
    +        delete list;    // then delete the LinkedList
    +        return true;
    +      }
    +    } cleanup;
    +
    +    _ptrs->unlink(&cleanup);  // cleanup the LinkedLists
    +    delete _ptrs;             // then delete the hash table
    +  }
    +
    +  // Implements MonitorClosure used to collect all owned monitors in the system
    +  void do_monitor(ObjectMonitor* monitor) override {
    +    assert(monitor->has_owner(), "Expects only owned monitors");
    +
    +    if (monitor->is_owner_anonymous()) {
    +      // There's no need to collect anonymous owned monitors
    +      // because the caller of this code is only interested
    +      // in JNI owned monitors.
    +      return;
    +    }
    +
    +    if (monitor->object_peek() == nullptr) {
    +      // JNI code doesn't necessarily keep the monitor object
    +      // alive. Filter out monitors with dead objects.
    +      return;
    +    }
    +
    +    add(monitor);
    +  }
    +
    +  // Implements the ObjectMonitorsView interface
    +  void visit(MonitorClosure* closure, JavaThread* thread) override {
    +    ObjectMonitorLinkedList* list = get_list(thread);
    +    LinkedListIterator iter(list != nullptr ? list->head() : nullptr);
    +    while (!iter.is_empty()) {
    +      ObjectMonitor* monitor = *iter.next();
    +      closure->do_monitor(monitor);
    +    }
    +  }
    +
    +  size_t key_count() { return _key_count; }
    +  size_t om_count() { return _om_count; }
    +};
    +
     void VM_ThreadDump::doit() {
       ResourceMark rm;
     
    @@ -279,16 +386,20 @@ void VM_ThreadDump::doit() {
         concurrent_locks.dump_at_safepoint();
       }
     
    -  ObjectMonitorsHashtable table;
    -  ObjectMonitorsHashtable* tablep = nullptr;
    +  ObjectMonitorsDump object_monitors;
       if (_with_locked_monitors) {
    -    // The caller wants locked monitor information and that's expensive to gather
    -    // when there are a lot of inflated monitors. So we deflate idle monitors and
    -    // gather information about owned monitors at the same time.
    -    tablep = &table;
    -    while (ObjectSynchronizer::deflate_idle_monitors(tablep) > 0) {
    -      ; /* empty */
    -    }
    +    // Gather information about owned monitors.
    +    ObjectSynchronizer::owned_monitors_iterate(&object_monitors);
    +
    +    // If there are many object monitors in the system then the above iteration
    +    // can start to take time. Be friendly to following thread dumps by telling
    +    // the MonitorDeflationThread to deflate monitors.
    +    //
    +    // This is trying to be somewhat backwards compatible with the previous
    +    // implementation, which performed monitor deflation right here. We might
    +    // want to reconsider the need to trigger monitor deflation from the thread
    +    // dumping and instead maybe tweak the deflation heuristics.
    +    ObjectSynchronizer::request_deflate_idle_monitors();
       }
     
       if (_num_threads == 0) {
    @@ -305,7 +416,7 @@ void VM_ThreadDump::doit() {
           if (_with_locked_synchronizers) {
             tcl = concurrent_locks.thread_concurrent_locks(jt);
           }
    -      snapshot_thread(jt, tcl, tablep);
    +      snapshot_thread(jt, tcl, &object_monitors);
         }
       } else {
         // Snapshot threads in the given _threads array
    @@ -340,15 +451,15 @@ void VM_ThreadDump::doit() {
           if (_with_locked_synchronizers) {
             tcl = concurrent_locks.thread_concurrent_locks(jt);
           }
    -      snapshot_thread(jt, tcl, tablep);
    +      snapshot_thread(jt, tcl, &object_monitors);
         }
       }
     }
     
     void VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl,
    -                                    ObjectMonitorsHashtable* table) {
    +                                    ObjectMonitorsView* monitors) {
       ThreadSnapshot* snapshot = _result->add_thread_snapshot(java_thread);
    -  snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors, table, false);
    +  snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors, monitors, false);
       snapshot->set_concurrent_locks(tcl);
     }
     
    diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp
    index 152d72a0400..8778fe29ade 100644
    --- a/src/hotspot/share/runtime/vmOperations.hpp
    +++ b/src/hotspot/share/runtime/vmOperations.hpp
    @@ -30,7 +30,7 @@
     #include "runtime/vmOperation.hpp"
     #include "runtime/threadSMR.hpp"
     
    -class ObjectMonitorsHashtable;
    +class ObjectMonitorsView;
     
     // A hodge podge of commonly used VM Operations
     
    @@ -204,7 +204,7 @@ class VM_ThreadDump : public VM_Operation {
       bool                           _with_locked_synchronizers;
     
       void snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl,
    -                       ObjectMonitorsHashtable* table);
    +                       ObjectMonitorsView* monitors);
     
      public:
       VM_ThreadDump(ThreadDumpResult* result,
    diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp
    index bae98f0aadf..e95c832894f 100644
    --- a/src/hotspot/share/services/threadService.cpp
    +++ b/src/hotspot/share/services/threadService.cpp
    @@ -45,6 +45,7 @@
     #include "runtime/init.hpp"
     #include "runtime/javaThread.inline.hpp"
     #include "runtime/objectMonitor.inline.hpp"
    +#include "runtime/synchronizer.hpp"
     #include "runtime/thread.inline.hpp"
     #include "runtime/threads.hpp"
     #include "runtime/threadSMR.inline.hpp"
    @@ -687,7 +688,7 @@ ThreadStackTrace::~ThreadStackTrace() {
       }
     }
     
    -void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth, ObjectMonitorsHashtable* table, bool full) {
    +void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth, ObjectMonitorsView* monitors, bool full) {
       assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
     
       if (_thread->has_last_Java_frame()) {
    @@ -723,17 +724,7 @@ void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth, ObjectMonitorsHasht
         // Iterate inflated monitors and find monitors locked by this thread
         // that are not found in the stack, e.g. JNI locked monitors:
         InflatedMonitorsClosure imc(this);
    -    if (table != nullptr) {
    -      // Get the ObjectMonitors locked by the target thread, if any,
    -      // and does not include any where owner is set to a stack lock
    -      // address in the target thread:
    -      ObjectMonitorsHashtable::PtrList* list = table->get_entry(_thread);
    -      if (list != nullptr) {
    -        ObjectSynchronizer::monitors_iterate(&imc, list, _thread);
    -      }
    -    } else {
    -      ObjectSynchronizer::monitors_iterate(&imc, _thread);
    -    }
    +    monitors->visit(&imc, _thread);
       }
     }
     
    @@ -988,9 +979,9 @@ ThreadSnapshot::~ThreadSnapshot() {
     }
     
     void ThreadSnapshot::dump_stack_at_safepoint(int max_depth, bool with_locked_monitors,
    -                                             ObjectMonitorsHashtable* table, bool full) {
    +                                             ObjectMonitorsView* monitors, bool full) {
       _stack_trace = new ThreadStackTrace(_thread, with_locked_monitors);
    -  _stack_trace->dump_stack_at_safepoint(max_depth, table, full);
    +  _stack_trace->dump_stack_at_safepoint(max_depth, monitors, full);
     }
     
     
    diff --git a/src/hotspot/share/services/threadService.hpp b/src/hotspot/share/services/threadService.hpp
    index ce0ab3c5027..f2b72700a4b 100644
    --- a/src/hotspot/share/services/threadService.hpp
    +++ b/src/hotspot/share/services/threadService.hpp
    @@ -38,7 +38,7 @@
     #include "services/management.hpp"
     
     class DeadlockCycle;
    -class ObjectMonitorsHashtable;
    +class ObjectMonitorsView;
     class OopClosure;
     class StackFrameInfo;
     class ThreadConcurrentLocks;
    @@ -264,7 +264,7 @@ class ThreadSnapshot : public CHeapObj {
       ThreadConcurrentLocks* get_concurrent_locks()     { return _concurrent_locks; }
     
       void        dump_stack_at_safepoint(int max_depth, bool with_locked_monitors,
    -                                      ObjectMonitorsHashtable* table, bool full);
    +                                      ObjectMonitorsView* monitors, bool full);
       void        set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; }
       void        metadata_do(void f(Metadata*));
     };
    @@ -287,7 +287,7 @@ class ThreadStackTrace : public CHeapObj {
       int             get_stack_depth()     { return _depth; }
     
       void            add_stack_frame(javaVFrame* jvf);
    -  void            dump_stack_at_safepoint(int max_depth, ObjectMonitorsHashtable* table, bool full);
    +  void            dump_stack_at_safepoint(int max_depth, ObjectMonitorsView* monitors, bool full);
       Handle          allocate_fill_stack_trace_element_array(TRAPS);
       void            metadata_do(void f(Metadata*));
       GrowableArray* jni_locked_monitors() { return _jni_locked_monitors; }
    diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups
    index c6e8461a54c..4923fbd5b27 100644
    --- a/test/hotspot/jtreg/TEST.groups
    +++ b/test/hotspot/jtreg/TEST.groups
    @@ -399,6 +399,7 @@ tier1_runtime = \
      -runtime/modules/LoadUnloadModuleStress.java \
      -runtime/modules/ModuleStress/ExportModuleStressTest.java \
      -runtime/modules/ModuleStress/ModuleStressGC.java \
    + -runtime/Monitor/ConcurrentDeflation.java \
      -runtime/ReservedStack \
      -runtime/SelectionResolution/AbstractMethodErrorTest.java \
      -runtime/SelectionResolution/IllegalAccessErrorTest.java \
    diff --git a/test/hotspot/jtreg/runtime/Monitor/ConcurrentDeflation.java b/test/hotspot/jtreg/runtime/Monitor/ConcurrentDeflation.java
    new file mode 100644
    index 00000000000..01a463c36ac
    --- /dev/null
    +++ b/test/hotspot/jtreg/runtime/Monitor/ConcurrentDeflation.java
    @@ -0,0 +1,81 @@
    +/*
    + * Copyright (c) 2023, 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 jdk.test.lib.process.OutputAnalyzer;
    +import jdk.test.lib.Platform;
    +import jdk.test.lib.process.ProcessTools;
    +
    +import java.lang.management.ManagementFactory;
    +import java.lang.management.ThreadInfo;
    +import java.lang.management.ThreadMXBean;
    +
    +/*
    + * @test
    + * @bug 8318757
    + * @summary Test concurrent monitor deflation by MonitorDeflationThread and thread dumping
    + * @library /test/lib
    + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:GuaranteedAsyncDeflationInterval=2000 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=0 ConcurrentDeflation
    + */
    +
    +public class ConcurrentDeflation {
    +    public static final long TOTAL_RUN_TIME_NS = 10_000_000_000L;
    +    public static Object[] monitors = new Object[1000];
    +    public static int monitorCount;
    +
    +    public static void main(String[] args) throws Exception {
    +        Thread threadDumper = new Thread(() -> dumpThreads());
    +        threadDumper.start();
    +        Thread monitorCreator = new Thread(() -> createMonitors());
    +        monitorCreator.start();
    +
    +        threadDumper.join();
    +        monitorCreator.join();
    +    }
    +
    +    static private void dumpThreads() {
    +        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    +        int dumpCount = 0;
    +        long startTime = System.nanoTime();
    +        while (System.nanoTime() - startTime < TOTAL_RUN_TIME_NS) {
    +            threadBean.dumpAllThreads(true, false);
    +            dumpCount++;
    +            try {
    +                Thread.sleep(10);
    +            } catch (InterruptedException e) {}
    +        }
    +        System.out.println("Dumped all thread info " + dumpCount + " times");
    +    }
    +
    +    static private void createMonitors() {
    +        int index = 0;
    +        long startTime = System.nanoTime();
    +        while (System.nanoTime() - startTime < TOTAL_RUN_TIME_NS) {
    +            index = index++ % 1000;
    +            monitors[index] = new Object();
    +            synchronized (monitors[index]) {
    +                monitorCount++;
    +            }
    +        }
    +        System.out.println("Created " + monitorCount + " monitors");
    +    }
    +}
    diff --git a/test/hotspot/jtreg/runtime/Monitor/MonitorWithDeadObjectTest.java b/test/hotspot/jtreg/runtime/Monitor/MonitorWithDeadObjectTest.java
    new file mode 100644
    index 00000000000..31aeaccf07a
    --- /dev/null
    +++ b/test/hotspot/jtreg/runtime/Monitor/MonitorWithDeadObjectTest.java
    @@ -0,0 +1,99 @@
    +/*
    + * Copyright (c) 2022, 2023, 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.
    + *
    + */
    +
    +/*
    + * @bug 8320515
    + * @summary This test checks that ObjectMonitors with dead objects don't
    + *          cause asserts, crashes, or failures when various sub-systems
    + *          in the JVM find them.
    + * @library /testlibrary /test/lib
    + * @modules jdk.management
    + */
    +
    +/*
    + * @requires os.family != "windows" & os.family != "aix"
    + * @test id=DetachThread
    + * @run main/othervm/native MonitorWithDeadObjectTest 0
    + */
    +
    +/*
    + * @requires os.family != "windows" & os.family != "aix"
    + * @test id=DumpThreadsBeforeDetach
    + * @run main/othervm/native MonitorWithDeadObjectTest 1
    + */
    +
    +/*
    + * @requires os.family != "windows" & os.family != "aix"
    + * @test id=DumpThreadsAfterDetach
    + * @run main/othervm/native MonitorWithDeadObjectTest 2
    + */
    +
    +import java.lang.management.ManagementFactory;
    +import java.lang.management.ThreadMXBean;
    +
    +public class MonitorWithDeadObjectTest {
    +    public static native void createMonitorWithDeadObject();
    +    public static native void createMonitorWithDeadObjectDumpThreadsBeforeDetach();
    +
    +    static {
    +        System.loadLibrary("MonitorWithDeadObjectTest");
    +    }
    +
    +    private static void dumpThreadsWithLockedMonitors() {
    +        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    +        threadBean.dumpAllThreads(true, false);
    +    }
    +
    +    private static void testDetachThread() {
    +        // Create an ObjectMonitor with a dead object from an attached thread.
    +        // This used to provoke an assert in DetachCurrentThread.
    +        createMonitorWithDeadObject();
    +    }
    +
    +    private static void testDumpThreadsBeforeDetach() {
    +        // Create an ObjectMonitor with a dead object from an attached thread
    +        // and perform a thread dump before detaching the thread.
    +        createMonitorWithDeadObjectDumpThreadsBeforeDetach();
    +    }
    +
    +    private static void testDumpThreadsAfterDetach() {
    +        createMonitorWithDeadObject();
    +
    +        // The thread dumping code used to not tolerate monitors with dead
    +        // objects and the detach code used to not unlock these monitors, so
    +        // test that we don't end up with a bug where these monitors are not
    +        // unlocked and then passed to the thread dumping code.
    +        dumpThreadsWithLockedMonitors();
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        int test = Integer.parseInt(args[0]);
    +        switch (test) {
    +            case 0: testDetachThread(); break;
    +            case 1: testDumpThreadsBeforeDetach(); break;
    +            case 2: testDumpThreadsAfterDetach(); break;
    +            default: throw new RuntimeException("Unknown test");
    +        };
    +    }
    +}
    diff --git a/test/hotspot/jtreg/runtime/Monitor/libMonitorWithDeadObjectTest.c b/test/hotspot/jtreg/runtime/Monitor/libMonitorWithDeadObjectTest.c
    new file mode 100644
    index 00000000000..7e12eac2ea2
    --- /dev/null
    +++ b/test/hotspot/jtreg/runtime/Monitor/libMonitorWithDeadObjectTest.c
    @@ -0,0 +1,172 @@
    +/*
    + * Copyright (c) 2022, 2023, 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.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +static JavaVM* jvm;
    +static pthread_t attacher;
    +
    +#define die(x) do { printf("%s:%s\n",x , __func__); perror(x); exit(EXIT_FAILURE); } while (0)
    +
    +static void check_exception(JNIEnv* env, const char* msg) {
    +  if ((*env)->ExceptionCheck(env)) {
    +    fprintf(stderr, "Error: %s", msg);
    +    exit(-1);
    +  }
    +}
    +
    +#define check(env, what, msg)                      \
    +  check_exception((env), (msg));                   \
    +  do {                                             \
    +    if ((what) == 0) {                             \
    +      fprintf(stderr, #what "is null: %s", (msg)); \
    +      exit(-2);                                    \
    +    }                                              \
    +  } while (0)
    +
    +static jobject create_object(JNIEnv* env) {
    +  jclass clazz = (*env)->FindClass(env, "java/lang/Object");
    +  check(env, clazz, "No class");
    +
    +  jmethodID constructor = (*env)->GetMethodID(env, clazz, "", "()V");
    +  check(env, constructor, "No constructor");
    +
    +  jobject obj = (*env)->NewObject(env, clazz, constructor);
    +  check(env, constructor, "No object");
    +
    +  return obj;
    +}
    +
    +static void system_gc(JNIEnv* env) {
    +  jclass clazz = (*env)->FindClass(env, "java/lang/System");
    +  check(env, clazz, "No class");
    +
    +  jmethodID method = (*env)->GetStaticMethodID(env, clazz, "gc", "()V");
    +  check(env, method, "No method");
    +
    +  (*env)->CallStaticVoidMethod(env, clazz, method);
    +  check_exception(env, "Calling System.gc()");
    +}
    +
    +static void thread_dump_with_locked_monitors(JNIEnv* env) {
    +  jclass ManagementFactoryClass = (*env)->FindClass(env, "java/lang/management/ManagementFactory");
    +  check(env, ManagementFactoryClass, "No ManagementFactory class");
    +
    +  jmethodID getThreadMXBeanMethod = (*env)->GetStaticMethodID(env, ManagementFactoryClass, "getThreadMXBean", "()Ljava/lang/management/ThreadMXBean;");
    +  check(env, getThreadMXBeanMethod, "No getThreadMXBean method");
    +
    +  jobject threadBean = (*env)->CallStaticObjectMethod(env, ManagementFactoryClass, getThreadMXBeanMethod);
    +  check(env, threadBean, "Calling getThreadMXBean()");
    +
    +  jclass ThreadMXBeanClass = (*env)->FindClass(env, "java/lang/management/ThreadMXBean");
    +  check(env, ThreadMXBeanClass, "No ThreadMXBean class");
    +
    +  jmethodID dumpAllThreadsMethod = (*env)->GetMethodID(env, ThreadMXBeanClass, "dumpAllThreads", "(ZZ)[Ljava/lang/management/ThreadInfo;");
    +  check(env, dumpAllThreadsMethod, "No dumpAllThreads method");
    +
    +  // The 'lockedMonitors == true' is what causes the monitor with a dead object to be examined.
    +  jobject array = (*env)->CallObjectMethod(env, threadBean, dumpAllThreadsMethod, JNI_TRUE /* lockedMonitors */, JNI_FALSE /* lockedSynchronizers*/);
    +  check(env, array, "Calling dumpAllThreads(true, false)");
    +}
    +
    +static void create_monitor_with_dead_object(JNIEnv* env) {
    +  jobject obj = create_object(env);
    +
    +  if ((*env)->MonitorEnter(env, obj) != 0) die("MonitorEnter");
    +
    +  // Drop the last strong reference to the object associated with the monitor.
    +  // The monitor only keeps a weak reference to the object.
    +  (*env)->DeleteLocalRef(env, obj);
    +
    +  // Let the GC clear the weak reference to the object.
    +  system_gc(env);
    +}
    +
    +static void* create_monitor_with_dead_object_in_thread(void* arg) {
    +  JNIEnv* env;
    +  int res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
    +  if (res != JNI_OK) die("AttachCurrentThread");
    +
    +  // Make the correct incantation to create a monitor with a dead object.
    +  create_monitor_with_dead_object(env);
    +
    +  // DetachCurrentThread will try to unlock held monitors. This has been a
    +  // source of at least two bugs:
    +  // - When the object reference in the monitor was cleared, the monitor
    +  //   iterator code would skip it, preventing it from being unlocked when
    +  //   the owner thread detached, leaving it lingering in the system.
    +  // - When the monitor iterator API was rewritten the code was changed to
    +  //   assert that we didn't have "owned" monitors with dead objects. This
    +  //   test provokes that situation and that asserts.
    +  if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) die("DetachCurrentThread");
    +
    +  return NULL;
    +}
    +
    +static void* create_monitor_with_dead_object_and_dump_threads_in_thread(void* arg) {
    +  JNIEnv* env;
    +  int res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
    +  if (res != JNI_OK) die("AttachCurrentThread");
    +
    +  // Make the correct incantation to create a monitor with a dead object.
    +  create_monitor_with_dead_object(env);
    +
    +  // Perform a thread dump that checks for all thread's monitors.
    +  // That code didn't expect the monitor iterators to return monitors
    +  // with dead objects and therefore asserted/crashed.
    +  thread_dump_with_locked_monitors(env);
    +
    +  if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) die("DetachCurrentThread");
    +
    +  return NULL;
    +}
    +
    +JNIEXPORT void JNICALL Java_MonitorWithDeadObjectTest_createMonitorWithDeadObject(JNIEnv* env, jclass jc) {
    +  void* ret;
    +
    +  (*env)->GetJavaVM(env, &jvm);
    +
    +  if (pthread_create(&attacher, NULL, create_monitor_with_dead_object_in_thread, NULL) != 0) die("pthread_create");
    +  if (pthread_join(attacher, &ret) != 0) die("pthread_join");
    +}
    +
    +JNIEXPORT void JNICALL Java_MonitorWithDeadObjectTest_createMonitorWithDeadObjectDumpThreadsBeforeDetach(JNIEnv* env, jclass jc) {
    +  void* ret;
    +
    +  (*env)->GetJavaVM(env, &jvm);
    +
    +  if (pthread_create(&attacher, NULL, create_monitor_with_dead_object_and_dump_threads_in_thread, NULL) != 0) die("pthread_create");
    +  if (pthread_join(attacher, &ret) != 0) die("pthread_join");
    +}
    +
    +#ifdef __cplusplus
    +}
    +#endif
    diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoTest.java b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoTest.java
    index 7d40301222c..7b99104670f 100644
    --- a/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoTest.java
    +++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoTest.java
    @@ -24,8 +24,10 @@
     
     /**
      * @test
    - * @bug 8185164
    - * @summary Checks that a contended monitor does not show up in the list of owned monitors
    + * @bug 8185164 8320515
    + * @summary Checks that a contended monitor does not show up in the list of owned monitors.
    + *          8320515 piggy-backs on this test and injects an owned monitor with a dead object,
    +            and checks that that monitor isn't exposed to GetOwnedMonitorInfo.
      * @requires vm.jvmti
      * @compile GetOwnedMonitorInfoTest.java
      * @run main/othervm/native -agentlib:GetOwnedMonitorInfoTest GetOwnedMonitorInfoTest
    @@ -46,19 +48,42 @@ public class GetOwnedMonitorInfoTest {
             }
         }
     
    +    private static native void jniMonitorEnter(Object obj);
         private static native int check();
         private static native boolean hasEventPosted();
     
    +    private static void jniMonitorEnterAndLetObjectDie() {
    +        // The monitor iterator used by GetOwnedMonitorInfo used to
    +        // assert when an owned monitor with a dead object was found.
    +        // Inject this situation into this test that performs other
    +        // GetOwnedMonitorInfo testing.
    +        Object obj = new Object() {};
    +        jniMonitorEnter(obj);
    +        if (!Thread.holdsLock(obj)) {
    +            throw new RuntimeException("The object is not locked");
    +        }
    +        obj = null;
    +        System.gc();
    +    }
    +
         public static void main(String[] args) throws Exception {
    -        runTest(true);
    -        runTest(false);
    +        runTest(true, true);
    +        runTest(true, false);
    +        runTest(false, true);
    +        runTest(false, false);
         }
     
    -    public static void runTest(boolean isVirtual) throws Exception {
    +    public static void runTest(boolean isVirtual, boolean jni) throws Exception {
             var threadFactory = isVirtual ? Thread.ofVirtual().factory() : Thread.ofPlatform().factory();
             final GetOwnedMonitorInfoTest lock = new GetOwnedMonitorInfoTest();
     
             Thread t1 = threadFactory.newThread(() -> {
    +            Thread.currentThread().setName("Worker-Thread");
    +
    +            if (jni) {
    +                jniMonitorEnterAndLetObjectDie();
    +            }
    +
                 synchronized (lock) {
                     System.out.println("Thread in sync section: "
                                        + Thread.currentThread().getName());
    diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/libGetOwnedMonitorInfoTest.c b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/libGetOwnedMonitorInfoTest.c
    index 5147fae5304..af4fd51f3b3 100644
    --- a/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/libGetOwnedMonitorInfoTest.c
    +++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/libGetOwnedMonitorInfoTest.c
    @@ -22,6 +22,7 @@
      */
     
     #include 
    +#include 
     #include 
     #include "jvmti.h"
     #include "jni.h"
    @@ -264,6 +265,14 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
         return JNI_OK;
     }
     
    +JNIEXPORT void JNICALL
    +Java_GetOwnedMonitorInfoTest_jniMonitorEnter(JNIEnv* env, jclass cls, jobject obj) {
    +    if ((*env)->MonitorEnter(env, obj) != 0) {
    +        fprintf(stderr, "MonitorEnter failed");
    +        exit(-1);
    +    }
    +}
    +
     JNIEXPORT jint JNICALL
     Java_GetOwnedMonitorInfoTest_check(JNIEnv *env, jclass cls) {
         return status;
    
    From 2de8cfaa2eb8eef614507d6b0e343cec83b9eebc Mon Sep 17 00:00:00 2001
    From: Long Yang 
    Date: Tue, 19 Mar 2024 08:35:23 +0000
    Subject: [PATCH 075/298] 8327799: JFR view: the "Park Until" field of
     jdk.ThreadPark is invalid if the parking method is not absolute
    
    Backport-of: 6f8b0a33fa15f1dfc8b0c116375df0f90d9d8759
    ---
     .../share/classes/jdk/jfr/internal/util/ValueFormatter.java    | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueFormatter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueFormatter.java
    index 8265a74fec4..d33ef36362d 100644
    --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueFormatter.java
    +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueFormatter.java
    @@ -272,6 +272,9 @@ private static List decodeDescriptors(String descriptor, String arraySiz
         }
     
         public static String formatTimestamp(Instant instant) {
    +        if (Instant.MIN.equals(instant)) {
    +            return "N/A";
    +        }
             return LocalTime.ofInstant(instant, ZoneId.systemDefault()).format(DATE_FORMAT);
         }
     }
    
    From 9e1840f9524675591aa8c61a654a6bd6c616fd6e Mon Sep 17 00:00:00 2001
    From: Aleksey Shipilev 
    Date: Tue, 19 Mar 2024 09:20:43 +0000
    Subject: [PATCH 076/298] 8325613: CTW: Stale method cleanup requires GC after
     Sweeper removal
    
    Backport-of: 1281e18f1447848d7eb5e3bde508ac002b4c390d
    ---
     .../src/sun/hotspot/tools/ctw/Compiler.java   | 23 ++++++++++++++++++-
     .../src/sun/hotspot/tools/ctw/CtwRunner.java  |  4 +++-
     2 files changed, 25 insertions(+), 2 deletions(-)
    
    diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java
    index 961090c1d40..7b495e46e33 100644
    --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java
    +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java
    @@ -41,9 +41,15 @@
      */
     public class Compiler {
     
    +    // Call GC after compiling as many methods. This would remove the stale methods.
    +    // This threshold should balance the GC overhead and the cost of keeping lots
    +    // of stale methods around.
    +    private static final long GC_METHOD_THRESHOLD = Long.getLong("gcMethodThreshold", 100);
    +
         private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
    -    private static final AtomicLong METHOD_COUNT = new AtomicLong(0L);
    +    private static final AtomicLong METHOD_COUNT = new AtomicLong();
    +    private static final AtomicLong METHODS_SINCE_LAST_GC = new AtomicLong();
     
         private Compiler() { }
     
    @@ -83,6 +89,21 @@ public static void compileClass(Class aClass, long id, Executor executor) {
                 executor.execute(new CompileMethodCommand(id, e));
             }
             METHOD_COUNT.addAndGet(methodCount);
    +
    +        // See if we need to schedule a GC
    +        while (true) {
    +            long current = METHODS_SINCE_LAST_GC.get();
    +            long update = current + methodCount;
    +            if (update >= GC_METHOD_THRESHOLD) {
    +                update = 0;
    +            }
    +            if (METHODS_SINCE_LAST_GC.compareAndSet(current, update)) {
    +                if (update == 0) {
    +                    executor.execute(() -> System.gc());
    +                }
    +                break;
    +            }
    +        }
         }
     
         private static void preloadClasses(String className, long id,
    diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java
    index 478b74c2741..5b08541bf0f 100644
    --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java
    +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java
    @@ -293,8 +293,10 @@ private String[] cmd(long classStart, long classStop) {
                     String.format("-XX:ReplayDataFile=replay_%s_%%p.log", phase),
                     // MethodHandle MUST NOT be compiled
                     "-XX:CompileCommand=exclude,java/lang/invoke/MethodHandle.*",
    -                // Stress* are c2-specific stress flags, so IgnoreUnrecognizedVMOptions is needed
                     "-XX:+IgnoreUnrecognizedVMOptions",
    +                // Do not pay extra zapping cost for explicit GC invocations
    +                "-XX:-ZapUnusedHeapArea",
    +                // Stress* are c2-specific stress flags, so IgnoreUnrecognizedVMOptions is needed
                     "-XX:+StressLCM",
                     "-XX:+StressGCM",
                     "-XX:+StressIGVN",
    
    From 06e4cf37df286ea0b3c61ff09889b5761f3fb9d7 Mon Sep 17 00:00:00 2001
    From: Oli Gillespie 
    Date: Tue, 19 Mar 2024 11:33:17 +0000
    Subject: [PATCH 077/298] 8315559: Delay TempSymbol cleanup to avoid symbol
     table churn 8321276:
     runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java failed with "'17
     2: jdk/test/lib/apps ' missing from stdout/stderr"
    
    Reviewed-by: coleenp
    Backport-of: d23f4f12adf1ea26b8c340efe2c3854e50b68301
    ---
     src/hotspot/share/oops/symbolHandle.cpp       | 47 ++++++++++++++
     src/hotspot/share/oops/symbolHandle.hpp       | 19 +++++-
     .../gtest/classfile/test_placeholders.cpp     | 11 +++-
     .../gtest/classfile/test_symbolTable.cpp      | 65 +++++++++++++++++--
     .../dynamicArchive/DynamicSharedSymbols.java  |  3 +-
     5 files changed, 135 insertions(+), 10 deletions(-)
     create mode 100644 src/hotspot/share/oops/symbolHandle.cpp
    
    diff --git a/src/hotspot/share/oops/symbolHandle.cpp b/src/hotspot/share/oops/symbolHandle.cpp
    new file mode 100644
    index 00000000000..350f0dd96c8
    --- /dev/null
    +++ b/src/hotspot/share/oops/symbolHandle.cpp
    @@ -0,0 +1,47 @@
    +/*
    + * Copyright Amazon.com Inc. 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.
    + */
    +
    +#include "precompiled.hpp"
    +#include "oops/symbolHandle.hpp"
    +#include "runtime/atomic.hpp"
    +
    +Symbol* volatile TempSymbolCleanupDelayer::_queue[QueueSize] = {};
    +volatile uint TempSymbolCleanupDelayer::_index = 0;
    +
    +// Keep this symbol alive for some time to allow for reuse.
    +// Temp symbols for the same string can often be created in quick succession,
    +// and this queue allows them to be reused instead of churning.
    +void TempSymbolCleanupDelayer::delay_cleanup(Symbol* sym) {
    +  assert(sym != nullptr, "precondition");
    +  sym->increment_refcount();
    +  uint i = Atomic::add(&_index, 1u) % QueueSize;
    +  Symbol* old = Atomic::xchg(&_queue[i], sym);
    +  Symbol::maybe_decrement_refcount(old);
    +}
    +
    +void TempSymbolCleanupDelayer::drain_queue() {
    +  for (uint i = 0; i < QueueSize; i++) {
    +    Symbol* sym = Atomic::xchg(&_queue[i], (Symbol*) nullptr);
    +    Symbol::maybe_decrement_refcount(sym);
    +  }
    +}
    diff --git a/src/hotspot/share/oops/symbolHandle.hpp b/src/hotspot/share/oops/symbolHandle.hpp
    index 249da936761..f1b2d2470c5 100644
    --- a/src/hotspot/share/oops/symbolHandle.hpp
    +++ b/src/hotspot/share/oops/symbolHandle.hpp
    @@ -28,6 +28,16 @@
     #include "memory/allocation.hpp"
     #include "oops/symbol.hpp"
     
    +class TempSymbolCleanupDelayer : AllStatic {
    +  static Symbol* volatile _queue[];
    +  static volatile uint _index;
    +
    +public:
    +  static const uint QueueSize = 128;
    +  static void delay_cleanup(Symbol* s);
    +  static void drain_queue();
    +};
    +
     // TempNewSymbol acts as a handle class in a handle/body idiom and is
     // responsible for proper resource management of the body (which is a Symbol*).
     // The body is resource managed by a reference counting scheme.
    @@ -49,10 +59,17 @@ class SymbolHandleBase : public StackObj {
       SymbolHandleBase() : _temp(nullptr) { }
     
       // Conversion from a Symbol* to a SymbolHandleBase.
    -  // Does not increment the current reference count if temporary.
       SymbolHandleBase(Symbol *s) : _temp(s) {
         if (!TEMP) {
           Symbol::maybe_increment_refcount(_temp);
    +      return;
    +    }
    +
    +    // Delay cleanup for temp symbols. Refcount is incremented while in
    +    // queue. But don't requeue existing entries, or entries that are held
    +    // elsewhere - it's a waste of effort.
    +    if (s != nullptr && s->refcount() == 1) {
    +      TempSymbolCleanupDelayer::delay_cleanup(s);
         }
       }
     
    diff --git a/test/hotspot/gtest/classfile/test_placeholders.cpp b/test/hotspot/gtest/classfile/test_placeholders.cpp
    index 9fa06d49f73..4179a1fc695 100644
    --- a/test/hotspot/gtest/classfile/test_placeholders.cpp
    +++ b/test/hotspot/gtest/classfile/test_placeholders.cpp
    @@ -39,10 +39,10 @@ TEST_VM(PlaceholderTable, supername) {
       ThreadInVMfromNative tivfn(THREAD);
     
       // Assert messages assume these symbols are unique, and the refcounts start at one.
    -  TempNewSymbol A = SymbolTable::new_symbol("abc2_8_2023_class");
    -  TempNewSymbol D = SymbolTable::new_symbol("def2_8_2023_class");
    +  Symbol* A = SymbolTable::new_symbol("abc2_8_2023_class");
    +  Symbol* D = SymbolTable::new_symbol("def2_8_2023_class");
       Symbol* super = SymbolTable::new_symbol("super2_8_2023_supername");
    -  TempNewSymbol interf = SymbolTable::new_symbol("interface2_8_2023_supername");
    +  Symbol* interf = SymbolTable::new_symbol("interface2_8_2023_supername");
     
       ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
     
    @@ -110,4 +110,9 @@ TEST_VM(PlaceholderTable, supername) {
       EXPECT_EQ(A->refcount(), 1) << "first lass name refcount should be 1";
       EXPECT_EQ(D->refcount(), 1) << "second class name refcount should be 1";
       EXPECT_EQ(super->refcount(), 0) << "super class name refcount should be 0 - was unloaded.";
    +
    +  // clean up temporary symbols
    +  A->decrement_refcount();
    +  D->decrement_refcount();
    +  interf->decrement_refcount();
     }
    diff --git a/test/hotspot/gtest/classfile/test_symbolTable.cpp b/test/hotspot/gtest/classfile/test_symbolTable.cpp
    index 4f4cbfe3e89..10f9560530e 100644
    --- a/test/hotspot/gtest/classfile/test_symbolTable.cpp
    +++ b/test/hotspot/gtest/classfile/test_symbolTable.cpp
    @@ -27,6 +27,14 @@
     #include "threadHelper.inline.hpp"
     #include "unittest.hpp"
     
    +// Helper to avoid interference from the cleanup delay queue by draining it
    +// immediately after creation.
    +TempNewSymbol stable_temp_symbol(Symbol* sym) {
    +  TempNewSymbol t = sym;
    +  TempSymbolCleanupDelayer::drain_queue();
    +  return t;
    +}
    +
     TEST_VM(SymbolTable, temp_new_symbol) {
       // Assert messages assume these symbols are unique, and the refcounts start at
       // one, but code does not rely on this.
    @@ -36,7 +44,7 @@ TEST_VM(SymbolTable, temp_new_symbol) {
     
       Symbol* abc = SymbolTable::new_symbol("abc");
       int abccount = abc->refcount();
    -  TempNewSymbol ss = abc;
    +  TempNewSymbol ss = stable_temp_symbol(abc);
       ASSERT_EQ(ss->refcount(), abccount) << "only one abc";
       ASSERT_EQ(ss->refcount(), abc->refcount()) << "should match TempNewSymbol";
     
    @@ -45,8 +53,8 @@ TEST_VM(SymbolTable, temp_new_symbol) {
       int efgcount = efg->refcount();
       int hijcount = hij->refcount();
     
    -  TempNewSymbol s1 = efg;
    -  TempNewSymbol s2 = hij;
    +  TempNewSymbol s1 = stable_temp_symbol(efg);
    +  TempNewSymbol s2 = stable_temp_symbol(hij);
       ASSERT_EQ(s1->refcount(), efgcount) << "one efg";
       ASSERT_EQ(s2->refcount(), hijcount) << "one hij";
     
    @@ -65,13 +73,13 @@ TEST_VM(SymbolTable, temp_new_symbol) {
       TempNewSymbol s3;
       Symbol* klm = SymbolTable::new_symbol("klm");
       int klmcount = klm->refcount();
    -  s3 = klm; // assignment
    +  s3 = stable_temp_symbol(klm); // assignment
       ASSERT_EQ(s3->refcount(), klmcount) << "only one klm now";
     
       Symbol* xyz = SymbolTable::new_symbol("xyz");
       int xyzcount = xyz->refcount();
       { // inner scope
    -    TempNewSymbol s_inner = xyz;
    +    TempNewSymbol s_inner = stable_temp_symbol(xyz);
       }
       ASSERT_EQ(xyz->refcount(), xyzcount - 1)
               << "Should have been decremented by dtor in inner scope";
    @@ -139,3 +147,50 @@ TEST_VM(SymbolTable, test_cleanup_leak) {
     
       ASSERT_EQ(entry2->refcount(), 1) << "Symbol refcount just created is 1";
     }
    +
    +TEST_VM(SymbolTable, test_cleanup_delay) {
    +  // Check that new temp symbols have an extra refcount increment, which is then
    +  // decremented when the queue spills over.
    +
    +  TempNewSymbol s1 = SymbolTable::new_symbol("temp-s1");
    +  ASSERT_EQ(s1->refcount(), 2) << "TempNewSymbol refcount just created is 2";
    +
    +  // Fill up the queue
    +  constexpr int symbol_name_length = 30;
    +  char symbol_name[symbol_name_length];
    +  for (uint i = 1; i < TempSymbolCleanupDelayer::QueueSize; i++) {
    +    os::snprintf(symbol_name, symbol_name_length, "temp-filler-%d", i);
    +    TempNewSymbol s = SymbolTable::new_symbol(symbol_name);
    +    ASSERT_EQ(s->refcount(), 2) << "TempNewSymbol refcount just created is 2";
    +  }
    +
    +  // Add one more
    +  TempNewSymbol spillover = SymbolTable::new_symbol("temp-spillover");
    +  ASSERT_EQ(spillover->refcount(), 2) << "TempNewSymbol refcount just created is 2";
    +
    +  // The first symbol should have been removed from the queue and decremented
    +  ASSERT_EQ(s1->refcount(), 1) << "TempNewSymbol off queue refcount is 1";
    +}
    +
    +TEST_VM(SymbolTable, test_cleanup_delay_drain) {
    +  // Fill up the queue
    +  constexpr int symbol_name_length = 30;
    +  char symbol_name[symbol_name_length];
    +  TempNewSymbol symbols[TempSymbolCleanupDelayer::QueueSize] = {};
    +  for (uint i = 0; i < TempSymbolCleanupDelayer::QueueSize; i++) {
    +    os::snprintf(symbol_name, symbol_name_length, "temp-%d", i);
    +    TempNewSymbol s = SymbolTable::new_symbol(symbol_name);
    +    symbols[i] = s;
    +  }
    +
    +  // While in the queue refcounts are incremented
    +  for (uint i = 0; i < TempSymbolCleanupDelayer::QueueSize; i++) {
    +    ASSERT_EQ(symbols[i]->refcount(), 2) << "TempNewSymbol refcount in queue is 2";
    +  }
    +
    +  // Draining the queue should decrement the refcounts
    +  TempSymbolCleanupDelayer::drain_queue();
    +  for (uint i = 0; i < TempSymbolCleanupDelayer::QueueSize; i++) {
    +    ASSERT_EQ(symbols[i]->refcount(), 1) << "TempNewSymbol refcount after drain is 1";
    +  }
    +}
    diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java
    index 24305c5a166..71dc2a3fac1 100644
    --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java
    +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java
    @@ -90,7 +90,8 @@ private static void doTest(String topArchiveName) throws Exception {
             ProcessBuilder pb = new ProcessBuilder();
             pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), Long.toString(pid), "VM.symboltable", "-verbose"});
             OutputAnalyzer output = CDSTestUtils.executeAndLog(pb, "jcmd-symboltable");
    -        output.shouldContain("17 2: jdk/test/lib/apps\n");
    +        output.shouldContain("17 3: jdk/test/lib/apps\n");  // 3 because a TempSymbol will be found in the TempSymbolCleanupDelayer queue.
    +                   // Note: we might want to drain the queue before CDS dumps but this is correct for now, unless the queue length changes.
             output.shouldContain("Dynamic shared symbols:\n");
             output.shouldContain("5 65535: Hello\n");
     
    
    From b3e81769c17344e90b9eeb97d5ded30b43d3d467 Mon Sep 17 00:00:00 2001
    From: Goetz Lindenmaier 
    Date: Tue, 19 Mar 2024 13:51:40 +0000
    Subject: [PATCH 078/298] 8309757: com/sun/jdi/ReferrersTest.java fails with
     virtual test thread factory
    
    Backport-of: d7251c1755779f8c4fdeac16ccb797ed45b1dfd4
    ---
     test/jdk/ProblemList-Virtual.txt        | 1 -
     test/jdk/com/sun/jdi/ReferrersTest.java | 5 ++++-
     2 files changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt
    index 186bd175f2f..d813a57e8f1 100644
    --- a/test/jdk/ProblemList-Virtual.txt
    +++ b/test/jdk/ProblemList-Virtual.txt
    @@ -29,7 +29,6 @@ com/sun/jdi/EATests.java#id0                                    8264699 generic-
     
     com/sun/jdi/ExceptionEvents.java 8278470 generic-all
     com/sun/jdi/RedefineCrossStart.java 8278470 generic-all
    -com/sun/jdi/ReferrersTest.java 8285422 generic-all
     com/sun/jdi/SetLocalWhileThreadInNative.java 8285422 generic-all
     com/sun/jdi/cds/CDSBreakpointTest.java 8307778 generic-all
     com/sun/jdi/cds/CDSDeleteAllBkptsTest.java 8307778 generic-all
    diff --git a/test/jdk/com/sun/jdi/ReferrersTest.java b/test/jdk/com/sun/jdi/ReferrersTest.java
    index 385292061b6..db483a1668e 100644
    --- a/test/jdk/com/sun/jdi/ReferrersTest.java
    +++ b/test/jdk/com/sun/jdi/ReferrersTest.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2023, 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
    @@ -454,6 +454,9 @@ void showReferrers(ObjectReference objRef, int level, int total, int which) {
                 if (name.equals("java.lang.ref.SoftReference")) {
                     return;
                 }
    +            if (name.equals("java.lang.reflect.Method")) {
    +                return;
    +            }
                 // oh oh, should really check for a subclass of ClassLoader :-)
                 if (name.indexOf("ClassLoader") >= 0) {
                     return;
    
    From dc6afd04f89302d24a67fc7178200153f20139f7 Mon Sep 17 00:00:00 2001
    From: Goetz Lindenmaier 
    Date: Tue, 19 Mar 2024 13:55:07 +0000
    Subject: [PATCH 079/298] 8312320: Remove
     javax/rmi/ssl/SSLSocketParametersTest.sh from ProblemList
    
    Backport-of: 8d29329138d44800ee4c0c02dacc01a06097de66
    ---
     test/jdk/ProblemList.txt | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
    index 1fd1d603fe9..4c794f552a7 100644
    --- a/test/jdk/ProblemList.txt
    +++ b/test/jdk/ProblemList.txt
    @@ -739,8 +739,6 @@ sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java              8313798 generic-
     
     # jdk_other
     
    -javax/rmi/ssl/SSLSocketParametersTest.sh                        8162906 generic-all
    -
     jdk/incubator/vector/ShortMaxVectorTests.java                   8306592 generic-i586
     jdk/incubator/vector/LoadJsvmlTest.java                         8305390 windows-x64
     
    
    From 81f621d83def0adbb70d48c0eb3aaa4a43adc531 Mon Sep 17 00:00:00 2001
    From: Goetz Lindenmaier 
    Date: Tue, 19 Mar 2024 13:56:13 +0000
    Subject: [PATCH 080/298] 8316696: Remove the testing base classes: IntlTest
     and CollatorTest
    
    Backport-of: b859da9c548fbd1463b336059d1c55312c7b7ba4
    ---
     .../text/BreakIterator/BreakIteratorTest.java | 196 +++---
     .../java/text/BreakIterator/Bug4533872.java   |  36 +-
     .../CharacterIteratorTest.java                |  86 +--
     test/jdk/java/text/Collator/APITest.java      | 102 +--
     test/jdk/java/text/Collator/Bug6271411.java   |  22 +-
     test/jdk/java/text/Collator/CollatorTest.java | 141 ----
     test/jdk/java/text/Collator/DanishTest.java   |  21 +-
     test/jdk/java/text/Collator/DummyTest.java    |  26 +-
     test/jdk/java/text/Collator/EnglishTest.java  |  24 +-
     test/jdk/java/text/Collator/FinnishTest.java  |  19 +-
     test/jdk/java/text/Collator/FrenchTest.java   |  18 +-
     test/jdk/java/text/Collator/G7Test.java       |  38 +-
     test/jdk/java/text/Collator/GermanTest.java   |  19 +-
     test/jdk/java/text/Collator/IteratorTest.java |  44 +-
     test/jdk/java/text/Collator/MonkeyTest.java   |  29 +-
     test/jdk/java/text/Collator/Regression.java   | 137 ++--
     test/jdk/java/text/Collator/SpanishTest.java  |  19 +-
     .../java/text/Collator/SurrogatesTest.java    |  21 +-
     test/jdk/java/text/Collator/Test4401726.java  |  18 +-
     test/jdk/java/text/Collator/ThaiTest.java     |  14 +-
     test/jdk/java/text/Collator/TurkishTest.java  |  19 +-
     .../java/text/Collator/VietnameseTest.java    |  19 +-
     .../Format/ChoiceFormat/Bug4185732Test.java   |  51 +-
     .../text/Format/DateFormat/Bug4322313.java    |  24 +-
     .../DateFormat/DateFormatRegression.java      | 280 ++++----
     .../DateFormat/DateFormatRoundTripTest.java   |  35 +-
     .../Format/DateFormat/DateFormatTest.java     | 292 ++++----
     .../Format/DateFormat/IntlTestDateFormat.java |  51 +-
     .../DateFormat/IntlTestDateFormatAPI.java     |  71 +-
     .../DateFormat/IntlTestDateFormatSymbols.java |  52 +-
     .../IntlTestSimpleDateFormatAPI.java          |  66 +-
     .../Format/DateFormat/TimeZoneNameTest.java   |  43 +-
     .../text/Format/DateFormat/bug4358730.java    |  17 +-
     .../Format/MessageFormat/Bug4185816Test.java  |  56 +-
     .../MessageFormat/MessageRegression.java      | 265 +++----
     .../Format/MessageFormat/MessageTest.java     |  25 +-
     .../text/Format/MessageFormat/bug4492719.java |  26 +-
     .../Format/NumberFormat/BigDecimalFormat.java |  21 +-
     .../Format/NumberFormat/BigDecimalParse.java  |  88 ++-
     .../text/Format/NumberFormat/Bug4838107.java  |  11 +-
     .../Format/NumberFormat/DFSExponential.java   |  30 +-
     .../Format/NumberFormat/DFSSerialization.java |  35 +-
     .../IntlTestDecimalFormatAPI.java             |  93 +--
     .../IntlTestDecimalFormatSymbols.java         |  43 +-
     .../NumberFormat/IntlTestNumberFormatAPI.java |  71 +-
     .../Format/NumberFormat/NumberRegression.java | 514 ++++++++------
     .../Format/NumberFormat/NumberRoundTrip.java  |  52 +-
     .../text/Format/NumberFormat/NumberTest.java  | 129 ++--
     .../Format/NumberFormat/PositionTest.java     |  82 ++-
     .../Format/common/FormatIteratorTest.java     |  96 ++-
     .../java/text/Normalizer/ICUBasicTest.java    |  72 +-
     .../text/Normalizer/NormalizerAPITest.java    |  48 +-
     test/jdk/java/text/testlib/HexDumpReader.java |  11 +-
     test/jdk/java/text/testlib/IntlTest.java      | 262 -------
     test/jdk/java/text/testlib/TestUtils.java     | 132 +++-
     .../java/util/Calendar/CalendarLimitTest.java |  44 +-
     .../util/Calendar/CalendarRegression.java     | 655 ++++++++++--------
     test/jdk/java/util/Calendar/CalendarTest.java | 242 ++++---
     .../java/util/Calendar/FieldStateTest.java    |  83 ++-
     .../util/Calendar/GregorianCutoverTest.java   | 148 ++--
     test/jdk/java/util/Calendar/JulianTest.java   |  15 +-
     .../java/util/Calendar/NonLenientTest.java    |  43 +-
     test/jdk/java/util/Calendar/bug4243802.java   |  11 +-
     test/jdk/java/util/Calendar/bug4316678.java   |   4 +-
     test/jdk/java/util/Calendar/bug4372743.java   |   5 +-
     test/jdk/java/util/Calendar/bug4409072.java   |  43 +-
     test/jdk/java/util/Date/DateRegression.java   |  79 ++-
     test/jdk/java/util/Date/DateTest.java         |  62 +-
     test/jdk/java/util/Date/TimestampTest.java    |  23 +-
     .../Locale/LegacyCodesClassInvariant.java     |  66 +-
     .../java/util/Locale/LocaleEnhanceTest.java   |  86 ++-
     test/jdk/java/util/Locale/LocaleTest.java     | 230 +++---
     test/jdk/java/util/TimeZone/Bug4322313.java   |  29 +-
     test/jdk/java/util/TimeZone/Bug6329116.java   |  25 +-
     .../util/TimeZone/TimeZoneBoundaryTest.java   | 223 +++---
     .../util/TimeZone/TimeZoneRegression.java     | 182 ++---
     test/jdk/java/util/TimeZone/TimeZoneTest.java | 161 +++--
     .../java/util/TimeZone/TransitionTest.java    |  28 +-
     .../sun/util/resources/TimeZone/IntlTest.java | 228 ------
     79 files changed, 3384 insertions(+), 3543 deletions(-)
     delete mode 100644 test/jdk/java/text/Collator/CollatorTest.java
     delete mode 100644 test/jdk/java/text/testlib/IntlTest.java
     delete mode 100644 test/jdk/sun/util/resources/TimeZone/IntlTest.java
    
    diff --git a/test/jdk/java/text/BreakIterator/BreakIteratorTest.java b/test/jdk/java/text/BreakIterator/BreakIteratorTest.java
    index 5a29ca86751..a31c1d338d2 100644
    --- a/test/jdk/java/text/BreakIterator/BreakIteratorTest.java
    +++ b/test/jdk/java/text/BreakIterator/BreakIteratorTest.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1996, 2023, 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
    @@ -27,8 +27,7 @@
      *      4097920 4098467 4111338 4113835 4117554 4143071 4146175 4152117
      *      4152416 4153072 4158381 4214367 4217703 4638433 8264765 8291660
      *      8294008
    - * @library /java/text/testlib
    - * @run main/timeout=2000 BreakIteratorTest
    + * @run junit/timeout=2000 BreakIteratorTest
      * @summary test BreakIterator
      */
     
    @@ -78,24 +77,16 @@
     import java.util.function.Predicate;
     import java.util.regex.Pattern;
     
    -public class BreakIteratorTest extends IntlTest
    -{
    -    private BreakIterator characterBreak;
    -    private BreakIterator wordBreak;
    -    private BreakIterator lineBreak;
    -    private BreakIterator sentenceBreak;
    +import org.junit.jupiter.api.Test;
     
    -    public static void main(String[] args) throws Exception {
    -        new BreakIteratorTest().run(args);
    -    }
    +import static org.junit.jupiter.api.Assertions.fail;
    +
    +public class BreakIteratorTest {
    +    private final BreakIterator characterBreak = BreakIterator.getCharacterInstance();
    +    private final BreakIterator wordBreak = BreakIterator.getWordInstance();
    +    private final BreakIterator lineBreak = BreakIterator.getLineInstance();
    +    private final BreakIterator sentenceBreak = BreakIterator.getSentenceInstance();
     
    -    public BreakIteratorTest()
    -    {
    -        characterBreak = BreakIterator.getCharacterInstance();
    -        wordBreak = BreakIterator.getWordInstance();
    -        lineBreak = BreakIterator.getLineInstance();
    -        sentenceBreak = BreakIterator.getSentenceInstance();
    -    }
     
         //=========================================================================
         // general test subroutines
    @@ -115,15 +106,12 @@ private void generalIteratorTest(BreakIterator bi, Vector expectedResult) {
             Vector nextResults = testFirstAndNext(bi, text);
             Vector previousResults = testLastAndPrevious(bi, text);
     
    -        logln("comparing forward and backward...");
    -        int errs = getErrorCount();
    +        System.out.println("comparing forward and backward...");
             compareFragmentLists("forward iteration", "backward iteration", nextResults,
                             previousResults);
    -        if (getErrorCount() == errs) {
    -            logln("comparing expected and actual...");
    -            compareFragmentLists("expected result", "actual result", expectedResult,
    -                            nextResults);
    -        }
    +        System.out.println("comparing expected and actual...");
    +        compareFragmentLists("expected result", "actual result", expectedResult,
    +                        nextResults);
     
             int[] boundaries = new int[expectedResult.size() + 3];
             boundaries[0] = BreakIterator.DONE;
    @@ -146,19 +134,19 @@ private Vector testFirstAndNext(BreakIterator bi, String text) {
             Vector result = new Vector();
     
             if (p != 0)
    -            errln("first() returned " + p + " instead of 0");
    +            fail("first() returned " + p + " instead of 0");
             while (p != BreakIterator.DONE) {
                 p = bi.next();
                 if (p != BreakIterator.DONE) {
                     if (p <= lastP)
    -                    errln("next() failed to move forward: next() on position "
    +                    fail("next() failed to move forward: next() on position "
                                         + lastP + " yielded " + p);
     
                     result.addElement(text.substring(lastP, p));
                 }
                 else {
                     if (lastP != text.length())
    -                    errln("next() returned DONE prematurely: offset was "
    +                    fail("next() returned DONE prematurely: offset was "
                                         + lastP + " instead of " + text.length());
                 }
                 lastP = p;
    @@ -172,19 +160,19 @@ private Vector testLastAndPrevious(BreakIterator bi, String text) {
             Vector result = new Vector();
     
             if (p != text.length())
    -            errln("last() returned " + p + " instead of " + text.length());
    +            fail("last() returned " + p + " instead of " + text.length());
             while (p != BreakIterator.DONE) {
                 p = bi.previous();
                 if (p != BreakIterator.DONE) {
                     if (p >= lastP)
    -                    errln("previous() failed to move backward: previous() on position "
    +                    fail("previous() failed to move backward: previous() on position "
                                         + lastP + " yielded " + p);
     
                     result.insertElementAt(text.substring(p, lastP), 0);
                 }
                 else {
                     if (lastP != 0)
    -                    errln("previous() returned DONE prematurely: offset was "
    +                    fail("previous() returned DONE prematurely: offset was "
                                         + lastP + " instead of 0");
                 }
                 lastP = p;
    @@ -227,27 +215,28 @@ private void compareFragmentLists(String f1Name, String f2Name, Vector f1, Vecto
                             ++tempP2;
                         }
                     }
    -                logln("*** " + f1Name + " has:");
    +                System.out.println("*** " + f1Name + " has:");
                     while (p1 <= tempP1 && p1 < f1.size()) {
                         s1 = (String)f1.elementAt(p1);
                         t1 += s1.length();
                         debugLogln(" *** >" + s1 + "<");
                         ++p1;
                     }
    -                logln("***** " + f2Name + " has:");
    +                System.out.println("***** " + f2Name + " has:");
                     while (p2 <= tempP2 && p2 < f2.size()) {
                         s2 = (String)f2.elementAt(p2);
                         t2 += s2.length();
                         debugLogln(" ***** >" + s2 + "<");
                         ++p2;
                     }
    -                errln("Discrepancy between " + f1Name + " and " + f2Name + "\n---\n" + f1 +"\n---\n" + f2);
    +                fail("Discrepancy between " + f1Name + " and " + f2Name
    +                        + "\n---\n" + f1 +"\n---\n" + f2);
                 }
             }
         }
     
         private void testFollowing(BreakIterator bi, String text, int[] boundaries) {
    -        logln("testFollowing():");
    +        System.out.println("testFollowing():");
             int p = 2;
             int i = 0;
             try {
    @@ -256,59 +245,59 @@ private void testFollowing(BreakIterator bi, String text, int[] boundaries) {
                         ++p;
     
                     int b = bi.following(i);
    -                logln("bi.following(" + i + ") -> " + b);
    +                System.out.println("bi.following(" + i + ") -> " + b);
                     if (b != boundaries[p])
    -                    errln("Wrong result from following() for " + i + ": expected " + boundaries[p]
    +                    fail("Wrong result from following() for " + i + ": expected " + boundaries[p]
                               + ", got " + b);
                 }
             } catch (IllegalArgumentException illargExp) {
    -            errln("IllegalArgumentException caught from following() for offset: " + i);
    +            fail("IllegalArgumentException caught from following() for offset: " + i);
             }
         }
     
         private void testPreceding(BreakIterator bi, String text, int[] boundaries) {
    -        logln("testPreceding():");
    +        System.out.println("testPreceding():");
             int p = 0;
             int i = 0;
             try {
                 for (i = 0; i <= text.length(); i++) {  // change to <= when new BI code goes in
                     int b = bi.preceding(i);
    -                logln("bi.preceding(" + i + ") -> " + b);
    +                System.out.println("bi.preceding(" + i + ") -> " + b);
                     if (b != boundaries[p])
    -                    errln("Wrong result from preceding() for " + i + ": expected " + boundaries[p]
    +                    fail("Wrong result from preceding() for " + i + ": expected " + boundaries[p]
                               + ", got " + b);
     
                     if (i == boundaries[p + 1])
                         ++p;
                 }
             } catch (IllegalArgumentException illargExp) {
    -            errln("IllegalArgumentException caught from preceding() for offset: " + i);
    +            fail("IllegalArgumentException caught from preceding() for offset: " + i);
             }
         }
     
         private void testIsBoundary(BreakIterator bi, String text, int[] boundaries) {
    -        logln("testIsBoundary():");
    +        System.out.println("testIsBoundary():");
             int p = 1;
             boolean isB;
             for (int i = 0; i <= text.length(); i++) {  // change to <= when new BI code goes in
                 isB = bi.isBoundary(i);
    -            logln("bi.isBoundary(" + i + ") -> " + isB);
    +            System.out.println("bi.isBoundary(" + i + ") -> " + isB);
     
                 if (i == boundaries[p]) {
                     if (!isB)
    -                    errln("Wrong result from isBoundary() for " + i + ": expected true, got false");
    +                    fail("Wrong result from isBoundary() for " + i + ": expected true, got false");
                     ++p;
                 }
                 else {
                     if (isB)
    -                    errln("Wrong result from isBoundary() for " + i + ": expected false, got true");
    +                    fail("Wrong result from isBoundary() for " + i + ": expected false, got true");
                 }
             }
         }
     
         private void doMultipleSelectionTest(BreakIterator iterator, String testText)
         {
    -        logln("Multiple selection test...");
    +        System.out.println("Multiple selection test...");
             BreakIterator testIterator = (BreakIterator)iterator.clone();
             int offset = iterator.first();
             int testOffset;
    @@ -317,9 +306,9 @@ private void doMultipleSelectionTest(BreakIterator iterator, String testText)
             do {
                 testOffset = testIterator.first();
                 testOffset = testIterator.next(count);
    -            logln("next(" + count + ") -> " + testOffset);
    +            System.out.println("next(" + count + ") -> " + testOffset);
                 if (offset != testOffset)
    -                errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
    +                fail("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
     
                 if (offset != BreakIterator.DONE) {
                     count++;
    @@ -334,9 +323,9 @@ private void doMultipleSelectionTest(BreakIterator iterator, String testText)
             do {
                 testOffset = testIterator.last();
                 testOffset = testIterator.next(count);
    -            logln("next(" + count + ") -> " + testOffset);
    +            System.out.println("next(" + count + ") -> " + testOffset);
                 if (offset != testOffset)
    -                errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
    +                fail("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
     
                 if (offset != BreakIterator.DONE) {
                     count--;
    @@ -382,7 +371,7 @@ private void doBreakInvariantTest(BreakIterator tb, String testChars)
                                 seen2 = true;
                         }
                         if (!seen2) {
    -                        errln("No break between U+" + Integer.toHexString((int)(work.charAt(1)))
    +                        fail("No break between U+" + Integer.toHexString((int)(work.charAt(1)))
                                         + " and U+" + Integer.toHexString((int)(work.charAt(2))));
                             errorCount++;
                             if (errorCount >= 75)
    @@ -406,7 +395,7 @@ private void doOtherInvariantTest(BreakIterator tb, String testChars)
                     tb.setText(work.toString());
                     for (int k = tb.first(); k != BreakIterator.DONE; k = tb.next())
                         if (k == 2) {
    -                        errln("Break between CR and LF in string U+" + Integer.toHexString(
    +                        fail("Break between CR and LF in string U+" + Integer.toHexString(
                                     (int)(work.charAt(0))) + ", U+d U+a U+" + Integer.toHexString(
                                     (int)(work.charAt(3))));
                             errorCount++;
    @@ -444,7 +433,7 @@ private void doOtherInvariantTest(BreakIterator tb, String testChars)
                     tb.setText(work.toString());
                     for (int k = tb.first(); k != BreakIterator.DONE; k = tb.next())
                         if (k == 2) {
    -                        errln("Break between U+" + Integer.toHexString((int)(work.charAt(1)))
    +                        fail("Break between U+" + Integer.toHexString((int)(work.charAt(1)))
                                     + " and U+" + Integer.toHexString((int)(work.charAt(2))));
                             errorCount++;
                             if (errorCount >= 75)
    @@ -469,13 +458,14 @@ public void debugLogln(String s) {
                     out.append(temp);
                 }
             }
    -        logln(out.toString());
    +        System.out.println(out.toString());
         }
     
         //=========================================================================
         // tests
         //=========================================================================
     
    +    @Test
         public void TestWordBreak() {
     
             Vector wordSelectionData = new Vector();
    @@ -559,6 +549,7 @@ public void TestWordBreak() {
             generalIteratorTest(wordBreak, wordSelectionData);
         }
     
    +    @Test
         public void TestBug4097779() {
             Vector wordSelectionData = new Vector();
     
    @@ -568,6 +559,7 @@ public void TestBug4097779() {
             generalIteratorTest(wordBreak, wordSelectionData);
         }
     
    +    @Test
         public void TestBug4098467Words() {
             Vector wordSelectionData = new Vector();
     
    @@ -597,6 +589,7 @@ public void TestBug4098467Words() {
             generalIteratorTest(wordBreak, wordSelectionData);
         }
     
    +    @Test
         public void TestBug4117554Words() {
             Vector wordSelectionData = new Vector();
     
    @@ -609,6 +602,7 @@ public void TestBug4117554Words() {
             generalIteratorTest(wordBreak, wordSelectionData);
         }
     
    +    @Test
         public void TestSentenceBreak() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -644,6 +638,7 @@ public void TestSentenceBreak() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4113835() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -653,6 +648,7 @@ public void TestBug4113835() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4111338() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -672,6 +668,7 @@ public void TestBug4111338() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4117554Sentences() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -694,6 +691,7 @@ public void TestBug4117554Sentences() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4158381() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -711,6 +709,7 @@ public void TestBug4158381() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4143071() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -722,6 +721,7 @@ public void TestBug4143071() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4152416() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -734,6 +734,7 @@ public void TestBug4152416() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4152117() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -752,6 +753,7 @@ public void TestBug4152117() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug8264765() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -763,6 +765,7 @@ public void TestBug8264765() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestLineBreak() {
             Vector lineSelectionData = new Vector();
     
    @@ -799,6 +802,7 @@ public void TestLineBreak() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4068133() {
             Vector lineSelectionData = new Vector();
     
    @@ -815,6 +819,7 @@ public void TestBug4068133() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4086052() {
             Vector lineSelectionData = new Vector();
     
    @@ -824,6 +829,7 @@ public void TestBug4086052() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4097920() {
             Vector lineSelectionData = new Vector();
     
    @@ -836,6 +842,7 @@ public void TestBug4097920() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
         /*
    +    @Test
         public void TestBug4035266() {
             Vector lineSelectionData = new Vector();
     
    @@ -849,6 +856,7 @@ public void TestBug4035266() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
         */
    +    @Test
         public void TestBug4098467Lines() {
             Vector lineSelectionData = new Vector();
     
    @@ -874,13 +882,14 @@ public void TestBug4098467Lines() {
             lineSelectionData.addElement("\u110c\u1161\u11bc\u1105\u1169\u1100\u116d\u1112\u116c");
     
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4117554Lines() {
             Vector lineSelectionData = new Vector();
     
    @@ -892,9 +901,10 @@ public void TestBug4117554Lines() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4217703() {
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
    @@ -921,6 +931,7 @@ public void TestBug4217703() {
         private static final String circumflexA = "a\u0302";
         private static final String tildeE = "e\u0303";
     
    +    @Test
         public void TestCharacterBreak() {
             Vector characterSelectionData = new Vector();
     
    @@ -952,6 +963,7 @@ public void TestCharacterBreak() {
             generalIteratorTest(characterBreak, characterSelectionData);
         }
     
    +    @Test
         public void TestBug4098467Characters() {
             Vector characterSelectionData = new Vector();
     
    @@ -992,6 +1004,7 @@ public void TestBug4098467Characters() {
             generalIteratorTest(characterBreak, characterSelectionData);
         }
     
    +    @Test
         public void TestBug4153072() {
             BreakIterator iter = BreakIterator.getWordInstance();
             String str = "...Hello, World!...";
    @@ -1005,17 +1018,18 @@ public void TestBug4153072() {
                 try {
                     dummy = iter.isBoundary(index);
                     if (index < begin)
    -                    errln("Didn't get exception with offset = " + index +
    +                    fail("Didn't get exception with offset = " + index +
                                         " and begin index = " + begin);
                 }
                 catch (IllegalArgumentException e) {
                     if (index >= begin)
    -                    errln("Got exception with offset = " + index +
    +                    fail("Got exception with offset = " + index +
                                         " and begin index = " + begin);
                 }
             }
         }
     
    +    @Test
         public void TestBug4146175Sentences() {
             Vector sentenceSelectionData = new Vector();
     
    @@ -1031,9 +1045,10 @@ public void TestBug4146175Sentences() {
             generalIteratorTest(sentenceBreak, sentenceSelectionData);
         }
     
    +    @Test
         public void TestBug4146175Lines() {
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
    @@ -1046,9 +1061,10 @@ public void TestBug4146175Lines() {
             generalIteratorTest(lineBreak, lineSelectionData);
         }
     
    +    @Test
         public void TestBug4214367() {
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
    @@ -1070,16 +1086,18 @@ public void TestBug4214367() {
             + "\u2001\u2002\u200c\u200d\u200e\u200f\u2010\u2011\u2012\u2028\u2029\u202a\u203e\u203f"
             + "\u2040\u20dd\u20de\u20df\u20e0\u2160\u2161\u2162\u2163\u2164";
     
    +    @Test
         public void TestSentenceInvariants()
         {
             BreakIterator e = BreakIterator.getSentenceInstance();
             doOtherInvariantTest(e, cannedTestChars + ".,\u3001\u3002\u3041\u3042\u3043\ufeff");
         }
     
    +    @Test
         public void TestWordInvariants()
         {
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
    @@ -1090,10 +1108,11 @@ public void TestWordInvariants()
                 + "\u30a3\u4e00\u4e01\u4e02");
         }
     
    +    @Test
         public void TestLineInvariants()
         {
             if (Locale.getDefault().getLanguage().equals("th")) {
    -            logln("This test is skipped in th locale.");
    +            System.out.println("This test is skipped in th locale.");
                 return;
             }
     
    @@ -1142,7 +1161,7 @@ public void TestLineInvariants()
                                                                      work.charAt(l) == '\ufeff')) {
                                     continue;
                                 }
    -                            errln("Got break between U+" + Integer.toHexString((int)
    +                            fail("Got break between U+" + Integer.toHexString((int)
                                         (work.charAt(l - 1))) + " and U+" + Integer.toHexString(
                                         (int)(work.charAt(l))));
                                 errorCount++;
    @@ -1195,7 +1214,7 @@ public void TestLineInvariants()
                             if (l == 2)
                                 saw2 = true;
                         if (!saw2) {
    -                        errln("Didn't get break between U+" + Integer.toHexString((int)
    +                        fail("Didn't get break between U+" + Integer.toHexString((int)
                                         (work.charAt(1))) + " and U+" + Integer.toHexString(
                                         (int)(work.charAt(2))));
                             errorCount++;
    @@ -1208,6 +1227,7 @@ public void TestLineInvariants()
             */
         }
     
    +    @Test
         public void TestCharacterInvariants()
         {
             BreakIterator e = BreakIterator.getCharacterInstance();
    @@ -1217,6 +1237,7 @@ public void TestCharacterInvariants()
                 + "\u11a9\u11aa");
         }
     
    +    @Test
         public void TestEmptyString()
         {
             String text = "";
    @@ -1226,12 +1247,13 @@ public void TestEmptyString()
             generalIteratorTest(lineBreak, x);
         }
     
    +    @Test
         public void TestGetAvailableLocales()
         {
             Locale[] locList = BreakIterator.getAvailableLocales();
     
             if (locList.length == 0)
    -            errln("getAvailableLocales() returned an empty list!");
    +            fail("getAvailableLocales() returned an empty list!");
             // I have no idea how to test this function...
         }
     
    @@ -1239,6 +1261,7 @@ public void TestGetAvailableLocales()
         /**
          * Bug 4095322
          */
    +    @Test
         public void TestJapaneseLineBreak()
         {
             StringBuffer testString = new StringBuffer("\u4e00x\u4e8c");
    @@ -1287,18 +1310,18 @@ public void TestJapaneseLineBreak()
                 iter.setText(testString.toString());
                 int j = iter.first();
                 if (j != 0) {
    -                errln("ja line break failure: failed to start at 0 and bounced at " + j);
    +                fail("ja line break failure: failed to start at 0 and bounced at " + j);
                 }
                 j = iter.next();
                 if (j != 1) {
    -                errln("ja line break failure: failed to stop before '"
    +                fail("ja line break failure: failed to stop before '"
                             + precedingChars.charAt(i) + "' (\\u"
                             + Integer.toString(precedingChars.charAt(i), 16)
                             + ") at 1 and bounded at " + j);
                 }
                 j = iter.next();
                 if (j != 3) {
    -                errln("ja line break failure: failed to skip position after '"
    +                fail("ja line break failure: failed to skip position after '"
                             + precedingChars.charAt(i) + "' (\\u"
                             + Integer.toString(precedingChars.charAt(i), 16)
                             + ") at 3 and bounded at " + j);
    @@ -1310,18 +1333,18 @@ public void TestJapaneseLineBreak()
                 iter.setText(testString.toString());
                 int j = iter.first();
                 if (j != 0) {
    -                errln("ja line break failure: failed to start at 0 and bounded at " + j);
    +                fail("ja line break failure: failed to start at 0 and bounded at " + j);
                 }
                 j = iter.next();
                 if (j != 2) {
    -                errln("ja line break failure: failed to skip position before '"
    +                fail("ja line break failure: failed to skip position before '"
                             + followingChars.charAt(i) + "' (\\u"
                             + Integer.toString(followingChars.charAt(i), 16)
                             + ") at 2 and bounded at " + j);
                 }
                 j = iter.next();
                 if (j != 3) {
    -                errln("ja line break failure: failed to stop after '"
    +                fail("ja line break failure: failed to stop after '"
                             + followingChars.charAt(i) + "' (\\u"
                             + Integer.toString(followingChars.charAt(i), 16)
                             + ") at 3 and bounded at " + j);
    @@ -1332,6 +1355,7 @@ public void TestJapaneseLineBreak()
         /**
          * Bug 4638433
          */
    +    @Test
         public void TestLineBreakBasedOnUnicode3_0_0()
         {
             BreakIterator iter;
    @@ -1345,7 +1369,7 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 5) {
    -            errln("Word break failure: failed to stop at 5 and bounded at " + i);
    +            fail("Word break failure: failed to stop at 5 and bounded at " + i);
             }
     
     
    @@ -1358,7 +1382,7 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 3) {
    -            errln("Line break failure: failed to skip before \\u301F(Pe) at 3 and bounded at " + i);
    +            fail("Line break failure: failed to skip before \\u301F(Pe) at 3 and bounded at " + i);
             }
     
             /* Mongolian 
    @@ -1368,7 +1392,7 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 2) {
    -            errln("Mongolian line break failure: failed to skip position before \\u1806(Pd) at 2 and bounded at " + i);
    +            fail("Mongolian line break failure: failed to skip position before \\u1806(Pd) at 2 and bounded at " + i);
             }
     
             /* Khmer  which have
    @@ -1378,11 +1402,11 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 1) {
    -            errln("Khmer line break failure: failed to stop before \\u17DB(Sc) at 1 and bounded at " + i);
    +            fail("Khmer line break failure: failed to stop before \\u17DB(Sc) at 1 and bounded at " + i);
             }
             i = iter.next();
             if (i != 3) {
    -            errln("Khmer line break failure: failed to skip position after \\u17DB(Sc) at 3 and bounded at " + i);
    +            fail("Khmer line break failure: failed to skip position after \\u17DB(Sc) at 3 and bounded at " + i);
             }
     
             /* Ogham  which have
    @@ -1392,7 +1416,7 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 2) {
    -            errln("Ogham line break failure: failed to skip postion before \\u1680(Zs) at 2 and bounded at " + i);
    +            fail("Ogham line break failure: failed to skip postion before \\u1680(Zs) at 2 and bounded at " + i);
             }
     
     
    @@ -1409,17 +1433,18 @@ public void TestLineBreakBasedOnUnicode3_0_0()
             i = iter.first();
             i = iter.next();
             if (i != 1) {
    -            errln("Thai line break failure: failed to stop before \\u201C(Pi) at 1 and bounded at " + i);
    +            fail("Thai line break failure: failed to stop before \\u201C(Pi) at 1 and bounded at " + i);
             }
             i = iter.next();
             if (i != 4) {
    -            errln("Thai line break failure: failed to stop after \\u201D(Pf) at 4 and bounded at " + i);
    +            fail("Thai line break failure: failed to stop after \\u201D(Pf) at 4 and bounded at " + i);
             }
         }
     
         /**
          * Bug 4068137
          */
    +    @Test
         public void TestEndBehavior()
         {
             String testString = "boo.";
    @@ -1427,11 +1452,11 @@ public void TestEndBehavior()
             wb.setText(testString);
     
             if (wb.first() != 0)
    -            errln("Didn't get break at beginning of string.");
    +            fail("Didn't get break at beginning of string.");
             if (wb.next() != 3)
    -            errln("Didn't get break before period in \"boo.\"");
    +            fail("Didn't get break before period in \"boo.\"");
             if (wb.current() != 4 && wb.next() != 4)
    -            errln("Didn't get break at end of string.");
    +            fail("Didn't get break at end of string.");
         }
     
         // [serialization test has been removed pursuant to bug #4152965]
    @@ -1439,6 +1464,7 @@ public void TestEndBehavior()
         /**
          * Bug 4450804
          */
    +    @Test
         public void TestLineBreakContractions() {
             Vector expected = new Vector();
     
    @@ -1453,6 +1479,7 @@ public void TestLineBreakContractions() {
         }
     
         private static final Pattern CODEPOINT = Pattern.compile("([0-9A-F]{4,5})");
    +    @Test
         public void TestGraphemeBreak() throws Exception {
             Files.lines(Paths.get(System.getProperty("test.root"),
                     "../../src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakTest.txt"))
    @@ -1470,6 +1497,7 @@ public void TestGraphemeBreak() throws Exception {
                     });
         }
     
    +    @Test
         public void TestSetTextIOOBException() {
             BreakIterator.getCharacterInstance().setText(new StringCharacterIterator("abcfefg", 1, 5, 3));
         }
    diff --git a/test/jdk/java/text/BreakIterator/Bug4533872.java b/test/jdk/java/text/BreakIterator/Bug4533872.java
    index 64a4ccf569e..b6a6f16340c 100644
    --- a/test/jdk/java/text/BreakIterator/Bug4533872.java
    +++ b/test/jdk/java/text/BreakIterator/Bug4533872.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 2023, 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
    @@ -24,18 +24,18 @@
     /**
      * @test
      * @bug 4533872 4640853
    - * @library /java/text/testlib
      * @summary Unit tests for supplementary character support (JSR-204) and Unicode 4.0 support
    + * @run junit Bug4533872
      */
     
     import java.text.BreakIterator;
     import java.util.Locale;
     
    -public class Bug4533872 extends IntlTest {
    +import org.junit.jupiter.api.Test;
     
    -    public static void main(String[] args) throws Exception {
    -        new Bug4533872().run(args);
    -    }
    +import static org.junit.jupiter.api.Assertions.fail;
    +
    +public class Bug4533872 {
     
         static final String[] given = {
           /* Lu Nd    Lu     Ll    */
    @@ -73,7 +73,7 @@ void TestNext() {
                 end = iter.next();
     
                 if (!expected[i][j].equals(given[i].substring(start, end))) {
    -                errln("Word break failure: printEachForward() expected:<" +
    +                fail("Word break failure: printEachForward() expected:<" +
                           expected[i][j] + ">, got:<" +
                           given[i].substring(start, end) +
                           "> start=" + start + "  end=" + end);
    @@ -95,7 +95,7 @@ void TestIsBoundary() {
     
                 while (end < given[i].length()) {
                     if (!iter.isBoundary(end)) {
    -                    errln("Word break failure: isBoundary() This should be a boundary. Index=" +
    +                    fail("Word break failure: isBoundary() This should be a boundary. Index=" +
                               end + " for " + given[i]);
                     }
                     end = iter.next();
    @@ -122,7 +122,7 @@ void TestPrintEachForward() {
                 // Check current()'s return value - should be same as first()'s.
                 current = iter.current();
                 if (start != current) {
    -                errln("Word break failure: printEachForward() Unexpected current value: current()=" +
    +                fail("Word break failure: printEachForward() Unexpected current value: current()=" +
                           current + ", expected(=first())=" + start);
                 }
     
    @@ -134,12 +134,12 @@ void TestPrintEachForward() {
                     // Check current()'s return value - should be same as next()'s.
                     current = iter.current();
                     if (end != current) {
    -                    errln("Word break failure: printEachForward() Unexpected current value: current()=" +
    +                    fail("Word break failure: printEachForward() Unexpected current value: current()=" +
                               current + ", expected(=next())=" + end);
                     }
     
                     if (!expected[i][j].equals(given[i].substring(start, end))) {
    -                    errln("Word break failure: printEachForward() expected:<" +
    +                    fail("Word break failure: printEachForward() expected:<" +
                               expected[i][j] + ">, got:<" +
                               given[i].substring(start, end) +
                               "> start=" + start + "  end=" + end);
    @@ -161,7 +161,7 @@ void TestPrintEachBackward() {
                 // Check current()'s return value - should be same as last()'s.
                 current = iter.current();
                 if (end != current) {
    -                errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
    +                fail("Word break failure: printEachBackward() Unexpected current value: current()=" +
                           current + ", expected(=last())=" + end);
                 }
     
    @@ -173,12 +173,12 @@ void TestPrintEachBackward() {
                     // Check current()'s return value - should be same as previous()'s.
                     current = iter.current();
                     if (start != current) {
    -                    errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
    +                    fail("Word break failure: printEachBackward() Unexpected current value: current()=" +
                               current + ", expected(=previous())=" + start);
                     }
     
                     if (!expected[i][j].equals(given[i].substring(start, end))) {
    -                    errln("Word break failure: printEachBackward() expected:<" +
    +                    fail("Word break failure: printEachBackward() expected:<" +
                               expected[i][j] + ">, got:<" +
                               given[i].substring(start, end) +
                               "> start=" + start + "  end=" + end);
    @@ -207,7 +207,7 @@ void TestPrintAt_1() {
                     start = iter.previous();
     
                     if (!expected[i][j].equals(given[i].substring(start, end))) {
    -                    errln("Word break failure: printAt_1() expected:<" +
    +                    fail("Word break failure: printAt_1() expected:<" +
                               expected[i][j] + ">, got:<" +
                               given[i].substring(start, end) +
                               "> start=" + start + "  end=" + end);
    @@ -234,7 +234,7 @@ void TestPrintAt_2() {
     
                 // Check preceding(0)'s return value - should equals BreakIterator.DONE.
                 if (iter.preceding(0) != BreakIterator.DONE) {
    -                 errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" +
    +                 fail("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" +
                            iter.preceding(0));
                 }
     
    @@ -243,7 +243,7 @@ void TestPrintAt_2() {
                     end = iter.next();
     
                     if (!expected[i][j].equals(given[i].substring(start, end))) {
    -                    errln("Word break failure: printAt_2() expected:<" +
    +                    fail("Word break failure: printAt_2() expected:<" +
                               expected[i][j] + ">, got:<" +
                               given[i].substring(start, end) +
                               "> start=" + start + "  end=" + end);
    @@ -254,7 +254,7 @@ void TestPrintAt_2() {
                 end = iter.last();
                 start = iter.next();
                 if (start != BreakIterator.DONE) {
    -                 errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" + start);
    +                 fail("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" + start);
                 }
             }
         }
    diff --git a/test/jdk/java/text/CharacterIterator/CharacterIteratorTest.java b/test/jdk/java/text/CharacterIterator/CharacterIteratorTest.java
    index 48133100e73..a559c3897b2 100644
    --- a/test/jdk/java/text/CharacterIterator/CharacterIteratorTest.java
    +++ b/test/jdk/java/text/CharacterIterator/CharacterIteratorTest.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 2023, 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,8 +23,8 @@
     
     /*
      * @test
    - * @library /java/text/testlib
      * @summary test for Character Iterator
    + * @run junit CharacterIteratorTest
      */
     
     /*
    @@ -65,14 +65,15 @@
     
     import java.text.*;
     
    -public class CharacterIteratorTest extends IntlTest {
    -    public static void main(String[] args) throws Exception {
    -        new CharacterIteratorTest().run(args);
    -    }
    +import org.junit.jupiter.api.Test;
    +
    +import static org.junit.jupiter.api.Assertions.fail;
     
    +public class CharacterIteratorTest {
         public CharacterIteratorTest() {
         }
     
    +    @Test
         public void TestConstructionAndEquality() {
             String  testText = "Now is the time for all good men to come to the aid of their country.";
             String  testText2 = "Don't bother using this string.";
    @@ -84,49 +85,50 @@ public void TestConstructionAndEquality() {
             CharacterIterator test5 = (CharacterIterator)test1.clone();
     
             if (test1.equals(test2) || test1.equals(test3) || test1.equals(test4))
    -            errln("Construation or equals() failed: Two unequal iterators tested equal");
    +            fail("Construation or equals() failed: Two unequal iterators tested equal");
     
             if (!test1.equals(test5))
    -            errln("clone() or equals() failed: Two clones tested unequal");
    +            fail("clone() or equals() failed: Two clones tested unequal");
     
             if (test1.hashCode() == test2.hashCode() || test1.hashCode() == test3.hashCode()
                             || test1.hashCode() == test4.hashCode())
    -            errln("hash() failed:  different objects have same hash code");
    +            fail("hash() failed:  different objects have same hash code");
     
             if (test1.hashCode() != test5.hashCode())
    -            errln("hash() failed:  identical objects have different hash codes");
    +            fail("hash() failed:  identical objects have different hash codes");
     
             test1.setIndex(5);
             if (!test1.equals(test2) || test1.equals(test5))
    -            errln("setIndex() failed");
    +            fail("setIndex() failed");
         }
     
    +    @Test
         public void TestIteration() {
             String text = "Now is the time for all good men to come to the aid of their country.";
     
             CharacterIterator   iter = new StringCharacterIterator(text, 5);
     
             if (iter.current() != text.charAt(5))
    -            errln("Iterator didn't start out in the right place.");
    +            fail("Iterator didn't start out in the right place.");
     
             char c = iter.first();
             int     i = 0;
     
             if (iter.getBeginIndex() != 0 || iter.getEndIndex() != text.length())
    -            errln("getBeginIndex() or getEndIndex() failed");
    +            fail("getBeginIndex() or getEndIndex() failed");
     
    -        logln("Testing forward iteration...");
    +        System.out.println("Testing forward iteration...");
             do {
                 if (c == CharacterIterator.DONE && i != text.length())
    -                errln("Iterator reached end prematurely");
    +                fail("Iterator reached end prematurely");
                 else if (c != text.charAt(i))
    -                errln("Character mismatch at position " + i + ", iterator has " + c +
    +                fail("Character mismatch at position " + i + ", iterator has " + c +
                                         ", string has " + text.charAt(c));
     
                 if (iter.current() != c)
    -                errln("current() isn't working right");
    +                fail("current() isn't working right");
                 if (iter.getIndex() != i)
    -                errln("getIndex() isn't working right");
    +                fail("getIndex() isn't working right");
     
                 if (c != CharacterIterator.DONE) {
                     c = iter.next();
    @@ -137,18 +139,18 @@ else if (c != text.charAt(i))
             c = iter.last();
             i = text.length() - 1;
     
    -        logln("Testing backward iteration...");
    +        System.out.println("Testing backward iteration...");
             do {
                 if (c == CharacterIterator.DONE && i >= 0)
    -                errln("Iterator reached end prematurely");
    +                fail("Iterator reached end prematurely");
                 else if (c != text.charAt(i))
    -                errln("Character mismatch at position " + i + ", iterator has " + c +
    +                fail("Character mismatch at position " + i + ", iterator has " + c +
                                         ", string has " + text.charAt(c));
     
                 if (iter.current() != c)
    -                errln("current() isn't working right");
    +                fail("current() isn't working right");
                 if (iter.getIndex() != i)
    -                errln("getIndex() isn't working right");
    +                fail("getIndex() isn't working right");
     
                 if (c != CharacterIterator.DONE) {
                     c = iter.previous();
    @@ -158,26 +160,26 @@ else if (c != text.charAt(i))
     
             iter = new StringCharacterIterator(text, 5, 15, 10);
             if (iter.getBeginIndex() != 5 || iter.getEndIndex() != 15)
    -            errln("creation of a restricted-range iterator failed");
    +            fail("creation of a restricted-range iterator failed");
     
             if (iter.getIndex() != 10 || iter.current() != text.charAt(10))
    -            errln("starting the iterator in the middle didn't work");
    +            fail("starting the iterator in the middle didn't work");
     
             c = iter.first();
             i = 5;
     
    -        logln("Testing forward iteration over a range...");
    +        System.out.println("Testing forward iteration over a range...");
             do {
                 if (c == CharacterIterator.DONE && i != 15)
    -                errln("Iterator reached end prematurely");
    +                fail("Iterator reached end prematurely");
                 else if (c != text.charAt(i))
    -                errln("Character mismatch at position " + i + ", iterator has " + c +
    +                fail("Character mismatch at position " + i + ", iterator has " + c +
                                         ", string has " + text.charAt(c));
     
                 if (iter.current() != c)
    -                errln("current() isn't working right");
    +                fail("current() isn't working right");
                 if (iter.getIndex() != i)
    -                errln("getIndex() isn't working right");
    +                fail("getIndex() isn't working right");
     
                 if (c != CharacterIterator.DONE) {
                     c = iter.next();
    @@ -188,18 +190,18 @@ else if (c != text.charAt(i))
             c = iter.last();
             i = 14;
     
    -        logln("Testing backward iteration over a range...");
    +        System.out.println("Testing backward iteration over a range...");
             do {
                 if (c == CharacterIterator.DONE && i >= 5)
    -                errln("Iterator reached end prematurely");
    +                fail("Iterator reached end prematurely");
                 else if (c != text.charAt(i))
    -                errln("Character mismatch at position " + i + ", iterator has " + c +
    +                fail("Character mismatch at position " + i + ", iterator has " + c +
                                         ", string has " + text.charAt(c));
     
                 if (iter.current() != c)
    -                errln("current() isn't working right");
    +                fail("current() isn't working right");
                 if (iter.getIndex() != i)
    -                errln("getIndex() isn't working right");
    +                fail("getIndex() isn't working right");
     
                 if (c != CharacterIterator.DONE) {
                     c = iter.previous();
    @@ -211,6 +213,7 @@ else if (c != text.charAt(i))
         /**
          * @bug 4082050 4078261 4078255
          */
    +    @Test
         public void TestPathologicalCases() {
             String text = "This is only a test.";
     
    @@ -227,7 +230,7 @@ public void TestPathologicalCases() {
                 || iter.previous() != CharacterIterator.DONE
                 || iter.current() != CharacterIterator.DONE
                 || iter.getIndex() != 5)
    -            errln("Got something other than DONE when performing operations on an empty StringCharacterIterator");
    +            fail("Got something other than DONE when performing operations on an empty StringCharacterIterator");
     */
     CharacterIterator iter = null;
     
    @@ -242,7 +245,7 @@ public void TestPathologicalCases() {
                 gotException = true;
             }
             if (!gotException)
    -            errln("StringCharacterIterator didn't throw an exception when given an invalid substring range.");
    +            fail("StringCharacterIterator didn't throw an exception when given an invalid substring range.");
     
             // test for bug #4078255 (getting wrong value from next() when we're at the end
             // of the string)
    @@ -253,17 +256,17 @@ public void TestPathologicalCases() {
             iter.last();
             actualIndex = iter.getIndex();
             if (actualIndex != expectedIndex - 1)
    -            errln("last() failed: expected " + (expectedIndex - 1) + ", got " + actualIndex);
    +            fail("last() failed: expected " + (expectedIndex - 1) + ", got " + actualIndex);
     
             iter.next();
             actualIndex = iter.getIndex();
             if (actualIndex != expectedIndex)
    -            errln("next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
    +            fail("next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
     
             iter.next();
             actualIndex = iter.getIndex();
             if (actualIndex != expectedIndex)
    -            errln("second next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
    +            fail("second next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
         }
     
         /*
    @@ -271,6 +274,7 @@ public void TestPathologicalCases() {
          * #4123771 is actually a duplicate of bug #4051073, which was fixed some time ago, but
          * no one ever added a regression test for it.
          */
    +    @Test
         public void TestBug4123771() {
             String text = "Some string for testing";
             StringCharacterIterator iter = new StringCharacterIterator(text);
    @@ -283,7 +287,7 @@ public void TestBug4123771() {
                 System.out.println(" position: " + index);
                 System.out.println(" getEndIndex(): " + iter.getEndIndex());
                 System.out.println(" text.length(): " + text.length());
    -            errln(""); // re-throw the exception through our test framework
    +            fail(""); // re-throw the exception through our test framework
             }
         }
     }
    diff --git a/test/jdk/java/text/Collator/APITest.java b/test/jdk/java/text/Collator/APITest.java
    index 643cdbe6bd1..1c2fc88a620 100644
    --- a/test/jdk/java/text/Collator/APITest.java
    +++ b/test/jdk/java/text/Collator/APITest.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 2023, 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 @@
      * @library /java/text/testlib
      * @summary test Collation API
      * @modules jdk.localedata
    + * @run junit APITest
      */
     /*
     (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
    @@ -45,17 +46,16 @@
     import java.text.CollationKey;
     import java.text.CollationElementIterator;
     
    -public class APITest extends CollatorTest {
    +import org.junit.jupiter.api.Test;
     
    -    public static void main(String[] args) throws Exception {
    -        new APITest().run(args);
    -    }
    +import static org.junit.jupiter.api.Assertions.fail;
    +
    +public class APITest {
     
         final void doAssert(boolean condition, String message)
         {
             if (!condition) {
    -            err("ERROR: ");
    -            errln(message);
    +            fail("ERROR: " + message);
             }
         }
     
    @@ -64,103 +64,103 @@ public final void TestProperty( )
             Collator col = null;
             try {
                 col = Collator.getInstance(Locale.ROOT);
    -            logln("The property tests begin : ");
    -            logln("Test ctors : ");
    +            System.out.println("The property tests begin : ");
    +            System.out.println("Test ctors : ");
                 doAssert(col.compare("ab", "abc") < 0, "ab < abc comparison failed");
                 doAssert(col.compare("ab", "AB") < 0, "ab < AB comparison failed");
                 doAssert(col.compare("black-bird", "blackbird") > 0, "black-bird > blackbird comparison failed");
                 doAssert(col.compare("black bird", "black-bird") < 0, "black bird < black-bird comparison failed");
                 doAssert(col.compare("Hello", "hello") > 0, "Hello > hello comparison failed");
     
    -            logln("Test ctors ends.");
    -            logln("testing Collator.getStrength() method ...");
    +            System.out.println("Test ctors ends.");
    +            System.out.println("testing Collator.getStrength() method ...");
                 doAssert(col.getStrength() == Collator.TERTIARY, "collation object has the wrong strength");
                 doAssert(col.getStrength() != Collator.PRIMARY, "collation object's strength is primary difference");
     
    -            logln("testing Collator.setStrength() method ...");
    +            System.out.println("testing Collator.setStrength() method ...");
                 col.setStrength(Collator.SECONDARY);
                 doAssert(col.getStrength() != Collator.TERTIARY, "collation object's strength is secondary difference");
                 doAssert(col.getStrength() != Collator.PRIMARY, "collation object's strength is primary difference");
                 doAssert(col.getStrength() == Collator.SECONDARY, "collation object has the wrong strength");
     
    -            logln("testing Collator.setDecomposition() method ...");
    +            System.out.println("testing Collator.setDecomposition() method ...");
                 col.setDecomposition(Collator.NO_DECOMPOSITION);
                 doAssert(col.getDecomposition() != Collator.FULL_DECOMPOSITION, "collation object's strength is secondary difference");
                 doAssert(col.getDecomposition() != Collator.CANONICAL_DECOMPOSITION, "collation object's strength is primary difference");
                 doAssert(col.getDecomposition() == Collator.NO_DECOMPOSITION, "collation object has the wrong strength");
             } catch (Exception foo) {
    -            errln("Error : " + foo.getMessage());
    -            errln("Default Collator creation failed.");
    +            fail("Error : " + foo.getMessage()
    +            + "\n Default Collator creation failed.");
             }
    -        logln("Default collation property test ended.");
    -        logln("Collator.getRules() testing ...");
    +        System.out.println("Default collation property test ended.");
    +        System.out.println("Collator.getRules() testing ...");
             doAssert(((RuleBasedCollator)col).getRules().length() != 0, "getRules() result incorrect" );
    -        logln("getRules tests end.");
    +        System.out.println("getRules tests end.");
             try {
                 col = Collator.getInstance(Locale.FRENCH);
                 col.setStrength(Collator.PRIMARY);
    -            logln("testing Collator.getStrength() method again ...");
    +            System.out.println("testing Collator.getStrength() method again ...");
                 doAssert(col.getStrength() != Collator.TERTIARY, "collation object has the wrong strength");
                 doAssert(col.getStrength() == Collator.PRIMARY, "collation object's strength is not primary difference");
     
    -            logln("testing French Collator.setStrength() method ...");
    +            System.out.println("testing French Collator.setStrength() method ...");
                 col.setStrength(Collator.TERTIARY);
                 doAssert(col.getStrength() == Collator.TERTIARY, "collation object's strength is not tertiary difference");
                 doAssert(col.getStrength() != Collator.PRIMARY, "collation object's strength is primary difference");
                 doAssert(col.getStrength() != Collator.SECONDARY, "collation object's strength is secondary difference");
     
             } catch (Exception bar) {
    -            errln("Error :  " + bar.getMessage());
    -            errln("Creating French collation failed.");
    +            fail("Error :  " + bar.getMessage()
    +            + "\n Creating French collation failed.");
             }
     
    -        logln("Create junk collation: ");
    +        System.out.println("Create junk collation: ");
             Locale abcd = Locale.of("ab", "CD");
             Collator junk = null;
             try {
                 junk = Collator.getInstance(abcd);
             } catch (Exception err) {
    -            errln("Error : " + err.getMessage());
    -            errln("Junk collation creation failed, should at least return the collator for the base bundle.");
    +            fail("Error : " + err.getMessage()
    +            + "\n Junk collation creation failed, should at least return the collator for the base bundle.");
             }
             try {
                 col = Collator.getInstance(Locale.ROOT);
                 doAssert(col.equals(junk), "The base bundle's collation should be returned.");
             } catch (Exception exc) {
    -            errln("Error : " + exc.getMessage());
    -            errln("Default collation comparison, caching not working.");
    +            fail("Error : " + exc.getMessage()
    +            + "\n Default collation comparison, caching not working.");
             }
     
    -        logln("Collator property test ended.");
    +        System.out.println("Collator property test ended.");
         }
     
         public final void TestHashCode( )
         {
    -        logln("hashCode tests begin.");
    +        System.out.println("hashCode tests begin.");
             Collator col1 = null;
             try {
                 col1 = Collator.getInstance(Locale.ROOT);
             } catch (Exception foo) {
    -            errln("Error : " + foo.getMessage());
    -            errln("Default collation creation failed.");
    +            fail("Error : " + foo.getMessage()
    +            + "\n Default collation creation failed.");
             }
             Collator col2 = null;
             Locale dk = Locale.of("da", "DK");
             try {
                 col2 = Collator.getInstance(dk);
             } catch (Exception bar) {
    -            errln("Error : " + bar.getMessage());
    -            errln("Danish collation creation failed.");
    +            fail("Error : " + bar.getMessage()
    +            + "\n Danish collation creation failed.");
                 return;
             }
             Collator col3 = null;
             try {
                 col3 = Collator.getInstance(Locale.ROOT);
             } catch (Exception err) {
    -            errln("Error : " + err.getMessage());
    -            errln("2nd default collation creation failed.");
    +            fail("Error : " + err.getMessage()
    +            + "\n 2nd default collation creation failed.");
             }
    -        logln("Collator.hashCode() testing ...");
    +        System.out.println("Collator.hashCode() testing ...");
     
             if (col1 != null) {
                 doAssert(col1.hashCode() != col2.hashCode(), "Hash test1 result incorrect");
    @@ -169,7 +169,7 @@ public final void TestHashCode( )
                 }
             }
     
    -        logln("hashCode tests end.");
    +        System.out.println("hashCode tests end.");
         }
     
         //----------------------------------------------------------------------------
    @@ -177,20 +177,20 @@ public final void TestHashCode( )
         //
         public final void TestCollationKey( )
         {
    -        logln("testing CollationKey begins...");
    +        System.out.println("testing CollationKey begins...");
             Collator col = null;
             try {
                 col = Collator.getInstance(Locale.ROOT);
             } catch (Exception foo) {
    -            errln("Error : " + foo.getMessage());
    -            errln("Default collation creation failed.");
    +            fail("Error : " + foo.getMessage()
    +            + "\n Default collation creation failed.");
             }
             if (col == null) {
                 return;
             }
     
             String test1 = "Abcda", test2 = "abcda";
    -        logln("Use tertiary comparison level testing ....");
    +        System.out.println("Use tertiary comparison level testing ....");
             CollationKey sortk1 = col.getCollationKey(test1);
             CollationKey sortk2 = col.getCollationKey(test2);
             doAssert(sortk1.compareTo(sortk2) > 0,
    @@ -209,20 +209,20 @@ public final void TestCollationKey( )
             byte byteArray1[] = sortk1.toByteArray();
             byte byteArray2[] = sortk2.toByteArray();
             doAssert(byteArray1 != null && byteArray2 != null, "CollationKey.toByteArray failed.");
    -        logln("testing sortkey ends...");
    +        System.out.println("testing sortkey ends...");
         }
         //----------------------------------------------------------------------------
         // ctor -- Tests the constructor methods
         //
         public final void TestElemIter( )
         {
    -        logln("testing sortkey begins...");
    +        System.out.println("testing sortkey begins...");
             Collator col = null;
             try {
                 col = Collator.getInstance();
             } catch (Exception foo) {
    -            errln("Error : " + foo.getMessage());
    -            errln("Default collation creation failed.");
    +            fail("Error : " + foo.getMessage()
    +            + "\n Default collation creation failed.");
             }
             RuleBasedCollator rbCol;
             if (col instanceof RuleBasedCollator) {
    @@ -232,7 +232,7 @@ public final void TestElemIter( )
             }
             String testString1 = "XFILE What subset of all possible test cases has the highest probability of detecting the most errors?";
             String testString2 = "Xf ile What subset of all possible test cases has the lowest probability of detecting the least errors?";
    -        logln("Constructors and comparison testing....");
    +        System.out.println("Constructors and comparison testing....");
             CollationElementIterator iterator1 = rbCol.getCollationElementIterator(testString1);
             CollationElementIterator iterator2 = rbCol.getCollationElementIterator(testString1);
             CollationElementIterator iterator3 = rbCol.getCollationElementIterator(testString2);
    @@ -303,17 +303,17 @@ public final void TestElemIter( )
                          != CollationElementIterator.secondaryOrder(order3),
                      "The secondary orders should be different");
             doAssert(order1 != CollationElementIterator.NULLORDER, "Unexpected end of iterator reached");
    -        logln("testing CollationElementIterator ends...");
    +        System.out.println("testing CollationElementIterator ends...");
         }
     
         public final void TestGetAll()
         {
             Locale[] list = Collator.getAvailableLocales();
             for (int i = 0; i < list.length; ++i) {
    -            log("Locale name: ");
    -            log(list[i].toString());
    -            log(" , the display name is : ");
    -            logln(list[i].getDisplayName());
    +            System.out.println("Locale name: ");
    +            System.out.println(list[i].toString());
    +            System.out.println(" , the display name is : ");
    +            System.out.println(list[i].getDisplayName());
             }
         }
     }
    diff --git a/test/jdk/java/text/Collator/Bug6271411.java b/test/jdk/java/text/Collator/Bug6271411.java
    index 16495d04bea..b78f11583d8 100644
    --- a/test/jdk/java/text/Collator/Bug6271411.java
    +++ b/test/jdk/java/text/Collator/Bug6271411.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2023, 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
    @@ -24,21 +24,20 @@
     /*
      * @test
      * @bug 6271411
    - * @library /java/text/testlib
      * @summary Confirm that three JCK testcases for CollationElementIterator pass.
    + * @run junit Bug6271411
      */
     
     import java.text.*;
     
    +import org.junit.jupiter.api.Test;
    +
    +import static org.junit.jupiter.api.Assertions.fail;
    +
     /*
      * Based on JCK-runtime-15/tests/api/java_text/CollationElementIterator/ColltnElmtIterTests.java.
      */
    -public class Bug6271411 extends IntlTest {
    -
    -    public static void main(String argv[]) throws Exception {
    -        Bug6271411 test = new Bug6271411();
    -        test.run(argv);
    -    }
    +public class Bug6271411 {
     
         /*
          * Rule for RuleBasedCollator
    @@ -58,6 +57,7 @@ public static void main(String argv[]) throws Exception {
          * (not IndexOutOfBoundsException) if the given offset is invalid.
          * Use CollationElementIterator.setText(String).
          */
    +    @Test
         public void Test_CollationElementIterator0007() throws Exception {
             int[] offsets = {
                 Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -10000, -2, -1,
    @@ -90,7 +90,7 @@ public void Test_CollationElementIterator0007() throws Exception {
             }
     
             if (err) {
    -            errln("CollationElementIterator.setOffset() didn't throw an expected IllegalArguemntException.");
    +            fail("CollationElementIterator.setOffset() didn't throw an expected IllegalArguemntException.");
             }
         }
     
    @@ -99,6 +99,7 @@ public void Test_CollationElementIterator0007() throws Exception {
          * IllegalArgumentException if the given offset is invalid.
          * Use CollationElementIterator.setText(CharacterIterator).
          */
    +    @Test
         public void Test_CollationElementIterator0010() throws Exception {
             String prefix = "xyz abc";
             String suffix = "1234567890";
    @@ -144,7 +145,7 @@ public void Test_CollationElementIterator0010() throws Exception {
             }
     
             if (err) {
    -            errln("CollationElementIterator.setOffset() didn't throw an expected IllegalArguemntException.");
    +            fail("CollationElementIterator.setOffset() didn't throw an expected IllegalArguemntException.");
             }
         }
     
    @@ -153,6 +154,7 @@ public void Test_CollationElementIterator0010() throws Exception {
          * an offset as expected.
          * Use CollationElementIterator.setText(CharacterIterator).
          */
    +    @Test
         public void Test_CollationElementIterator0011() throws Exception {
             String prefix = "xyz abc";
             String suffix = "1234567890";
    diff --git a/test/jdk/java/text/Collator/CollatorTest.java b/test/jdk/java/text/Collator/CollatorTest.java
    deleted file mode 100644
    index bb6785b888f..00000000000
    --- a/test/jdk/java/text/Collator/CollatorTest.java
    +++ /dev/null
    @@ -1,141 +0,0 @@
    -/*
    - * Copyright (c) 1998, 2016, 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.lang.reflect.*;
    -import java.util.Hashtable;
    -import java.util.Enumeration;
    -import java.util.Vector;
    -import java.io.*;
    -import java.text.*;
    -
    -/**
    - * CollatorTest is a base class for tests that can be run conveniently from
    - * the command line as well as under the Java test harness.
    - * 

    - * Sub-classes implement a set of methods named Test. Each - * of these methods performs some test. Test methods should indicate - * errors by calling either err or errln. This will increment the - * errorCount field and may optionally print a message to the log. - * Debugging information may also be added to the log via the log - * and logln methods. These methods will add their arguments to the - * log only if the test is being run in verbose mode. - */ -public abstract class CollatorTest extends IntlTest { - - //------------------------------------------------------------------------ - // These methods are utilities specific to the Collation tests.. - //------------------------------------------------------------------------ - - protected void assertEqual(CollationElementIterator i1, CollationElementIterator i2) { - int c1, c2, count = 0; - do { - c1 = i1.next(); - c2 = i2.next(); - if (c1 != c2) { - errln(" " + count + ": " + c1 + " != " + c2); - break; - } - count++; - } while (c1 != CollationElementIterator.NULLORDER); - } - - // Replace nonprintable characters with unicode escapes - static protected String prettify(String str) { - StringBuffer result = new StringBuffer(); - - String zero = "0000"; - - for (int i = 0; i < str.length(); i++) { - char ch = str.charAt(i); - if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| (ch > 0x7E && ch < 0xA0) || ch > 0x100) { - String hex = Integer.toString((int)ch,16); - - result.append("\\u" + zero.substring(0, 4 - hex.length()) + hex); - } else { - result.append(ch); - } - } - return result.toString(); - } - - // Produce a printable representation of a CollationKey - static protected String prettify(CollationKey key) { - StringBuffer result = new StringBuffer(); - byte[] bytes = key.toByteArray(); - - for (int i = 0; i < bytes.length; i += 2) { - int val = (bytes[i] << 8) + bytes[i+1]; - result.append(Integer.toString(val, 16) + " "); - } - return result.toString(); - } - - //------------------------------------------------------------------------ - // Everything below here is boilerplate code that makes it possible - // to add a new test by simply adding a function to an existing class - //------------------------------------------------------------------------ - - protected void doTest(Collator col, int strength, - String[] source, String[] target, int[] result) { - if (source.length != target.length) { - errln("Data size mismatch: source = " + - source.length + ", target = " + target.length); - - return; // Return if "-nothrow" is specified. - } - if (source.length != result.length) { - errln("Data size mismatch: source & target = " + - source.length + ", result = " + result.length); - - return; // Return if "-nothrow" is specified. - } - - col.setStrength(strength); - for (int i = 0; i < source.length ; i++) { - doTest(col, source[i], target[i], result[i]); - } - } - - protected void doTest(Collator col, - String source, String target, int result) { - char relation = '='; - if (result <= -1) { - relation = '<'; - } else if (result >= 1) { - relation = '>'; - } - - int compareResult = col.compare(source, target); - CollationKey sortKey1 = col.getCollationKey(source); - CollationKey sortKey2 = col.getCollationKey(target); - int keyResult = sortKey1.compareTo(sortKey2); - if (compareResult != keyResult) { - errln("Compare and Collation Key results are different! Source = " + - source + " Target = " + target); - } - if (keyResult != result) { - errln("Collation Test failed! Source = " + source + " Target = " + - target + " result should be " + relation); - } - } -} diff --git a/test/jdk/java/text/Collator/DanishTest.java b/test/jdk/java/text/Collator/DanishTest.java index ee8c5481b5f..19596912388 100644 --- a/test/jdk/java/text/Collator/DanishTest.java +++ b/test/jdk/java/text/Collator/DanishTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -27,6 +27,7 @@ * @library /java/text/testlib * @summary test Danish Collation * @modules jdk.localedata + * @run junit DanishTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -43,12 +44,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class DanishTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new DanishTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class DanishTest { /* * Data for TestPrimary() @@ -196,18 +197,20 @@ public static void main(String[] args) throws Exception { "\u00F6BERG" // o-diaeresis }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); for (int i = 0; i < testData.length-1; i++) { for (int j = i+1; j < testData.length; j++) { - doTest(myCollation, testData[i], testData[j], -1); + TestUtils.doCollatorTest(myCollation, testData[i], testData[j], -1); } } } diff --git a/test/jdk/java/text/Collator/DummyTest.java b/test/jdk/java/text/Collator/DummyTest.java index 3e3124edb07..814b5544ea8 100644 --- a/test/jdk/java/text/Collator/DummyTest.java +++ b/test/jdk/java/text/Collator/DummyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,11 +25,16 @@ * @test * @library /java/text/testlib * @summary test Dummy Collation + * @run junit DummyTest */ import java.text.Collator; import java.text.RuleBasedCollator; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved (C) Copyright IBM Corp. 1996 - All Rights Reserved @@ -42,11 +47,7 @@ Taligent is a registered trademark of Taligent, Inc. */ -public class DummyTest extends CollatorTest { - - public static void main(String[] args) throws Exception { - new DummyTest().run(args); - } +public class DummyTest { private static final String DEFAULTRULES = "='\u200B'=\u200C=\u200D=\u200E=\u200F" @@ -382,25 +383,28 @@ public static void main(String[] args) throws Exception { "z" }; + @Test public void TestPrimary() { - doTest(getCollator(), Collator.PRIMARY, + TestUtils.doCollatorTest(getCollator(), Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestSecondary() { - doTest(getCollator(), Collator.SECONDARY, + TestUtils.doCollatorTest(getCollator(), Collator.SECONDARY, secondarySourceData, secondaryTargetData, secondaryResults); } + @Test public void TestTertiary() { Collator col = getCollator(); - doTest(col, Collator.TERTIARY, + TestUtils.doCollatorTest(col, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); for (int i = 0; i < testData.length-1; i++) { for (int j = i+1; j < testData.length; j++) { - doTest(col, testData[i], testData[j], -1); + TestUtils.doCollatorTest(col, testData[i], testData[j], -1); } } } @@ -412,7 +416,7 @@ private Collator getCollator() { myCollation = new RuleBasedCollator (DEFAULTRULES + "& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "); } catch (Exception foo) { - errln("Collator creation failed."); + fail("Collator creation failed."); myCollation = (RuleBasedCollator)Collator.getInstance(); } } diff --git a/test/jdk/java/text/Collator/EnglishTest.java b/test/jdk/java/text/Collator/EnglishTest.java index 3c4da57b75c..ee948de21b6 100644 --- a/test/jdk/java/text/Collator/EnglishTest.java +++ b/test/jdk/java/text/Collator/EnglishTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,11 +25,16 @@ * @test * @library /java/text/testlib * @summary test English Collation + * @run junit EnglishTest */ import java.util.Locale; import java.text.Collator; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved (C) Copyright IBM Corp. 1996 - All Rights Reserved @@ -42,11 +47,7 @@ Taligent is a registered trademark of Taligent, Inc. */ -public class EnglishTest extends CollatorTest { - - public static void main(String[] args) throws Exception { - new EnglishTest().run(args); - } +public class EnglishTest { /* * Data for TestPrimary() @@ -201,23 +202,26 @@ public static void main(String[] args) throws Exception { "x" }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestSecondary() { - doTest(myCollation, Collator.SECONDARY, + TestUtils.doCollatorTest(myCollation, Collator.SECONDARY, secondarySourceData, secondaryTargetData, secondaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); for (int i = 0; i < testData.length-1; i++) { for (int j = i+1; j < testData.length; j++) { - doTest(myCollation, testData[i], testData[j], -1); + TestUtils.doCollatorTest(myCollation, testData[i], testData[j], -1); } } } diff --git a/test/jdk/java/text/Collator/FinnishTest.java b/test/jdk/java/text/Collator/FinnishTest.java index afd403fd96b..42c5de360cf 100644 --- a/test/jdk/java/text/Collator/FinnishTest.java +++ b/test/jdk/java/text/Collator/FinnishTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ * @library /java/text/testlib * @summary test Finnish Collation * @modules jdk.localedata + * @run junit FinnishTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -42,12 +43,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class FinnishTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new FinnishTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class FinnishTest { /* * Data for TestPrimary() @@ -85,13 +86,15 @@ public static void main(String[] args) throws Exception { 1, -1, 1 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); } diff --git a/test/jdk/java/text/Collator/FrenchTest.java b/test/jdk/java/text/Collator/FrenchTest.java index 38492db023c..fa6ca031859 100644 --- a/test/jdk/java/text/Collator/FrenchTest.java +++ b/test/jdk/java/text/Collator/FrenchTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ * @library /java/text/testlib * @summary test French Collation * @modules jdk.localedata + * @run junit FrenchTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -42,12 +43,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class FrenchTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new FrenchTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class FrenchTest { private static final String[] tertiarySourceData = { "abc", @@ -86,13 +87,14 @@ public static void main(String[] args) throws Exception { "x" }; + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); for (int i = 0; i < testData.length-1; i++) { for (int j = i+1; j < testData.length; j++) { - doTest(myCollation, testData[i], testData[j], -1); + TestUtils.doCollatorTest(myCollation, testData[i], testData[j], -1); } } } diff --git a/test/jdk/java/text/Collator/G7Test.java b/test/jdk/java/text/Collator/G7Test.java index f7bdfa4f868..fcb201b0719 100644 --- a/test/jdk/java/text/Collator/G7Test.java +++ b/test/jdk/java/text/Collator/G7Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ * @library /java/text/testlib * @summary test G7 Collation * @modules jdk.localedata + * @run junit G7Test */ /* * @@ -54,13 +55,13 @@ import java.text.RuleBasedCollator; import java.util.Locale; -// G7 test program for printing out test results +import org.junit.jupiter.api.Test; -public class G7Test extends CollatorTest { +import static org.junit.jupiter.api.Assertions.fail; - public static void main(String[] args) throws Exception { - new G7Test().run(args); - } +// G7 test program for printing out test results + +public class G7Test { private static final String testCases[] = { "black-birds", // 0 @@ -158,6 +159,7 @@ public static void main(String[] args) throws Exception { 2, 3, 4, 5, 20, 6, 8, 10, 7, 29 }; + @Test public void TestG7Data() { for (int i = 0; i < locales.length; i++) { Collator myCollation= null; @@ -167,14 +169,14 @@ public void TestG7Data() { myCollation = Collator.getInstance(locales[i]); tblColl1 = new RuleBasedCollator(((RuleBasedCollator)myCollation).getRules()); } catch (Exception foo) { - errln("Exception: " + foo.getMessage() + + fail("Exception: " + foo.getMessage() + " Locale : " + locales[i].getDisplayName() + " getRules failed\n"); continue; } for (int j = 0; j < FIXEDTESTSET; j++) { for (int n = j+1; n < FIXEDTESTSET; n++) { - doTest(tblColl1, testCases[G7Results[i][j]], + TestUtils.doCollatorTest(tblColl1, testCases[G7Results[i][j]], testCases[G7Results[i][n]], -1); } } @@ -185,6 +187,7 @@ public void TestG7Data() { /* * Demo Test 1 : Create a new table collation with rules "& Z < p, P" */ + @Test public void TestDemoTest1() { int j = 0; final Collator myCollation = Collator.getInstance(Locale.US); @@ -196,13 +199,13 @@ public void TestDemoTest1() { tblColl = new RuleBasedCollator(newRules); for (j = 0; j < FIXEDTESTSET; j++) { for (int n = j+1; n < FIXEDTESTSET; n++) { - doTest(tblColl, testCases[Test1Results[j]], + TestUtils.doCollatorTest(tblColl, testCases[Test1Results[j]], testCases[Test1Results[n]], -1); } } tblColl = null; } catch (Exception foo) { - errln("Exception: " + foo.getMessage() + + fail("Exception: " + foo.getMessage() + "\nDemo Test 1 Table Collation object creation failed."); } } @@ -211,6 +214,7 @@ public void TestDemoTest1() { * Demo Test 2 : Create a new table collation with rules * "& C < ch , cH, Ch, CH" */ + @Test public void TestDemoTest2() { final Collator myCollation = Collator.getInstance(Locale.US); final String defRules = ((RuleBasedCollator)myCollation).getRules(); @@ -220,12 +224,12 @@ public void TestDemoTest2() { RuleBasedCollator tblColl = new RuleBasedCollator(newRules); for (int j = 0; j < TOTALTESTSET; j++) { for (int n = j+1; n < TOTALTESTSET; n++) { - doTest(tblColl, testCases[Test2Results[j]], + TestUtils.doCollatorTest(tblColl, testCases[Test2Results[j]], testCases[Test2Results[n]], -1); } } } catch (Exception foo) { - errln("Exception: " + foo.getMessage() + + fail("Exception: " + foo.getMessage() + "\nDemo Test 2 Table Collation object creation failed.\n"); } } @@ -234,6 +238,7 @@ public void TestDemoTest2() { * Demo Test 3 : Create a new table collation with rules * "& Question'-'mark ; '?' & Hash'-'mark ; '#' & Ampersand ; '&'" */ + @Test public void TestDemoTest3() { final Collator myCollation = Collator.getInstance(Locale.US); final String defRules = ((RuleBasedCollator)myCollation).getRules(); @@ -244,12 +249,12 @@ public void TestDemoTest3() { tblColl = new RuleBasedCollator(newRules); for (int j = 0; j < TOTALTESTSET; j++) { for (int n = j+1; n < TOTALTESTSET; n++) { - doTest(tblColl, testCases[Test3Results[j]], + TestUtils.doCollatorTest(tblColl, testCases[Test3Results[j]], testCases[Test3Results[n]], -1); } } } catch (Exception foo) { - errln("Exception: " + foo.getMessage() + + fail("Exception: " + foo.getMessage() + "\nDemo Test 3 Table Collation object creation failed."); } } @@ -258,6 +263,7 @@ public void TestDemoTest3() { * Demo Test 4 : Create a new table collation with rules * " & aa ; a'-' & ee ; e'-' & ii ; i'-' & oo ; o'-' & uu ; u'-' " */ + @Test public void TestDemoTest4() { final Collator myCollation = Collator.getInstance(Locale.US); final String defRules = ((RuleBasedCollator)myCollation).getRules(); @@ -268,12 +274,12 @@ public void TestDemoTest4() { tblColl = new RuleBasedCollator(newRules); for (int j = 0; j < TOTALTESTSET; j++) { for (int n = j+1; n < TOTALTESTSET; n++) { - doTest(tblColl, testCases[Test4Results[j]], + TestUtils.doCollatorTest(tblColl, testCases[Test4Results[j]], testCases[Test4Results[n]], -1); } } } catch (Exception foo) { - errln("Exception: " + foo.getMessage() + + fail("Exception: " + foo.getMessage() + "\nDemo Test 4 Table Collation object creation failed."); } tblColl = null; diff --git a/test/jdk/java/text/Collator/GermanTest.java b/test/jdk/java/text/Collator/GermanTest.java index 74129e96f93..92c6466e8c1 100644 --- a/test/jdk/java/text/Collator/GermanTest.java +++ b/test/jdk/java/text/Collator/GermanTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,6 +25,7 @@ * @test * @library /java/text/testlib * @summary test German Collation + * @run junit GermanTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -41,12 +42,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class GermanTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new GermanTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class GermanTest { /* * Shared data for TestPrimary() and TestTertiary() @@ -97,13 +98,15 @@ public static void main(String[] args) throws Exception { -1, 1 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, testSourceData, testTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, testSourceData, testTargetData, tertiaryResults); } diff --git a/test/jdk/java/text/Collator/IteratorTest.java b/test/jdk/java/text/Collator/IteratorTest.java index a5c7f9bedfa..38b6bb41565 100644 --- a/test/jdk/java/text/Collator/IteratorTest.java +++ b/test/jdk/java/text/Collator/IteratorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ * @bug 4062985 4108758 4108762 4157299 * @library /java/text/testlib * @summary Test CollationElementIterator, particularly the new methods in 1.2 + * @run junit IteratorTest */ /* * (C) Copyright IBM Corp. 1998 - All Rights Reserved @@ -40,22 +41,23 @@ import java.util.Locale; import java.text.*; -public class IteratorTest extends CollatorTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class IteratorTest { // TODO: // - Test previous() with contracting character sequences, which don't work // at the moment. // - Test edge cases on setOffset(), e.g. offset > length, etc. // - public static void main(String[] args) throws Exception { - new IteratorTest().run(args); - } - /** * Test for CollationElementIterator.previous() * * @bug 4108758 - Make sure it works with contracting characters * */ + @Test public void TestPrevious() throws ParseException { // A basic test to see if it's working at all backAndForth(en_us.getCollationElementIterator(test1)); @@ -82,6 +84,7 @@ public void TestPrevious() throws ParseException { /** * Test for getOffset() and setOffset() */ + @Test public void TestOffset() { CollationElementIterator iter = en_us.getCollationElementIterator(test1); @@ -96,7 +99,7 @@ public void TestOffset() { // Now set the offset back to the beginning and see if it works iter.setOffset(0); - assertEqual(iter, en_us.getCollationElementIterator(test1)); + TestUtils.compareCollationElementIters(iter, en_us.getCollationElementIterator(test1)); // TODO: try iterating halfway through a messy string. } @@ -104,6 +107,7 @@ public void TestOffset() { /** * Test for setText() */ + @Test public void TestSetText() { CollationElementIterator iter1 = en_us.getCollationElementIterator(test1); CollationElementIterator iter2 = en_us.getCollationElementIterator(test2); @@ -117,12 +121,13 @@ public void TestSetText() { // Now set it to point to the same string as the first iterator iter2.setText(test1); - assertEqual(iter1, iter2); + TestUtils.compareCollationElementIters(iter1, iter2); } /** @bug 4108762 * Test for getMaxExpansion() */ + @Test public void TestMaxExpansion() throws ParseException { // Try a simple one first: // The only expansion ends with 'e' and has length 2 @@ -151,6 +156,7 @@ public void TestMaxExpansion() throws ParseException { /* * @bug 4157299 */ + @Test public void TestClearBuffers() throws ParseException { RuleBasedCollator c = new RuleBasedCollator("< a < b < c & ab = d"); CollationElementIterator i = c.getCollationElementIterator("abcd"); @@ -160,7 +166,7 @@ public void TestClearBuffers() throws ParseException { i.setOffset(0); // go back to the beginning int e = i.next(); // and get this one again if (e != e0) { - errln("got " + Integer.toString(e, 16) + ", expected " + + fail("got " + Integer.toString(e, 16) + ", expected " + Integer.toString(e0, 16)); } } @@ -179,26 +185,26 @@ private void backAndForth(CollationElementIterator iter) { while ((o = iter.previous()) != CollationElementIterator.NULLORDER) { if (o != orders[--index]) { - errln("Mismatch at index " + index + ": " + fail("Mismatch at index " + index + ": " + orders[index] + " vs " + o); break; } } if (index != 0) { - errln("Didn't get back to beginning - index is " + index); + fail("Didn't get back to beginning - index is " + index); iter.reset(); - err("next: "); + fail("next: "); while ((o = iter.next()) != NULLORDER) { - err( Integer.toHexString(o) + " "); + fail( Integer.toHexString(o) + " "); } - errln(""); + fail(""); - err("prev: "); + fail("prev: "); while ((o = iter.previous()) != NULLORDER) { - err( Integer.toHexString(o) + " "); + fail( Integer.toHexString(o) + " "); } - errln(""); + fail(""); } } @@ -226,7 +232,7 @@ private void verifyExpansion(String[][] tests) throws ParseException if (order == NULLORDER || iter.next() != NULLORDER) { iter.reset(); - errln("verifyExpansion: '" + tests[i][0] + + fail("verifyExpansion: '" + tests[i][0] + "' has multiple orders:" + orderString(iter)); } @@ -234,7 +240,7 @@ private void verifyExpansion(String[][] tests) throws ParseException int expect = new Integer(tests[i][1]).intValue(); if (expansion != expect) { - errln("expansion for '" + tests[i][0] + "' is wrong: " + + fail("expansion for '" + tests[i][0] + "' is wrong: " + "expected " + expect + ", got " + expansion); } } diff --git a/test/jdk/java/text/Collator/MonkeyTest.java b/test/jdk/java/text/Collator/MonkeyTest.java index 9539bf5f5ae..5ae343ce150 100644 --- a/test/jdk/java/text/Collator/MonkeyTest.java +++ b/test/jdk/java/text/Collator/MonkeyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,6 +25,7 @@ * @test * @library /java/text/testlib * @summary test Collation, Monkey style + * @run junit MonkeyTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -47,31 +48,32 @@ import java.text.RuleBasedCollator; import java.text.CollationKey; -public class MonkeyTest extends CollatorTest -{ - public static void main(String[] args) throws Exception { - new MonkeyTest().run(args); - } +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class MonkeyTest +{ public void report(String s, String t, int result, int revResult) { if (result == -1) { if (revResult != 1) - errln(" --> Test Failed"); + fail(" --> Test Failed"); } else if (result == 1) { if (revResult != -1) - errln(" --> Test Failed"); + fail(" --> Test Failed"); } else if (result == 0) { if (revResult != 0) - errln(" --> Test Failed"); + fail(" --> Test Failed"); } } + @Test public void TestCollationKey() { String source = "-abcdefghijklmnopqrstuvwxyz#&^$@"; @@ -105,16 +107,17 @@ public void TestCollationKey() CollationKey2 = myCollator.getCollationKey(addOne); result = CollationKey1.compareTo(CollationKey2); if (result != -1) - errln("CollationKey(" + subs + ")" + ".LT." + "CollationKey(" + addOne + ") Failed."); + fail("CollationKey(" + subs + ")" + ".LT." + "CollationKey(" + addOne + ") Failed."); result = CollationKey2.compareTo(CollationKey1); if (result != 1) - errln("CollationKey(" + addOne + ")" + ".GT." + "CollationKey(" + subs + ") Failed."); + fail("CollationKey(" + addOne + ")" + ".GT." + "CollationKey(" + subs + ") Failed."); } private static int checkValue(int value) { value *= (value > 0) ? 1 : -1; return value; } + @Test public void TestCompare() { String source = "-abcdefghijklmnopqrstuvwxyz#&^$@"; @@ -140,10 +143,10 @@ public void TestCompare() String addOne = subs + "\uE000"; result = myCollator.compare(subs, addOne); if (result != -1) - errln("Test : " + subs + " .LT. " + addOne + " Failed."); + fail("Test : " + subs + " .LT. " + addOne + " Failed."); result = myCollator.compare(addOne, subs); if (result != 1) - errln("Test : " + addOne + " .GE. " + subs + " Failed."); + fail("Test : " + addOne + " .GE. " + subs + " Failed."); } private static Collator myCollator = Collator.getInstance(); } diff --git a/test/jdk/java/text/Collator/Regression.java b/test/jdk/java/text/Collator/Regression.java index 6a0af4cccee..5876ede6ecf 100644 --- a/test/jdk/java/text/Collator/Regression.java +++ b/test/jdk/java/text/Collator/Regression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -30,6 +30,7 @@ * @library /java/text/testlib * @summary Regression tests for Collation and associated classes * @modules jdk.localedata + * @run junit Regression */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -47,15 +48,16 @@ import java.util.Locale; import java.util.Vector; +import org.junit.jupiter.api.Test; -public class Regression extends CollatorTest { +import static org.junit.jupiter.api.Assertions.fail; - public static void main(String[] args) throws Exception { - new Regression().run(args); - } + +public class Regression { // CollationElementIterator.reset() doesn't work // + @Test public void Test4048446() { CollationElementIterator i1 = en_us.getCollationElementIterator(test1); CollationElementIterator i2 = en_us.getCollationElementIterator(test1); @@ -64,12 +66,13 @@ public void Test4048446() { } i1.reset(); - assertEqual(i1, i2); + TestUtils.compareCollationElementIters(i1, i2); } // Collator -> rules -> Collator round-trip broken for expanding characters // + @Test public void Test4051866() throws ParseException { // Build a collator containing expanding characters RuleBasedCollator c1 = new RuleBasedCollator("< o " @@ -84,15 +87,16 @@ public void Test4051866() throws ParseException { // Make sure they're the same if (!c1.getRules().equals(c2.getRules())) { - errln("Rules are not equal"); + fail("Rules are not equal"); } } // Collator thinks "black-bird" == "black" // + @Test public void Test4053636() { if (en_us.equals("black-bird","black")) { - errln("black-bird == black"); + fail("black-bird == black"); } } @@ -100,6 +104,7 @@ public void Test4053636() { // CollationElementIterator will not work correctly if the associated // Collator object's mode is changed // + @Test public void Test4054238() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); @@ -111,18 +116,19 @@ public void Test4054238() { // At this point, BOTH iterators should use NO_DECOMPOSITION, since the // collator itself is in that mode - assertEqual(i1, i2); + TestUtils.compareCollationElementIters(i1, i2); } // Collator.IDENTICAL documented but not implemented // + @Test public void Test4054734() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); try { c.setStrength(Collator.IDENTICAL); } catch (Exception e) { - errln("Caught " + e.toString() + " setting Collator.IDENTICAL"); + fail("Caught " + e.toString() + " setting Collator.IDENTICAL"); } String[] decomp = { @@ -143,6 +149,7 @@ public void Test4054734() { // Full Decomposition mode not implemented // + @Test public void Test4054736() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); c.setDecomposition(Collator.FULL_DECOMPOSITION); @@ -156,6 +163,7 @@ public void Test4054736() { // Collator.getInstance() causes an ArrayIndexOutofBoundsException for Korean // + @Test public void Test4058613() { // Creating a default collator doesn't work when Korean is the default // locale @@ -169,7 +177,7 @@ public void Test4058613() { // Since the fix to this bug was to turn of decomposition for Korean collators, // ensure that's what we got if (c.getDecomposition() != Collator.NO_DECOMPOSITION) { - errln("Decomposition is not set to NO_DECOMPOSITION"); + fail("Decomposition is not set to NO_DECOMPOSITION"); } } finally { @@ -180,28 +188,30 @@ public void Test4058613() { // RuleBasedCollator.getRules does not return the exact pattern as input // for expanding character sequences // + @Test public void Test4059820() { RuleBasedCollator c = null; try { c = new RuleBasedCollator("< a < b , c/a < d < z"); } catch (ParseException e) { - errln("Exception building collator: " + e.toString()); + fail("Exception building collator: " + e.toString()); return; } if ( c.getRules().indexOf("c/a") == -1) { - errln("returned rules do not contain 'c/a'"); + fail("returned rules do not contain 'c/a'"); } } // MergeCollation::fixEntry broken for "& H < \u0131, \u0130, i, I" // + @Test public void Test4060154() { RuleBasedCollator c = null; try { c = new RuleBasedCollator("< g, G < h, H < i, I < j, J" + " & H < \u0131, \u0130, i, I" ); } catch (ParseException e) { - errln("Exception building collator: " + e.toString()); + fail("Exception building collator: " + e.toString()); return; } c.setDecomposition(Collator.CANONICAL_DECOMPOSITION); @@ -227,6 +237,7 @@ public void Test4060154() { // Secondary/Tertiary comparison incorrect in French Secondary // + @Test public void Test4062418() throws ParseException { RuleBasedCollator c = (RuleBasedCollator) Collator.getInstance(Locale.FRANCE); c.setStrength(Collator.SECONDARY); @@ -240,9 +251,10 @@ public void Test4062418() throws ParseException { // Collator.compare() method broken if either string contains spaces // + @Test public void Test4065540() { if (en_us.compare("abcd e", "abcd f") == 0) { - errln("'abcd e' == 'abcd f'"); + fail("'abcd e' == 'abcd f'"); } } @@ -250,6 +262,7 @@ public void Test4065540() { // correct result. For example, // u1EB1 -> \u0103 + \u0300 -> a + \u0306 + \u0300. // + @Test public void Test4066189() { String test1 = "\u1EB1"; String test2 = "a\u0306\u0300"; @@ -262,11 +275,12 @@ public void Test4066189() { c2.setDecomposition(Collator.NO_DECOMPOSITION); CollationElementIterator i2 = en_us.getCollationElementIterator(test2); - assertEqual(i1, i2); + TestUtils.compareCollationElementIters(i1, i2); } // French secondary collation checking at the end of compare iteration fails // + @Test public void Test4066696() { RuleBasedCollator c = (RuleBasedCollator) Collator.getInstance(Locale.FRANCE); c.setStrength(Collator.SECONDARY); @@ -281,6 +295,7 @@ public void Test4066696() { // Bad canonicalization of same-class combining characters // + @Test public void Test4076676() { // These combining characters are all in the same class, so they should not // be reordered, and they should compare as unequal. @@ -291,38 +306,41 @@ public void Test4076676() { c.setStrength(Collator.TERTIARY); if (c.compare(s1,s2) == 0) { - errln("Same-class combining chars were reordered"); + fail("Same-class combining chars were reordered"); } } // RuleBasedCollator.equals(null) throws NullPointerException // + @Test public void Test4079231() { try { if (en_us.equals(null)) { - errln("en_us.equals(null) returned true"); + fail("en_us.equals(null) returned true"); } } catch (Exception e) { - errln("en_us.equals(null) threw " + e.toString()); + fail("en_us.equals(null) threw " + e.toString()); } } // RuleBasedCollator breaks on "< a < bb" rule // + @Test public void Test4078588() throws ParseException { RuleBasedCollator rbc=new RuleBasedCollator("< a < bb"); int result = rbc.compare("a","bb"); if (result != -1) { - errln("Compare(a,bb) returned " + result + "; expected -1"); + fail("Compare(a,bb) returned " + result + "; expected -1"); } } // Combining characters in different classes not reordered properly. // + @Test public void Test4081866() throws ParseException { // These combining characters are all in different classes, // so they should be reordered and the strings should compare as equal. @@ -338,12 +356,13 @@ public void Test4081866() throws ParseException { c.setDecomposition(Collator.CANONICAL_DECOMPOSITION); if (c.compare(s1,s2) != 0) { - errln("Combining chars were not reordered"); + fail("Combining chars were not reordered"); } } // string comparison errors in Scandinavian collators // + @Test public void Test4087241() { RuleBasedCollator c = (RuleBasedCollator) Collator.getInstance( Locale.of("da", "DK")); @@ -360,6 +379,7 @@ public void Test4087241() { // CollationKey takes ignorable strings into account when it shouldn't // + @Test public void Test4087243() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); c.setStrength(Collator.TERTIARY); @@ -374,6 +394,7 @@ public void Test4087243() { // Mu/micro conflict // Micro symbol and greek lowercase letter Mu should sort identically // + @Test public void Test4092260() { Collator c = Collator.getInstance(Locale.of("el")); @@ -401,6 +422,7 @@ void Test4095316() { compareArray(c, tests); } + @Test public void Test4101940() { try { RuleBasedCollator c = new RuleBasedCollator("< a < b"); @@ -408,16 +430,17 @@ public void Test4101940() { i.reset(); if (i.next() != i.NULLORDER) { - errln("next did not return NULLORDER"); + fail("next did not return NULLORDER"); } } catch (Exception e) { - errln("Caught " + e ); + fail("Caught " + e ); } } // Collator.compare not handling spaces properly // + @Test public void Test4103436() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); c.setStrength(Collator.TERTIARY); @@ -432,6 +455,7 @@ public void Test4103436() { // Collation not Unicode conformant with Hangul syllables // + @Test public void Test4114076() { RuleBasedCollator c = (RuleBasedCollator) en_us.clone(); c.setStrength(Collator.TERTIARY); @@ -457,18 +481,20 @@ public void Test4114076() { // Collator.getCollationKey was hanging on certain character sequences // + @Test public void Test4124632() throws Exception { Collator coll = Collator.getInstance(Locale.JAPAN); try { coll.getCollationKey("A\u0308bc"); } catch (OutOfMemoryError e) { - errln("Ran out of memory -- probably an infinite loop"); + fail("Ran out of memory -- probably an infinite loop"); } } // sort order of french words with multiple accents has errors // + @Test public void Test4132736() { Collator c = Collator.getInstance(Locale.FRANCE); @@ -481,6 +507,7 @@ public void Test4132736() { // The sorting using java.text.CollationKey is not in the exact order // + @Test public void Test4133509() { String[] test1 = { "Exception", "<", "ExceptionInInitializerError", @@ -492,6 +519,7 @@ public void Test4133509() { // Collation with decomposition off doesn't work for Europe // + @Test public void Test4114077() { // Ensure that we get the same results with decomposition off // as we do with it on.... @@ -519,6 +547,7 @@ public void Test4114077() { // Support for Swedish gone in 1.1.6 (Can't create Swedish collator) // + @Test public void Test4141640() { // // Rather than just creating a Swedish collator, we might as well @@ -531,7 +560,7 @@ public void Test4141640() { try { Collator c = Collator.getInstance(locales[i]); } catch (Exception e) { - errln("Caught " + e + " creating collator for " + locales[i]); + fail("Caught " + e + " creating collator for " + locales[i]); } } } @@ -539,6 +568,7 @@ public void Test4141640() { // getCollationKey throws exception for spanish text // Cannot reproduce this bug on 1.2, however it DOES fail on 1.1.6 // + @Test public void Test4139572() { // // Code pasted straight from the bug report @@ -553,6 +583,7 @@ public void Test4139572() { // RuleBasedCollator doesn't use getCollationElementIterator internally // + @Test public void Test4146160() throws ParseException { // // Use a custom collator class whose getCollationElementIterator @@ -561,13 +592,13 @@ public void Test4146160() throws ParseException { My4146160Collator.count = 0; new My4146160Collator().getCollationKey("1"); if (My4146160Collator.count < 1) { - errln("getCollationElementIterator not called"); + fail("getCollationElementIterator not called"); } My4146160Collator.count = 0; new My4146160Collator().compare("1", "2"); if (My4146160Collator.count < 1) { - errln("getCollationElementIterator not called"); + fail("getCollationElementIterator not called"); } } @@ -592,6 +623,7 @@ public CollationElementIterator getCollationElementIterator( // CollationElementIterator.previous broken for expanding char sequences // + @Test public void Test4179686() throws ParseException { // Create a collator with a few expanding character sequences in it.... @@ -617,7 +649,7 @@ public void Test4179686() throws ParseException { int expect = ((Integer)elements.elementAt(index)).intValue(); if (elem != expect) { - errln("Mismatch at index " + index + fail("Mismatch at index " + index + ": got " + Integer.toString(elem,16) + ", expected " + Integer.toString(expect,16)); } @@ -625,6 +657,7 @@ public void Test4179686() throws ParseException { } } + @Test public void Test4244884() throws ParseException { RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(Locale.US); coll = new RuleBasedCollator(coll.getRules() @@ -644,13 +677,14 @@ public void Test4244884() throws ParseException { for (int i = 1; i < testStrings.length; i++) { if (coll.compare(testStrings[i - 1], testStrings[i]) >= 0) { - errln("error: \"" + testStrings[i - 1] + fail("error: \"" + testStrings[i - 1] + "\" is greater than or equal to \"" + testStrings[i] + "\"."); } } } + @Test public void Test4179216() throws ParseException { // you can position a CollationElementIterator in the middle of // a contracting character sequence, yielding a bogus collation @@ -673,7 +707,7 @@ public void Test4179216() throws ParseException { int elt5 = CollationElementIterator.primaryOrder(iter.next()); if (elt4 != elt0 || elt5 != elt0) - errln("The collation elements at positions 0 (" + elt0 + "), 4 (" + fail("The collation elements at positions 0 (" + elt0 + "), 4 (" + elt4 + "), and 5 (" + elt5 + ") don't match."); // test that the "cat" combination works properly @@ -697,7 +731,7 @@ public void Test4179216() throws ParseException { if (elt14 != elt15 || elt14 != elt16 || elt14 != elt17 || elt14 != elt18 || elt14 != elt19) - errln("\"cat\" elements don't match: elt14 = " + elt14 + ", elt15 = " + fail("\"cat\" elements don't match: elt14 = " + elt14 + ", elt15 = " + elt15 + ", elt16 = " + elt16 + ", elt17 = " + elt17 + ", elt18 = " + elt18 + ", elt19 = " + elt19); @@ -735,14 +769,15 @@ public void Test4179216() throws ParseException { } for (int i = 0; i < nextElements.length; i++) { if (nextElements[i].equals(setOffsetElements[i])) { - logln(nextElements[i]); + System.out.println(nextElements[i]); } else { - errln("Error: next() yielded " + nextElements[i] + ", but setOffset() yielded " + fail("Error: next() yielded " + nextElements[i] + ", but setOffset() yielded " + setOffsetElements[i]); } } } + @Test public void Test4216006() throws Exception { // rule parser barfs on "<\u00e0=a\u0300", and on other cases // where the same token (after normalization) appears twice in a row @@ -769,6 +804,7 @@ public void Test4216006() throws Exception { compareArray(collator, tests); } + @Test public void Test4171974() { // test French accent ordering more thoroughly String[] frenchList = { @@ -800,10 +836,10 @@ public void Test4171974() { }; Collator french = Collator.getInstance(Locale.FRENCH); - logln("Testing French order..."); + System.out.println("Testing French order..."); checkListOrder(frenchList, french); - logln("Testing French order without decomposition..."); + System.out.println("Testing French order without decomposition..."); french.setDecomposition(Collator.NO_DECOMPOSITION); checkListOrder(frenchList, french); @@ -836,10 +872,10 @@ public void Test4171974() { }; Collator english = Collator.getInstance(Locale.ENGLISH); - logln("Testing English order..."); + System.out.println("Testing English order..."); checkListOrder(englishList, english); - logln("Testing English order without decomposition..."); + System.out.println("Testing English order without decomposition..."); english.setDecomposition(Collator.NO_DECOMPOSITION); checkListOrder(englishList, english); } @@ -849,35 +885,36 @@ private void checkListOrder(String[] sortedList, Collator c) { // passed-in list is already sorted into ascending order for (int i = 0; i < sortedList.length - 1; i++) { if (c.compare(sortedList[i], sortedList[i + 1]) >= 0) { - errln("List out of order at element #" + i + ": " - + prettify(sortedList[i]) + " >= " - + prettify(sortedList[i + 1])); + fail("List out of order at element #" + i + ": " + + TestUtils.prettify(sortedList[i]) + " >= " + + TestUtils.prettify(sortedList[i + 1])); } } } // CollationElementIterator set doesn't work propertly with next/prev + @Test public void Test4663220() { RuleBasedCollator collator = (RuleBasedCollator)Collator.getInstance(Locale.US); CharacterIterator stringIter = new StringCharacterIterator("fox"); CollationElementIterator iter = collator.getCollationElementIterator(stringIter); int[] elements_next = new int[3]; - logln("calling next:"); + System.out.println("calling next:"); for (int i = 0; i < 3; ++i) { - logln("[" + i + "] " + (elements_next[i] = iter.next())); + System.out.println("[" + i + "] " + (elements_next[i] = iter.next())); } int[] elements_fwd = new int[3]; - logln("calling set/next:"); + System.out.println("calling set/next:"); for (int i = 0; i < 3; ++i) { iter.setOffset(i); - logln("[" + i + "] " + (elements_fwd[i] = iter.next())); + System.out.println("[" + i + "] " + (elements_fwd[i] = iter.next())); } for (int i = 0; i < 3; ++i) { if (elements_next[i] != elements_fwd[i]) { - errln("mismatch at position " + i + + fail("mismatch at position " + i + ": " + elements_next[i] + " != " + elements_fwd[i]); } @@ -904,8 +941,8 @@ private void compareArray(Collator c, String[] tests) { int result = c.compare(tests[i], tests[i+2]); if (sign(result) != sign(expect)) { - errln( i/3 + ": compare(" + prettify(tests[i]) - + " , " + prettify(tests[i+2]) + fail( i/3 + ": compare(" + TestUtils.prettify(tests[i]) + + " , " + TestUtils.prettify(tests[i+2]) + ") got " + result + "; expected " + expect); } else @@ -916,11 +953,11 @@ private void compareArray(Collator c, String[] tests) { result = k1.compareTo(k2); if (sign(result) != sign(expect)) { - errln( i/3 + ": key(" + prettify(tests[i]) - + ").compareTo(key(" + prettify(tests[i+2]) + fail( i/3 + ": key(" + TestUtils.prettify(tests[i]) + + ").compareTo(key(" + TestUtils.prettify(tests[i+2]) + ")) got " + result + "; expected " + expect); - errln(" " + prettify(k1) + " vs. " + prettify(k2)); + fail(" " + TestUtils.prettifyCKey(k1) + " vs. " + TestUtils.prettifyCKey(k2)); } } } diff --git a/test/jdk/java/text/Collator/SpanishTest.java b/test/jdk/java/text/Collator/SpanishTest.java index 5fb1776e540..3435e6fecb0 100644 --- a/test/jdk/java/text/Collator/SpanishTest.java +++ b/test/jdk/java/text/Collator/SpanishTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,6 +25,7 @@ * @test * @library /java/text/testlib * @summary test Spanish Collation + * @run junit SpanishTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -41,12 +42,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class SpanishTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new SpanishTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class SpanishTest { /* * TestPrimary() @@ -92,13 +93,15 @@ public static void main(String[] args) throws Exception { -1, -1, 1, -1, -1 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); } diff --git a/test/jdk/java/text/Collator/SurrogatesTest.java b/test/jdk/java/text/Collator/SurrogatesTest.java index 87df904e882..3825b31781f 100644 --- a/test/jdk/java/text/Collator/SurrogatesTest.java +++ b/test/jdk/java/text/Collator/SurrogatesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,17 +25,18 @@ * @test * @library /java/text/testlib * @summary test Supplementary Character Collation + * @run junit SurrogatesTest */ import java.text.Collator; import java.text.RuleBasedCollator; -// Quick dummy program for printing out test results -public class SurrogatesTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new SurrogatesTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class SurrogatesTest { /* * Data for TestPrimary() @@ -83,13 +84,15 @@ public static void main(String[] args) throws Exception { -1, 1, 1, 1, -1, -1, -1, -1, 1 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); } @@ -108,7 +111,7 @@ private Collator getCollator() { + "&\ud800\udc0a < x, X" + "&A < \ud800\udc04\ud800\udc05"); } catch (Exception e) { - errln("Failed to create new RulebasedCollator object"); + fail("Failed to create new RulebasedCollator object"); return null; } } diff --git a/test/jdk/java/text/Collator/Test4401726.java b/test/jdk/java/text/Collator/Test4401726.java index 6f9e9ed945e..3c5b1dfe959 100644 --- a/test/jdk/java/text/Collator/Test4401726.java +++ b/test/jdk/java/text/Collator/Test4401726.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -27,6 +27,7 @@ * @author John O'Conner * @library /java/text/testlib * @summary Regression tests for Collation and associated classes + * @run junit Test4401726 */ @@ -34,12 +35,13 @@ import java.util.Locale; import java.util.Vector; -public class Test4401726 extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new Test4401726().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class Test4401726 { + @Test public void TestSetOffSet() { int[] expected = {0, -1, 65536}; @@ -60,7 +62,7 @@ public void TestSetOffSet() { actual[2] = iterator.next(); if (compareArray(expected, actual) == false) { - errln("Failed."); + fail("Failed."); } str = "a"; @@ -72,11 +74,11 @@ public void TestSetOffSet() { actual[2] = iterator.next(); if (compareArray(expected, actual) == false) { - errln("Failed."); + fail("Failed."); } } catch (ParseException e) { - errln("Unexpected ParseException: " + e); + fail("Unexpected ParseException: " + e); } diff --git a/test/jdk/java/text/Collator/ThaiTest.java b/test/jdk/java/text/Collator/ThaiTest.java index cb4d3346186..c11547028e8 100644 --- a/test/jdk/java/text/Collator/ThaiTest.java +++ b/test/jdk/java/text/Collator/ThaiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ * @library /java/text/testlib * @summary test Thai Collation * @modules jdk.localedata + * @run junit ThaiTest */ /* * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. @@ -39,11 +40,11 @@ import java.text.Collator; import java.text.RuleBasedCollator; -public class ThaiTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new ThaiTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class ThaiTest { /* * Data for TestPrimary() @@ -148,8 +149,9 @@ public static void main(String[] args) throws Exception { 0, 0, 0 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } diff --git a/test/jdk/java/text/Collator/TurkishTest.java b/test/jdk/java/text/Collator/TurkishTest.java index cc819c2a6ee..1f65501e50c 100644 --- a/test/jdk/java/text/Collator/TurkishTest.java +++ b/test/jdk/java/text/Collator/TurkishTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ * @library /java/text/testlib * @summary test Turkish Collation * @modules jdk.localedata + * @run junit TurkishTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -42,12 +43,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class TurkishTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new TurkishTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class TurkishTest { /* * Data for TestPrimary() @@ -105,13 +106,15 @@ public static void main(String[] args) throws Exception { -1, -1, -1, -1, 1, -1, -1, 1, -1, -1 }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, primarySourceData, primaryTargetData, primaryResults); } + @Test public void TestTertiary() { - doTest(myCollation, Collator.TERTIARY, + TestUtils.doCollatorTest(myCollation, Collator.TERTIARY, tertiarySourceData, tertiaryTargetData, tertiaryResults); } diff --git a/test/jdk/java/text/Collator/VietnameseTest.java b/test/jdk/java/text/Collator/VietnameseTest.java index 530a86b8a3a..f3b0798b5f3 100644 --- a/test/jdk/java/text/Collator/VietnameseTest.java +++ b/test/jdk/java/text/Collator/VietnameseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -27,6 +27,7 @@ * @library /java/text/testlib * @summary test Vietnamese Collation * @modules jdk.localedata + * @run junit VietnameseTest */ /* @@ -44,12 +45,12 @@ import java.util.Locale; import java.text.Collator; -// Quick dummy program for printing out test results -public class VietnameseTest extends CollatorTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new VietnameseTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +// Quick dummy program for printing out test results +public class VietnameseTest { private final static String testPS[] = { "a", @@ -346,17 +347,19 @@ public static void main(String[] args) throws Exception { "Z" }; + @Test public void TestPrimary() { - doTest(myCollation, Collator.PRIMARY, testPS, testPT, testPR); + TestUtils.doCollatorTest(myCollation, Collator.PRIMARY, testPS, testPT, testPR); } + @Test public void TestTertiary() { int testLength = testT.length; myCollation.setStrength(Collator.TERTIARY); for (int i = 0; i < testLength - 1; i++) { for (int j = i+1; j < testLength; j++) { - doTest(myCollation, testT[i], testT[j], -1); + TestUtils.doCollatorTest(myCollation, testT[i], testT[j], -1); } } } diff --git a/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java b/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java index f7d6bceebf8..51edac17d38 100644 --- a/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java +++ b/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, 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,10 +25,11 @@ * @test * @bug 4185732 * @library /java/text/testlib - * @build Bug4185732Test IntlTest HexDumpReader - * @run main Bug4185732Test - * @summary test that ChoiceFormat invariants are preserved across serialization + * @build Bug4185732Test HexDumpReader + * @run junit Bug4185732Test + * @summary test that ChoiceFormat invariants are preserved across serialization. */ + /* * This file is available under and governed by the GNU General Public * License version 2 only, as published by the Free Software Foundation. @@ -67,54 +68,32 @@ import java.io.*; import java.text.ChoiceFormat; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /** - * A Locale can never contains language codes of he, yi or id. + * A Locale can never contain language codes of he, yi or id. */ -public class Bug4185732Test extends IntlTest { - public static void main(String[] args) throws Exception { - if (args.length == 1 && args[0].equals("prepTest")) { - prepTest(); - } else { - new Bug4185732Test().run(args); - } - } - +public class Bug4185732Test { + @Test public void testIt() throws Exception { try { final ObjectInputStream in = new ObjectInputStream(HexDumpReader.getStreamFromHexDump("Bug4185732.ser.txt")); final ChoiceFormat loc = (ChoiceFormat)in.readObject(); if (loc.getFormats().length != loc.getLimits().length) { - errln("ChoiceFormat did not properly check stream"); + fail("ChoiceFormat did not properly check stream"); } else { //for some reason, the data file was VALID. This test //requires a corrupt data file the format and limit //arrays are of different length. - errln("Test data file was not properly created"); + fail("Test data file was not properly created"); } } catch (InvalidObjectException e) { //this is what we want to have happen } catch (Exception e) { - errln(e.toString()); - } - } - - /** - * Create a data file for this test. The data file must be corrupted by hand. - */ - private static void prepTest() { - try { - ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("Bug4185732.ser")); - final double[] limits = {1,2,3,4,5,6,7}; - final String[] formats = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}; - final ChoiceFormat fmt = new ChoiceFormat(limits, formats); - out.writeObject(fmt); - out.close(); - System.out.println("You must invalidate the output file before running the test"); - System.out.println("by modifying the length of one of the array"); - } catch (Exception e) { - System.out.println(e); + fail(e.toString()); } } } diff --git a/test/jdk/java/text/Format/DateFormat/Bug4322313.java b/test/jdk/java/text/Format/DateFormat/Bug4322313.java index dc64491f293..17a0e53ffb0 100644 --- a/test/jdk/java/text/Format/DateFormat/Bug4322313.java +++ b/test/jdk/java/text/Format/DateFormat/Bug4322313.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -24,17 +24,22 @@ /** * @test * @bug 4322313 4833268 6302990 6304305 - * @library /java/text/testlib * @summary Make sure that new implementation for * SimpleDateFormat.parse('z' or 'Z') and format('z' or 'Z') work correctly. + * @run junit Bug4322313 */ import java.io.*; import java.text.*; import java.util.*; -public class Bug4322313 extends IntlTest { +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class Bug4322313 { + + @Test public void Test4322313() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); @@ -200,7 +205,7 @@ public void Test4322313() { ", got:" + date.getTime() + ", " + date); } else { /* - logln("\tParse Okay [Locale=" + + System.out.println("\tParse Okay [Locale=" + locale) + ", " + formats[j] + "/\"" + valids[k][0] + "\"] expected:" + valids[k][1] + @@ -252,7 +257,7 @@ public void Test4322313() { ", got:" + s + ", " + date); } else { /* - logln("\tFormat Okay [Locale=" + + System.out.println("\tFormat Okay [Locale=" + locale + ", " + formats[j] + "/\"" + valids[k][0] + "\"] expected:" + valids[k][2+j] + @@ -286,7 +291,7 @@ public void Test4322313() { invalids[k][1] + ", got: " + offset); } else { /* - logln("\tParse Okay [Locale=" + + System.out.println("\tParse Okay [Locale=" + locale + ", " + formats[j] + "/\"" + invalids[k][0] + "\"] correct offset: " + offset); @@ -322,7 +327,7 @@ public void Test4322313() { invalids[k][1] + ", got: " + offset); } else { /* - logln("\tParse Okay [Locale=" + + System.out.println("\tParse Okay [Locale=" + locale + ", " + formats[j] + "/\"" + invalids[k][0] + "\"] Expected exception occurred with an correct offset: " @@ -354,12 +359,9 @@ public void Test4322313() { Locale.setDefault(savedLocale); TimeZone.setDefault(savedTimeZone); if (err) { - errln("SimpleDateFormat.parse()/format() test failed"); + fail("SimpleDateFormat.parse()/format() test failed"); } } } - public static void main(String[] args) throws Exception { - new Bug4322313().run(args); - } } diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java index fb92986adf1..a1851908ca9 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java @@ -25,6 +25,10 @@ import java.util.*; import java.io.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /** * @test * @bug 4029195 4052408 4056591 4059917 4060212 4061287 4065240 4071441 4073003 @@ -32,55 +36,53 @@ * 4134203 4138203 4148168 4151631 4151706 4153860 4162071 4182066 4209272 4210209 * 4213086 4250359 4253490 4266432 4406615 4413980 8008577 8305853 * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRegression + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRegression */ -public class DateFormatRegression extends IntlTest { - - public static void main(String[] args) throws Exception { - new DateFormatRegression().run(args); - } +public class DateFormatRegression { + @Test public void Test4029195() { @SuppressWarnings("deprecation") Date today = new Date(); - logln("today: " + today); + System.out.println("today: " + today); SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateInstance(); - logln("pattern: " + sdf.toPattern()); - logln("today: " + sdf.format(today)); + System.out.println("pattern: " + sdf.toPattern()); + System.out.println("today: " + sdf.format(today)); sdf.applyPattern("G yyyy DDD"); String todayS = sdf.format(today); - logln("today: " + todayS); + System.out.println("today: " + todayS); try { today = sdf.parse(todayS); - logln("today date: " + today); + System.out.println("today date: " + today); } catch(Exception e) { - logln("Error reparsing date: " + e.getMessage()); + System.out.println("Error reparsing date: " + e.getMessage()); } try { String rt = sdf.format(sdf.parse(todayS)); - logln("round trip: " + rt); - if (!rt.equals(todayS)) errln("Fail: Want " + todayS + " Got " + rt); + System.out.println("round trip: " + rt); + if (!rt.equals(todayS)) fail("Fail: Want " + todayS + " Got " + rt); } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } + @Test public void Test4052408() { DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.US); @SuppressWarnings("deprecation") Date date = new Date(97, Calendar.MAY, 3, 8, 55); String str; - logln(str = fmt.format(date)); + System.out.println(str = fmt.format(date)); if (!str.equals("5/3/97 8:55 AM")) - errln("Fail: Test broken; Want 5/3/97 8:55 AM Got " + str); + fail("Fail: Test broken; Want 5/3/97 8:55 AM Got " + str); Map expected = new HashMap<>(); expected.put(DateFormat.MONTH_FIELD, "5"); expected.put(DateFormat.DATE_FIELD, "3"); @@ -117,33 +119,34 @@ public void Test4052408() { char[] dst = new char[pos.getEndIndex() - pos.getBeginIndex()]; buf.getChars(pos.getBeginIndex(), pos.getEndIndex(), dst, 0); str = new String(dst); - log(i + ": " + fieldNames[i] + + System.out.println(i + ": " + fieldNames[i] + ", \"" + str + "\", " + pos.getBeginIndex() + ", " + pos.getEndIndex()); String exp = expected.get(i); if ((exp == null && str.length() == 0) || str.equals(exp)) - logln(" ok"); + System.out.println(" ok"); else { - logln(" expected " + exp); + System.out.println(" expected " + exp); pass = false; } } - if (!pass) errln("Fail: FieldPosition not set right by DateFormat"); + if (!pass) fail("Fail: FieldPosition not set right by DateFormat"); } /** * Verify the function of the [s|g]et2DigitYearStart() API. */ @SuppressWarnings("deprecation") + @Test public void Test4056591() { try { SimpleDateFormat fmt = new SimpleDateFormat("yyMMdd", Locale.US); Date start = new Date(1809-1900, Calendar.DECEMBER, 25); fmt.set2DigitYearStart(start); if (!fmt.get2DigitYearStart().equals(start)) - errln("get2DigitYearStart broken"); + fail("get2DigitYearStart broken"); Object[] DATA = { "091225", new Date(1809-1900, Calendar.DECEMBER, 25), "091224", new Date(1909-1900, Calendar.DECEMBER, 24), @@ -154,20 +157,21 @@ public void Test4056591() { String s = (String) DATA[i]; Date exp = (Date) DATA[i+1]; Date got = fmt.parse(s); - logln(s + " -> " + got + "; exp " + exp); - if (!got.equals(exp)) errln("set2DigitYearStart broken"); + System.out.println(s + " -> " + got + "; exp " + exp); + if (!got.equals(exp)) fail("set2DigitYearStart broken"); } } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } + @Test public void Test4059917() { Locale locale = Locale.getDefault(); if (!TestUtils.usesAsciiDigits(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -185,54 +189,55 @@ public void Test4059917() { void aux917( SimpleDateFormat fmt, String str ) { try { - logln( "==================" ); - logln( "testIt: pattern=" + fmt.toPattern() + + System.out.println( "==================" ); + System.out.println( "testIt: pattern=" + fmt.toPattern() + " string=" + str ); Object o; o = fmt.parseObject( str ); - logln( "Parsed object: " + o ); + System.out.println( "Parsed object: " + o ); String formatted = fmt.format( o ); - logln( "Formatted string: " + formatted ); - if (!formatted.equals(str)) errln("Fail: Want " + str + " Got " + formatted); + System.out.println( "Formatted string: " + formatted ); + if (!formatted.equals(str)) fail("Fail: Want " + str + " Got " + formatted); } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } + @Test public void Test4060212() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); try { String dateString = "1995-040.05:01:29"; - logln( "dateString= " + dateString ); - logln("Using yyyy-DDD.hh:mm:ss"); + System.out.println( "dateString= " + dateString ); + System.out.println("Using yyyy-DDD.hh:mm:ss"); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-DDD.hh:mm:ss"); ParsePosition pos = new ParsePosition(0); Date myDate = formatter.parse( dateString, pos ); String myString = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.LONG).format( myDate ); - logln( myString ); + System.out.println( myString ); Calendar cal = new GregorianCalendar(); cal.setTime(myDate); if (cal.get(Calendar.DAY_OF_YEAR) != 40) - errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + + fail("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + " Want 40"); - logln("Using yyyy-ddd.hh:mm:ss"); + System.out.println("Using yyyy-ddd.hh:mm:ss"); formatter = new SimpleDateFormat("yyyy-ddd.hh:mm:ss"); pos = new ParsePosition(0); myDate = formatter.parse( dateString, pos ); myString = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.LONG).format( myDate ); - logln( myString ); + System.out.println( myString ); cal.setTime(myDate); if (cal.get(Calendar.DAY_OF_YEAR) != 40) - errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + + fail("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + " Want 40"); } finally { @@ -240,24 +245,26 @@ public void Test4060212() { } } + @Test public void Test4061287() { SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy"); try { - logln(df.parse("35/01/1971").toString()); + System.out.println(df.parse("35/01/1971").toString()); } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } df.setLenient(false); boolean ok = false; try { - logln(df.parse("35/01/1971").toString()); + System.out.println(df.parse("35/01/1971").toString()); } catch (ParseException e) {ok=true;} - if (!ok) errln("Fail: Lenient not working"); + if (!ok) fail("Fail: Lenient not working"); } @SuppressWarnings("deprecation") + @Test public void Test4065240() { Date curDate; DateFormat shortdate, fulldate; @@ -276,13 +283,13 @@ public void Test4065240() { format(curDate)); strFullDate = new String("The current date (long form) is " + fulldate.format(curDate)); - logln(strShortDate); - logln(strFullDate); + System.out.println(strShortDate); + System.out.println(strFullDate); // UPDATE THIS AS ZONE NAME RESOURCE FOR in de_DE is updated if (!strFullDate.endsWith("EST") && !strFullDate.endsWith("GMT-05:00")) { - errln("Fail: Want GMT-05:00"); + fail("Fail: Want GMT-05:00"); } } finally { @@ -301,6 +308,7 @@ public void Test4065240() { Currently this bug breaks MessageFormat.toPattern */ @SuppressWarnings("deprecation") + @Test public void Test4071441() { DateFormat fmtA = DateFormat.getInstance(); DateFormat fmtB = DateFormat.getInstance(); @@ -311,15 +319,15 @@ public void Test4071441() { calA.setTime(epoch); calB.setTime(epoch); if (!calA.equals(calB)) - errln("Fail: Can't complete test; Calendar instances unequal"); + fail("Fail: Can't complete test; Calendar instances unequal"); if (!fmtA.equals(fmtB)) - errln("Fail: DateFormat unequal when Calendars equal"); + fail("Fail: DateFormat unequal when Calendars equal"); calB.setTime(xmas); if (calA.equals(calB)) - errln("Fail: Can't complete test; Calendar instances equal"); + fail("Fail: Can't complete test; Calendar instances equal"); if (!fmtA.equals(fmtB)) - errln("Fail: DateFormat unequal when Calendars equivalent"); - logln("DateFormat.equals ok"); + fail("Fail: DateFormat unequal when Calendars equivalent"); + System.out.println("DateFormat.equals ok"); } /* The java.text.DateFormat.parse(String) method expects for the @@ -332,6 +340,7 @@ public void Test4071441() { Please extend the parsing method(s) to handle strings with four-digit year values (probably also applicable to various other locales. */ + @Test public void Test4073003() { try { DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); @@ -342,18 +351,19 @@ public void Test4073003() { String s = fmt.format(d); String ss = fmt.format(dd); if (!d.equals(dd)) - errln("Fail: " + d + " != " + dd); + fail("Fail: " + d + " != " + dd); if (!s.equals(ss)) - errln("Fail: " + s + " != " + ss); - logln("Ok: " + s + " " + d); + fail("Fail: " + s + " != " + ss); + System.out.println("Ok: " + s + " " + d); } } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } + @Test public void Test4089106() { TimeZone def = TimeZone.getDefault(); try { @@ -361,13 +371,14 @@ public void Test4089106() { TimeZone.setDefault(customTz); SimpleDateFormat f = new SimpleDateFormat(); if (!f.getTimeZone().equals(customTz)) - errln("Fail: SimpleDateFormat should use TimeZone.getDefault()"); + fail("Fail: SimpleDateFormat should use TimeZone.getDefault()"); } finally { TimeZone.setDefault(def); } } + @Test public void Test4100302() { Locale[] locales = new Locale[] { Locale.CANADA, @@ -414,21 +425,21 @@ public void Test4100302() { if (!format.equals(ois.readObject())) { pass = false; - logln("DateFormat instance for locale " + + System.out.println("DateFormat instance for locale " + locales[i] + " is incorrectly serialized/deserialized."); } else { - logln("DateFormat instance for locale " + + System.out.println("DateFormat instance for locale " + locales[i] + " is OKAY."); } } - if (!pass) errln("Fail: DateFormat serialization/equality bug"); + if (!pass) fail("Fail: DateFormat serialization/equality bug"); } catch (IOException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } catch (ClassNotFoundException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } @@ -437,6 +448,7 @@ public void Test4100302() { * Test whether DataFormat can be serialized/deserialized correctly * even if invalid/customized TimeZone is used. */ + @Test public void Test4413980() { TimeZone savedTimeZone = TimeZone.getDefault(); try { @@ -465,23 +477,23 @@ public void Test4413980() { if (!format.equals(ois.readObject())) { pass = false; - logln("DateFormat instance which uses TimeZone <" + + System.out.println("DateFormat instance which uses TimeZone <" + IDs[i] + "> is incorrectly serialized/deserialized."); } else { - logln("DateFormat instance which uses TimeZone <" + + System.out.println("DateFormat instance which uses TimeZone <" + IDs[i] + "> is correctly serialized/deserialized."); } } if (!pass) { - errln("Fail: DateFormat serialization/equality bug"); + fail("Fail: DateFormat serialization/equality bug"); } } catch (IOException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } catch (ClassNotFoundException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } finally { @@ -489,17 +501,18 @@ public void Test4413980() { } } + @Test public void Test4101483() { SimpleDateFormat sdf = new SimpleDateFormat("z", Locale.US); FieldPosition fp = new FieldPosition(DateFormat.TIMEZONE_FIELD); @SuppressWarnings("deprecation") Date d= new Date(9234567890L); StringBuffer buf = new StringBuffer(""); - logln(sdf.format(d, buf, fp).toString()); - logln(d + " => " + buf); - logln("beginIndex = " + fp.getBeginIndex()); - logln("endIndex = " + fp.getEndIndex()); - if (fp.getBeginIndex() == fp.getEndIndex()) errln("Fail: Empty field"); + System.out.println(sdf.format(d, buf, fp).toString()); + System.out.println(d + " => " + buf); + System.out.println("beginIndex = " + fp.getBeginIndex()); + System.out.println("endIndex = " + fp.getEndIndex()); + if (fp.getBeginIndex() == fp.getEndIndex()) fail("Fail: Empty field"); } /** @@ -510,6 +523,7 @@ public void Test4101483() { * NT; it would actually have failed on any non-US locale. Now it should * work on all locales. */ + @Test public void Test4103340() { // choose a date that is the FIRST of some month // and some arbitrary time @@ -519,30 +533,32 @@ public void Test4103340() { String s = d.toString(); String s2 = df.format(d); - logln("Date="+s); - logln("DF="+s2); + System.out.println("Date="+s); + System.out.println("DF="+s2); if (s.indexOf(s2.substring(0,2)) == -1) - errln("Months should match"); + fail("Months should match"); } + @Test public void Test4103341() { TimeZone saveZone =TimeZone.getDefault(); try { TimeZone.setDefault(TimeZone.getTimeZone("CST")); SimpleDateFormat simple = new SimpleDateFormat("MM/dd/yyyy HH:mm"); if (!simple.getTimeZone().equals(TimeZone.getDefault())) - errln("Fail: SimpleDateFormat not using default zone"); + fail("Fail: SimpleDateFormat not using default zone"); } finally { TimeZone.setDefault(saveZone); } } + @Test public void Test4104136() { SimpleDateFormat sdf = new SimpleDateFormat(); String pattern = "'time' hh:mm"; sdf.applyPattern(pattern); - logln("pattern: \"" + pattern + "\""); + System.out.println("pattern: \"" + pattern + "\""); @SuppressWarnings("deprecation") Object[] DATA = { @@ -557,14 +573,14 @@ public void Test4104136() { ParsePosition pos = new ParsePosition(0); Date d = sdf.parse(text, pos); - logln(" text: \"" + text + "\""); - logln(" index: " + pos.getIndex()); - logln(" result: " + d); + System.out.println(" text: \"" + text + "\""); + System.out.println(" index: " + pos.getIndex()); + System.out.println(" result: " + d); if (pos.getIndex() != finish.getIndex()) - errln("Fail: Expected pos " + finish.getIndex()); + fail("Fail: Expected pos " + finish.getIndex()); if (!((d == null && exp == null) || d.equals(exp))) - errln("Fail: Expected result " + exp); + fail("Fail: Expected result " + exp); } } @@ -574,27 +590,29 @@ public void Test4104136() { * StringIndexOutOfBoundsException during the second parse. However, * this is not seen. */ + @Test public void Test4104522() { SimpleDateFormat sdf = new SimpleDateFormat(); String pattern = "'time' hh:mm"; sdf.applyPattern(pattern); - logln("pattern: \"" + pattern + "\""); + System.out.println("pattern: \"" + pattern + "\""); // works correctly ParsePosition pp = new ParsePosition(0); String text = "time "; Date date = sdf.parse(text, pp); - logln(" text: \"" + text + "\"" + + System.out.println(" text: \"" + text + "\"" + " date: " + date); // works wrong pp = new ParsePosition(0); text = "time"; date = sdf.parse(text, pp); - logln(" text: \"" + text + "\"" + + System.out.println(" text: \"" + text + "\"" + " date: " + date); } + @Test public void Test4106807() { Date date; DateFormat df = DateFormat.getDateTimeInstance(); @@ -618,13 +636,13 @@ public void Test4106807() { try { format.setTimeZone(gmt); date = format.parse(dateString); - logln(df.format(date)); + System.out.println(df.format(date)); gc.setTime(date); - logln("" + gc.get(Calendar.ZONE_OFFSET)); - logln(format.format(date)); + System.out.println("" + gc.get(Calendar.ZONE_OFFSET)); + System.out.println(format.format(date)); } catch (ParseException e) { - logln("No way Jose"); + System.out.println("No way Jose"); } } } @@ -632,12 +650,13 @@ public void Test4106807() { /** * SimpleDateFormat won't parse "GMT" */ + @Test public void Test4134203() { String dateFormat = "MM/dd/yy HH:mm:ss zzz"; SimpleDateFormat fmt = new SimpleDateFormat(dateFormat); ParsePosition p0 = new ParsePosition(0); Date d = fmt.parse("01/22/92 04:52:00 GMT", p0); - logln(d.toString()); + System.out.println(d.toString()); // In the failure case an exception is thrown by parse(); // if no exception is thrown, the test passes. } @@ -645,12 +664,13 @@ public void Test4134203() { /** * Another format for GMT string parse */ + @Test public void Test4266432() { String dateFormat = "MM/dd HH:mm:ss zzz yyyy"; SimpleDateFormat fmt = new SimpleDateFormat(dateFormat); ParsePosition p0 = new ParsePosition(0); Date d = fmt.parse("01/22 04:52:00 GMT 1992", p0); - logln(d.toString()); + System.out.println(d.toString()); // In the failure case an exception is thrown by parse(); // if no exception is thrown, the test passes. } @@ -662,6 +682,7 @@ public void Test4266432() { * NOTE: Updated for fixed semantics as of Kestrel. See * 4253490 */ + @Test public void Test4148168() throws ParseException { SimpleDateFormat fmt = new SimpleDateFormat("", Locale.US); int ms = 456; @@ -677,7 +698,7 @@ public void Test4148168() throws ParseException { fmt.applyPattern(PAT[i]); String str = fmt.format(d); if (!str.equals(OUT[i])) { - errln("FAIL: " + ms + " ms x \"" + PAT[i] + "\" -> \"" + + fail("FAIL: " + ms + " ms x \"" + PAT[i] + "\" -> \"" + str + "\", exp \"" + OUT[i] + '"'); } } @@ -692,7 +713,7 @@ public void Test4148168() throws ParseException { cal.setTime(d); ms = cal.get(Calendar.MILLISECOND); if (ms != MS[i]) { - errln("FAIL: parse(\"" + IN[i] + "\" x \"s.S\") -> " + + fail("FAIL: parse(\"" + IN[i] + "\" x \"s.S\") -> " + ms + " ms, exp " + MS[i] + " ms"); } } @@ -701,17 +722,18 @@ public void Test4148168() throws ParseException { /** * SimpleDateFormat incorrect handling of 2 single quotes in format() */ + @Test public void Test4151631() { String pattern = "'TO_DATE('''dd'-'MM'-'yyyy HH:mm:ss''' , ''DD-MM-YYYY HH:MI:SS'')'"; - logln("pattern=" + pattern); + System.out.println("pattern=" + pattern); SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US); @SuppressWarnings("deprecation") String result = format.format(new Date(1998-1900, Calendar.JUNE, 30, 13, 30, 0)); if (!result.equals("TO_DATE('30-06-1998 13:30:00' , 'DD-MM-YYYY HH:MI:SS')")) { - errln("Fail: result=" + result); + fail("Fail: result=" + result); } else { - logln("Pass: result=" + result); + System.out.println("Pass: result=" + result); } } @@ -720,15 +742,16 @@ public void Test4151631() { * CANNOT REPRODUCE THIS BUG ON 1.2FCS */ @SuppressWarnings("deprecation") + @Test public void Test4151706() { SimpleDateFormat fmt = new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss z", Locale.US); try { Date d = fmt.parse("Thursday, 31-Dec-98 23:00:00 GMT"); if (d.getTime() != Date.UTC(1998-1900, Calendar.DECEMBER, 31, 23, 0, 0)) - errln("Incorrect value: " + d); + fail("Incorrect value: " + d); } catch (Exception e) { - errln("Fail: " + e); + fail("Fail: " + e); } } @@ -737,6 +760,7 @@ public void Test4151706() { * This is actually a bug down in GregorianCalendar, but it was reported * as follows... */ + @Test public void Test4153860() throws ParseException { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -751,7 +775,7 @@ public void Test4153860() throws ParseException { // Try to create a Date for February 4th Date d2 = sf.parse("1998.02-04 1"); if (!d1.equals(d2)) { - errln("Parse failed, got " + d2 + + fail("Parse failed, got " + d2 + ", expected " + d1); } } @@ -765,6 +789,7 @@ public void Test4153860() throws ParseException { * as "EST" or "CST", not Australian "EST" and "CST". */ @SuppressWarnings("deprecation") + @Test public void Test4406615() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); @@ -784,13 +809,13 @@ public void Test4406615() { d1.getDate() != 31 || d1.getHours() != 21 || d1.getMinutes() != 0 || d2.getYear() != (2000-1900) || d2.getMonth() != 11 || d2.getDate() != 31 || d2.getHours() != 22 || d2.getMinutes() != 0) { - errln("Parse failed, d1 = " + d1 + ", d2 = " + d2); + fail("Parse failed, d1 = " + d1 + ", d2 = " + d2); } else { - logln("Parse passed"); + System.out.println("Parse passed"); } } catch (Exception e) { - errln("Parse failed, got Exception " + e); + fail("Parse failed, got Exception " + e); } finally { Locale.setDefault(savedLocale); @@ -802,6 +827,7 @@ public void Test4406615() { * Cannot reproduce this bug under 1.2 FCS -- it may be a convoluted duplicate * of some other bug that has been fixed. */ + @Test public void Test4162071() { String dateString = "Thu, 30-Jul-1999 11:51:14 GMT"; String format = "EEE', 'dd-MMM-yyyy HH:mm:ss z"; // RFC 822/1123 @@ -810,16 +836,17 @@ public void Test4162071() { try { Date x = df.parse(dateString); - logln("Parse format \"" + format + "\" ok"); - logln(dateString + " -> " + df.format(x)); + System.out.println("Parse format \"" + format + "\" ok"); + System.out.println(dateString + " -> " + df.format(x)); } catch (Exception e) { - errln("Parse format \"" + format + "\" failed."); + fail("Parse format \"" + format + "\" failed."); } } /** * DateFormat shouldn't parse year "-1" as a two-digit year (e.g., "-1" -> 1999). */ + @Test public void Test4182066() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -869,9 +896,9 @@ public void Test4182066() { } } if (pass) { - log(out.toString()); + System.out.println(out.toString()); } else { - err(out.toString()); + fail(out.toString()); } } finally { @@ -884,6 +911,7 @@ public void Test4182066() { * Bug 4209272 * DateFormat cannot parse Feb 29 2000 when setLenient(false) */ + @Test public void Test4210209() { String pattern = "MMM d, yyyy"; DateFormat fmt = new SimpleDateFormat(pattern, @@ -892,13 +920,13 @@ public void Test4210209() { @SuppressWarnings("deprecation") Date d = new Date(2000-1900, Calendar.FEBRUARY, 29); String s = fmt.format(d); - logln(d + " x " + pattern + " => " + s); + System.out.println(d + " x " + pattern + " => " + s); ParsePosition pos = new ParsePosition(0); d = fmt.parse(s, pos); - logln(d + " <= " + pattern + " x " + s); - logln("Parse pos = " + pos); + System.out.println(d + " <= " + pattern + " x " + s); + System.out.println("Parse pos = " + pos); if (pos.getErrorIndex() != -1) { - errln("FAIL"); + fail("FAIL"); } // The underlying bug is in GregorianCalendar. If the following lines @@ -908,12 +936,13 @@ public void Test4210209() { cal.clear(); cal.setLenient(false); cal.set(2000, Calendar.FEBRUARY, 29); // This should work! - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); } /** * DateFormat.getDateTimeInstance() allows illegal parameters. */ + @Test public void Test4213086() { int[] DATA = { // Style value, 0/1 for illegal/legal @@ -962,7 +991,7 @@ public void Test4213086() { e = ex; } if (got != DATA[i+1] || e != null) { - errln("FAIL: DateFormat." + DESC[j] + " style " + DATA[i] + " " + + fail("FAIL: DateFormat." + DESC[j] + " style " + DATA[i] + " " + (e != null ? e.toString() : GOT[got])); } } @@ -970,6 +999,7 @@ public void Test4213086() { } @SuppressWarnings("deprecation") + @Test public void Test4253490() throws ParseException { SimpleDateFormat fmt = new SimpleDateFormat("S", Locale.US); @@ -993,10 +1023,10 @@ public void Test4253490() throws ParseException { fmt.applyPattern(FORMAT_PAT[i]); String s = fmt.format(d); if (s.equals(FORMAT_TO[i])) { - logln(String.valueOf(FORMAT_MS) + " ms f* \"" + + System.out.println(String.valueOf(FORMAT_MS) + " ms f* \"" + FORMAT_PAT[i] + "\" -> \"" + s + '"'); } else { - errln("FAIL: " + FORMAT_MS + " ms f* \"" + + fail("FAIL: " + FORMAT_MS + " ms f* \"" + FORMAT_PAT[i] + "\" -> \"" + s + "\", expect \"" + FORMAT_TO[i] + '"'); } @@ -1008,10 +1038,10 @@ public void Test4253490() throws ParseException { cal.setTime(fmt.parse(PARSE_STR[i])); int ms = cal.get(Calendar.MILLISECOND); if (ms == PARSE_TO[i]) { - logln("\"" + PARSE_STR[i] + "\" p* \"" + + System.out.println("\"" + PARSE_STR[i] + "\" p* \"" + PARSE_PAT + "\" -> " + ms + " ms"); } else { - errln("FAIL: \"" + PARSE_STR[i] + "\" p* \"" + + fail("FAIL: \"" + PARSE_STR[i] + "\" p* \"" + PARSE_PAT + "\" -> " + ms + " ms, expect " + PARSE_TO[i] + " ms"); } @@ -1023,10 +1053,10 @@ public void Test4253490() throws ParseException { cal.setTime(fmt.parse(PARSE_STR[i])); int ms = cal.get(Calendar.MILLISECOND); if (ms == PARSE_TO[i]) { - logln("\"" + PARSE_STR[i] + "\" p* \"" + + System.out.println("\"" + PARSE_STR[i] + "\" p* \"" + PARSE_LPAT + "\" -> " + ms + " ms"); } else { - errln("FAIL: \"" + PARSE_STR[i] + "\" p* \"" + + fail("FAIL: \"" + PARSE_STR[i] + "\" p* \"" + PARSE_LPAT + "\" -> " + ms + " ms, expect " + PARSE_TO[i] + " ms"); } @@ -1036,6 +1066,7 @@ public void Test4253490() throws ParseException { /** * Bug in handling of time instance; introduces in fix for 4213086. */ + @Test public void Test4250359() { DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US); @@ -1048,7 +1079,7 @@ public void Test4250359() { int i = s.indexOf("AM"); int j = s.indexOf("AM", i+1); if (i < 0 || j >= 0) { - errln("FAIL: getTimeInstance().format(d) => \"" + + fail("FAIL: getTimeInstance().format(d) => \"" + s + "\""); } } @@ -1057,6 +1088,7 @@ public void Test4250359() { * Test whether SimpleDataFormat (DateFormatSymbols) can format/parse * non-localized time zones. */ + @Test public void Test4261506() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); @@ -1068,22 +1100,22 @@ public void Test4261506() { SimpleDateFormat fmt = new SimpleDateFormat("yy/MM/dd hh:ss zzz", Locale.JAPAN); @SuppressWarnings("deprecation") String result = fmt.format(new Date(1999 - 1900, 0, 1)); - logln("format()=>" + result); + System.out.println("format()=>" + result); if (!result.endsWith("PST")) { - errln("FAIL: SimpleDataFormat.format() did not retrun PST"); + fail("FAIL: SimpleDataFormat.format() did not retrun PST"); } Date d = null; try { d = fmt.parse("99/1/1 10:10 PST"); } catch (ParseException e) { - errln("FAIL: SimpleDataFormat.parse() could not parse PST"); + fail("FAIL: SimpleDataFormat.parse() could not parse PST"); } result = fmt.format(d); - logln("roundtrip:" + result); + System.out.println("roundtrip:" + result); if (!result.equals("99/01/01 10:10 PST")) { - errln("FAIL: SimpleDataFomat timezone roundtrip failed"); + fail("FAIL: SimpleDataFomat timezone roundtrip failed"); } Locale.setDefault(savedLocale); diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java b/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java index 0be2732eba6..c3f86cf0fcd 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,14 +25,13 @@ * @test * @summary test Date Format (Round Trip) * @bug 8008577 - * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRoundTripTest + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRoundTripTest */ import java.text.*; import java.util.*; -public class DateFormatRoundTripTest extends IntlTest { +public class DateFormatRoundTripTest { static Random RANDOM = null; @@ -107,15 +106,15 @@ public static void main(String[] args) throws Exception { List newArgs = new ArrayList<>(); for (int i=0; i Random using as seed."); - super.usage(); } static private class TestCase { @@ -310,8 +309,8 @@ private interface FormatFactory { public void TestDateFormatRoundTrip() { avail = DateFormat.getAvailableLocales(); - logln("DateFormat available locales: " + avail.length); - logln("Default TimeZone: " + + System.out.println("DateFormat available locales: " + avail.length); + System.out.println("Default TimeZone: " + (defaultZone = TimeZone.getDefault()).getID()); if (random || initialDate != null) { @@ -333,7 +332,7 @@ public void TestDateFormatRoundTrip() { * TimeZone must be set to tc.zone before this method is called. */ private void doTestInZone(TestCase tc) { - logln(escape(tc.toString())); + System.out.println(escape(tc.toString())); Locale save = Locale.getDefault(); try { if (locale != null) { @@ -368,10 +367,10 @@ private void loopedTest() { if (INFINITE) { // Special infinite loop test mode for finding hard to reproduce errors if (locale != null) { - logln("ENTERING INFINITE TEST LOOP, LOCALE " + locale.getDisplayName()); + System.out.println("ENTERING INFINITE TEST LOOP, LOCALE " + locale.getDisplayName()); for (;;) doTest(locale); } else { - logln("ENTERING INFINITE TEST LOOP, ALL LOCALES"); + System.out.println("ENTERING INFINITE TEST LOOP, ALL LOCALES"); for (;;) { for (int i=0; i0&&d[j].getTime()==d[j-1].getTime()?" d==":"") + (j>0&&s[j].equals(s[j-1])?" s==":"")); } - errln(escape(out.toString())); + throw new RuntimeException(escape(out.toString())); } } } catch (ParseException e) { - errln(e.toString()); + throw new RuntimeException(e.toString()); } } diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatTest.java b/test/jdk/java/text/Format/DateFormat/DateFormatTest.java index f71204cc7d7..5f02c12e80d 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatTest.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,30 +26,31 @@ * @bug 4052223 4089987 4469904 4326988 4486735 8008577 8045998 8140571 * 8190748 8216969 * @summary test DateFormat and SimpleDateFormat. - * @library /java/text/testlib * @modules jdk.localedata - * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatTest + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI DateFormatTest */ import java.util.*; import java.text.*; import static java.util.GregorianCalendar.*; -public class DateFormatTest extends IntlTest +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; + +import static org.junit.jupiter.api.Assertions.fail; + +public class DateFormatTest { - public static void main(String[] args) throws Exception { - Locale reservedLocale = Locale.getDefault(); - try { - Locale.setDefault(Locale.US); - new DateFormatTest().run(args); - } finally { - // restore the reserved locale - Locale.setDefault(reservedLocale); - } + + // Change JVM default Locale + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); } // Test 4 digit year parsing with pattern "yy" @SuppressWarnings("deprecation") + @Test public void TestYearParsing() { String str = "7/Sep/2001"; @@ -58,17 +59,18 @@ public void TestYearParsing() SimpleDateFormat sdf = new SimpleDateFormat(pat, Locale.US); try { Date d = sdf.parse(str); - logln(str + " parses with " + pat + " to " + d); + System.out.println(str + " parses with " + pat + " to " + d); if (d.getTime() != exp.getTime()) { - errln("FAIL: Expected " + exp); + fail("FAIL: Expected " + exp); } } catch (ParseException e) { - errln(str + " parse fails with " + pat); + fail(str + " parse fails with " + pat); } } // Test written by Wally Wedel and emailed to me. + @Test public void TestWallyWedel() { /* @@ -91,11 +93,11 @@ public void TestWallyWedel() /* * How many ids do we have? */ - logln("Time Zone IDs size: " + ids.length); + System.out.println("Time Zone IDs size: " + ids.length); /* * Column headings (sort of) */ - logln("Ordinal ID offset(h:m) name"); + System.out.println("Ordinal ID offset(h:m) name"); /* * Loop through the tzs. */ @@ -136,19 +138,20 @@ public void TestWallyWedel() boolean ok = fmtDstOffset == null || fmtDstOffset.equals(dstOffset); if (ok) { - logln(i + " " + ids[i] + " " + dstOffset + + System.out.println(i + " " + ids[i] + " " + dstOffset + " " + fmtOffset + (fmtDstOffset != null ? " ok" : " ?")); } else { - errln(i + " " + ids[i] + " " + dstOffset + + fail(i + " " + ids[i] + " " + dstOffset + " " + fmtOffset + " *** FAIL ***"); } } } // Test equals + @Test public void TestEquals() { DateFormat fmtA = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); @@ -156,12 +159,13 @@ public void TestEquals() DateFormat fmtB = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); if (!fmtA.equals(fmtB)) { - errln("FAIL"); + fail("FAIL"); } } // Check out some specific parsing problem @SuppressWarnings("deprecation") + @Test public void TestTwoDigitYearDSTParse() { SimpleDateFormat fullFmt = @@ -181,12 +185,12 @@ public void TestTwoDigitYearDSTParse() try { TimeZone.setDefault(PST); Date d = fmt.parse(s); - logln(s + " P> " + fullFmt.format(d)); + System.out.println(s + " P> " + fullFmt.format(d)); if (d.getHours() != hour) { - errln("FAIL: Should parse to hour " + hour); + fail("FAIL: Should parse to hour " + hour); } } - catch (ParseException e) { errln("FAIL: " + e.getMessage()); } + catch (ParseException e) { fail("FAIL: " + e.getMessage()); } finally { TimeZone.setDefault(save); } @@ -234,6 +238,7 @@ static String escape(String s) /** * Bug 4089987 */ + @Test public void TestFieldPosition() { DateFormat[] dateFormats = { @@ -273,13 +278,13 @@ public void TestFieldPosition() continue; } df.setTimeZone(PST); - logln(" Pattern = " + ((SimpleDateFormat)df).toPattern()); - logln(" Result = " + df.format(someDate)); + System.out.println(" Pattern = " + ((SimpleDateFormat)df).toPattern()); + System.out.println(" Result = " + df.format(someDate)); for (int i = 0; i < fieldIDs.length; ++i) { String field = getFieldText(df, fieldIDs[i], someDate); if (!field.equals(expected[exp])) { - errln("FAIL: field #" + i + " " + fieldNames[i] + " = \"" + + fail("FAIL: field #" + i + " " + fieldNames[i] + " = \"" + escape(field) + "\", expected \"" + escape(expected[exp]) + "\""); } ++exp; @@ -298,6 +303,7 @@ static String getFieldText(DateFormat df, int field, Date date) // Test parsing of partial strings @SuppressWarnings("deprecation") + @Test public void TestPartialParse994() { SimpleDateFormat f = new SimpleDateFormat(); @@ -312,34 +318,35 @@ public void TestPartialParse994() void tryPat994(SimpleDateFormat format, String pat, String str, Date expected) { - logln("Pattern \"" + pat + "\" String \"" + str + "\""); + System.out.println("Pattern \"" + pat + "\" String \"" + str + "\""); try { format.applyPattern(pat); Date date = format.parse(str); String f = format.format(date); - logln(" parse(" + str + ") -> " + date.toString()); - logln(" format -> " + f); + System.out.println(" parse(" + str + ") -> " + date.toString()); + System.out.println(" format -> " + f); if (expected == null || !date.equals(expected)) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } if (!f.equals(str)) { - errln("FAIL: Expected " + str); + fail("FAIL: Expected " + str); } } catch(ParseException e) { - logln("ParseException: " + e.getMessage()); + System.out.println("ParseException: " + e.getMessage()); if (expected != null) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } } catch(Exception e) { - errln("*** Exception:"); + fail("*** Exception:"); e.printStackTrace(); } } // Test pattern with runs things together + @Test public void TestRunTogetherPattern985() { String format = "yyyyMMddHHmmssSSSzzzz"; @@ -350,7 +357,7 @@ public void TestRunTogetherPattern985() Date date1 = new Date(); now = formatter.format(date1); - logln(now); + System.out.println(now); ParsePosition pos = new ParsePosition(0); @@ -361,15 +368,16 @@ public void TestRunTogetherPattern985() then = formatter.format(date2); } - logln(then); + System.out.println(then); if (!date2.equals(date1)) { - errln("FAIL"); + fail("FAIL"); } } // Test patterns which run numbers together @SuppressWarnings("deprecation") + @Test public void TestRunTogetherPattern917() { SimpleDateFormat fmt; @@ -386,7 +394,7 @@ public void TestRunTogetherPattern917() } void _testIt917( SimpleDateFormat fmt, String str, Date expected ) { - logln( "pattern=" + fmt.toPattern() + " string=" + str ); + System.out.println( "pattern=" + fmt.toPattern() + " string=" + str ); Object o; try { @@ -395,27 +403,28 @@ void _testIt917( SimpleDateFormat fmt, String str, Date expected ) e.printStackTrace(); return; } - logln( "Parsed object: " + o ); + System.out.println( "Parsed object: " + o ); if (!o.equals(expected)) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } String formatted = fmt.format( o ); - logln( "Formatted string: " + formatted ); + System.out.println( "Formatted string: " + formatted ); if (!formatted.equals(str)) { - errln("FAIL: Expected " + str); + fail("FAIL: Expected " + str); } } // Test Czech month formatting -- this can cause a problem because the June and // July month names share a common prefix. @SuppressWarnings("deprecation") + @Test public void TestCzechMonths459() { // Use Czech, which has month names with shared prefixes for June and July DateFormat fmt = DateFormat.getDateInstance(DateFormat.FULL, Locale.of("cs")); //((SimpleDateFormat)fmt).applyPattern("MMMM d yyyy"); - logln("Pattern " + ((SimpleDateFormat)fmt).toPattern()); + System.out.println("Pattern " + ((SimpleDateFormat)fmt).toPattern()); Date june = new Date(97, Calendar.JUNE, 15); Date july = new Date(97, Calendar.JULY, 15); @@ -424,31 +433,32 @@ public void TestCzechMonths459() String julyStr = fmt.format(july); try { - logln("format(June 15 1997) = " + juneStr); + System.out.println("format(June 15 1997) = " + juneStr); Date d = fmt.parse(juneStr); String s = fmt.format(d); int month = d.getMonth(); - logln(" -> parse -> " + s + " (month = " + month + ")"); + System.out.println(" -> parse -> " + s + " (month = " + month + ")"); if (month != JUNE) { - errln("FAIL: Month should be June"); + fail("FAIL: Month should be June"); } - logln("format(July 15 1997) = " + julyStr); + System.out.println("format(July 15 1997) = " + julyStr); d = fmt.parse(julyStr); s = fmt.format(d); month = d.getMonth(); - logln(" -> parse -> " + s + " (month = " + month + ")"); + System.out.println(" -> parse -> " + s + " (month = " + month + ")"); if (month != JULY) { - errln("FAIL: Month should be July"); + fail("FAIL: Month should be July"); } } catch (ParseException e) { - errln("Exception: " + e); + fail("Exception: " + e); } } // Test big D (day of year) versus little d (day of month) @SuppressWarnings("deprecation") + @Test public void TestLetterDPattern212() { String dateString = "1995-040.05:01:29"; @@ -457,32 +467,33 @@ public void TestLetterDPattern212() Date expLittleD = new Date(95, 0, 1, 5, 1, 29); Date expBigD = new Date(expLittleD.getTime() + 39*24*3600000L); // 39 days expLittleD = expBigD; // Expect the same, with default lenient parsing - logln( "dateString= " + dateString ); + System.out.println( "dateString= " + dateString ); SimpleDateFormat formatter = new SimpleDateFormat(bigD); ParsePosition pos = new ParsePosition(0); Date myDate = formatter.parse( dateString, pos ); - logln("Using " + bigD + " -> " + myDate); + System.out.println("Using " + bigD + " -> " + myDate); if (myDate.getTime() != expBigD.getTime()) { - errln("FAIL: Expected " + expBigD + " got " + myDate); + fail("FAIL: Expected " + expBigD + " got " + myDate); } formatter = new SimpleDateFormat(littleD); pos = new ParsePosition(0); myDate = formatter.parse( dateString, pos ); - logln("Using " + littleD + " -> " + myDate); + System.out.println("Using " + littleD + " -> " + myDate); if (myDate.getTime() != expLittleD.getTime()) { - errln("FAIL: Expected " + expLittleD + " got " + myDate); + fail("FAIL: Expected " + expLittleD + " got " + myDate); } } // Test the 'G' day of year pattern @SuppressWarnings("deprecation") + @Test public void TestDayOfYearPattern195() { Date today = new Date(); Date expected = new Date(today.getYear(), today.getMonth(), today.getDate()); - logln("Test Date: " + today); + System.out.println("Test Date: " + today); SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateInstance(); @@ -496,29 +507,30 @@ void tryPattern(SimpleDateFormat sdf, Date d, String pattern, Date expected) if (pattern != null) { sdf.applyPattern(pattern); } - logln("pattern: " + sdf.toPattern()); + System.out.println("pattern: " + sdf.toPattern()); String formatResult = sdf.format(d); - logln(" format -> " + formatResult); + System.out.println(" format -> " + formatResult); try { Date d2 = sdf.parse(formatResult); - logln(" parse(" + formatResult + ") -> " + d2); + System.out.println(" parse(" + formatResult + ") -> " + d2); if (d2.getTime() != expected.getTime()) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } String format2 = sdf.format(d2); - logln(" format -> " + format2); + System.out.println(" format -> " + format2); if (!formatResult.equals(format2)) { - errln("FAIL: Round trip drift"); + fail("FAIL: Round trip drift"); } } catch(Exception e) { - errln("Error: " + e.getMessage()); + fail("Error: " + e.getMessage()); } } // Test a pattern with single quotes @SuppressWarnings("deprecation") + @Test public void TestQuotePattern161() { // This pattern used to end in " zzz" but that makes this test zone-dependent @@ -526,9 +538,9 @@ public void TestQuotePattern161() Date currentTime_1 = new Date(97, Calendar.AUGUST, 13, 10, 42, 28); String dateString = formatter.format(currentTime_1); String exp = "08/13/1997 at 10:42:28 AM "; - logln("format(" + currentTime_1 + ") = " + dateString); + System.out.println("format(" + currentTime_1 + ") = " + dateString); if (!dateString.regionMatches(0, exp, 0, exp.length())) { - errln("FAIL: Expected " + exp); + fail("FAIL: Expected " + exp); } } @@ -540,6 +552,7 @@ public void TestQuotePattern161() * 1 line that should be correct is off by 100 years. (In this day * and age, no one would assume that 1/1/00 is Jan 1 1900.) **/ + @Test public void TestBadInput135() { int looks[] = { DateFormat.SHORT, DateFormat.MEDIUM, @@ -560,22 +573,22 @@ public void TestBadInput135() try { Date when = df.parse(text); if ( when == null ){ - errln(prefix + + fail(prefix + "SHOULD NOT HAPPEN: parse returned null."); continue; } String format = full.format(when); - logln(prefix + "OK: " + format); + System.out.println(prefix + "OK: " + format); // Only match the start -- not the zone, which could vary if (!format.regionMatches(0, expected, 0, expected.length())) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } } catch ( ParseException e ){ //errln(prefix + e); // This is expected. } catch ( StringIndexOutOfBoundsException e ){ - errln(prefix + "SHOULD NOT HAPPEN: " + e); + fail(prefix + "SHOULD NOT HAPPEN: " + e); } } } @@ -610,6 +623,7 @@ public void TestBadInput135() }; // More testing of the parsing of bad input @SuppressWarnings("UnusedAssignment") + @Test public void TestBadInput135a() { SimpleDateFormat dateParse = new SimpleDateFormat(); @@ -620,12 +634,12 @@ public void TestBadInput135a() dateParse.applyPattern("d MMMM, yyyy"); dateParse.setTimeZone(TimeZone.getDefault()); s = "not parseable"; - logln("Trying to parse \"" + s + "\" with " + dateParse.toPattern()); + System.out.println("Trying to parse \"" + s + "\" with " + dateParse.toPattern()); try { date = dateParse.parse(s); - errln("FAIL: Expected exception during parse"); + fail("FAIL: Expected exception during parse"); } catch (Exception ex) { - logln("Exception during parse: " + ex); // This is expected + System.out.println("Exception during parse: " + ex); // This is expected } for (int i=0; i " + d.toString()); if (d.getTime() != expected.getTime()) { - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); } } catch (ParseException e) { - errln("FAIL: Got exception"); + fail("FAIL: Got exception"); } } // Test behavior of DateFormat with applied time zone + @Test public void TestDateFormatZone061() { Date date; @@ -732,28 +748,29 @@ public void TestDateFormatZone061() // 25-Mar-97 00:00:00 GMT date = new Date( 859248000000L ); - logln( "Date 1997/3/25 00:00 GMT: " + date ); + System.out.println( "Date 1997/3/25 00:00 GMT: " + date ); formatter = new SimpleDateFormat("dd-MMM-yyyyy HH:mm", Locale.UK); formatter.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); String temp = formatter.format( date ); - logln( "Formatted in GMT to: " + temp ); + System.out.println( "Formatted in GMT to: " + temp ); /* Parse date string */ try { Date tempDate = formatter.parse( temp ); - logln( "Parsed to: " + tempDate ); + System.out.println( "Parsed to: " + tempDate ); if (tempDate.getTime() != date.getTime()) { - errln("FAIL: Expected " + date); + fail("FAIL: Expected " + date); } } catch( Throwable t ) { - errln( "Date Formatter throws: " + + fail( "Date Formatter throws: " + t.toString() ); } } // Make sure DateFormat uses the correct zone. + @Test public void TestDateFormatZone146() { TimeZone saveDefault = TimeZone.getDefault(); @@ -767,9 +784,9 @@ public void TestDateFormatZone146() TimeZone testdefault = TimeZone.getDefault(); String testtimezone = testdefault.getID(); if (testtimezone.equals("GMT")) { - logln("Test timezone = " + testtimezone); + System.out.println("Test timezone = " + testtimezone); } else { - errln("Test timezone should be GMT, not " + testtimezone); + fail("Test timezone should be GMT, not " + testtimezone); } // now try to use the default GMT time zone @@ -799,9 +816,9 @@ public void TestDateFormatZone146() DateFormat fmt = new SimpleDateFormat(DATA[i+2], Locale.ENGLISH); fmt.setCalendar(greenwichcalendar); String result = fmt.format(greenwichdate); - logln(DATA[i] + result); + System.out.println(DATA[i] + result); if (!result.equals(DATA[i+1])) { - errln("FAIL: Expected " + DATA[i+1] + fail("FAIL: Expected " + DATA[i+1] + ", got " + result); } } @@ -812,6 +829,7 @@ public void TestDateFormatZone146() } /* HS : Commented out for now, need to be changed not to use hardcoded results. + @Test public void TestLocaleDateFormat() // Bug 495 { Date testDate = new Date (97, Calendar.SEPTEMBER, 15); @@ -821,13 +839,13 @@ public void TestLocaleDateFormat() // Bug 495 DateFormat.FULL, Locale.US); String expectedFRENCH = "lundi 15 septembre 1997 00 h 00 GMT-07:00"; String expectedUS = "Monday, September 15, 1997 12:00:00 o'clock AM PDT"; - logln("Date set to : " + testDate); + System.out.println("Date set to : " + testDate); String out = dfFrench.format(testDate); - logln("Date Formated with French Locale " + out); - if (!out.equals(expectedFRENCH)) errln("FAIL: Expected " + expectedFRENCH); + System.out.println("Date Formated with French Locale " + out); + if (!out.equals(expectedFRENCH)) fail("FAIL: Expected " + expectedFRENCH); out = dfUS.format(testDate); - logln("Date Formated with US Locale " + out); - if (!out.equals(expectedUS)) errln("FAIL: Expected " + expectedUS); + System.out.println("Date Formated with US Locale " + out); + if (!out.equals(expectedUS)) fail("FAIL: Expected " + expectedUS); } */ /** @@ -835,13 +853,14 @@ public void TestLocaleDateFormat() // Bug 495 */ /* test commented out pending API-change approval + @Test public void Test2YearStartDate() throws ParseException { // create a SimpleDateFormat to test with; dump out if it's not a SimpleDateFormat DateFormat test = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); if (!(test instanceof SimpleDateFormat)) { - errln("DateFormat.getInstance() didn't return an instance of SimpleDateFormat!"); + fail("DateFormat.getInstance() didn't return an instance of SimpleDateFormat!"); return; } @@ -861,7 +880,7 @@ public void Test2YearStartDate() throws ParseException cal.setTime(date); if (cal.get(Calendar.YEAR) != 1900 || cal.get(Calendar.MONTH) != 0 || cal.get(Calendar.DATE) != 1) - errln("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) + fail("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR) + " instead of 1/1/1900."); @@ -869,19 +888,19 @@ public void Test2YearStartDate() throws ParseException date = sdf.parse(testString1); cal.setTime(date); if (cal.get(Calendar.YEAR) != 1967) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 yielded a year of " + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1967."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 failed: got " + + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1900 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/10."); date = sdf.parse(testString2); cal.setTime(date); if (cal.get(Calendar.YEAR) != 1943) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 yielded a year of " + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1943."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 failed: got " + + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1900 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/16."); @@ -891,19 +910,19 @@ public void Test2YearStartDate() throws ParseException date = sdf.parse(testString1); cal.setTime(date); if (cal.get(Calendar.YEAR) != 2067) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 yielded a year of " + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 2067."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 failed: got " + + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/2000 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/10."); date = sdf.parse(testString2); cal.setTime(date); if (cal.get(Calendar.YEAR) != 2043) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 yielded a year of " + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1943."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 failed: got " + + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/2000 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/16."); @@ -913,19 +932,19 @@ public void Test2YearStartDate() throws ParseException date = sdf.parse(testString1); cal.setTime(date); if (cal.get(Calendar.YEAR) != 1967) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 yielded a year of " + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1967."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 10) - errln("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 failed: got " + + fail("Parsing \"3/10/67\" with 2-digit start date set to 1/1/1950 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/10."); date = sdf.parse(testString2); cal.setTime(date); if (cal.get(Calendar.YEAR) != 2043) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 yielded a year of " + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1943."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) - errln("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 failed: got " + + fail("Parsing \"3/16/43\" with 2-digit start date set to 1/1/1950 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/16."); @@ -935,19 +954,19 @@ public void Test2YearStartDate() throws ParseException date = sdf.parse(testString2); cal.setTime(date); if (cal.get(Calendar.YEAR) != 2043) - errln("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 yielded a year of " + fail("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 2043."); if (cal.get(Calendar.MONTH) != 2 || cal.get(Calendar.DATE) != 16) - errln("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 failed: got " + + fail("Parsing \"3/16/43\" with 2-digit start date set to 6/1/1943 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 3/16."); date = sdf.parse(testString3); cal.setTime(date); if (cal.get(Calendar.YEAR) != 1943) - errln("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 yielded a year of " + fail("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 yielded a year of " + cal.get(Calendar.YEAR) + " instead of 1943."); if (cal.get(Calendar.MONTH) != 6 || cal.get(Calendar.DATE) != 21) - errln("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 failed: got " + + fail("Parsing \"7/21/43\" with 2-digit start date set to 6/1/1943 failed: got " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + " instead of 7/21."); @@ -957,7 +976,7 @@ public void Test2YearStartDate() throws ParseException cal.setTime(date); if (cal.get(Calendar.YEAR) != 1943 || cal.get(Calendar.MONTH) != 5 || cal.get(Calendar.DATE) != 1) - errln("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) + fail("SimpleDateFormat.get2DigitStartDate() returned " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR) + " instead of 6/1/1943."); } @@ -967,6 +986,7 @@ public void Test2YearStartDate() throws ParseException * ParsePosition.errorIndex tests. */ @SuppressWarnings("deprecation") + @Test public void Test4052223() { String str = "7/SOS/2001"; @@ -975,17 +995,18 @@ public void Test4052223() SimpleDateFormat sdf = new SimpleDateFormat(pat); ParsePosition pos = new ParsePosition(0); Date d = sdf.parse(str, pos); - logln(str + " parses with " + pat + " to " + d); + System.out.println(str + " parses with " + pat + " to " + d); if (d == null && pos.getErrorIndex() == 2) { - logln("Expected null returned, failed at : " + pos.getErrorIndex()); + System.out.println("Expected null returned, failed at : " + pos.getErrorIndex()); } else { - errln("Failed, parse " + str + " got : " + d + ", index=" + pos.getErrorIndex()); + fail("Failed, parse " + str + " got : " + d + ", index=" + pos.getErrorIndex()); } } /** * Bug4469904 -- th_TH date format doesn't use Thai B.E. */ + @Test public void TestBuddhistEraBugId4469904() { String era = "\u0e1e.\u0e28."; Locale loc = Locale.of("th", "TH"); @@ -996,7 +1017,7 @@ public void TestBuddhistEraBugId4469904() { String output = df.format(date); int index = output.indexOf(era); if (index == -1) { - errln("Test4469904: Failed. Buddhist Era abbrev not present."); + fail("Test4469904: Failed. Buddhist Era abbrev not present."); } } @@ -1004,6 +1025,7 @@ public void TestBuddhistEraBugId4469904() { * 4326988: API: SimpleDateFormat throws NullPointerException when parsing with null pattern */ @SuppressWarnings("UnusedAssignment") + @Test public void Test4326988() { String[] wrongPatterns = { "hh o''clock", @@ -1021,28 +1043,28 @@ public void Test4326988() { // Check NullPointerException try { SimpleDateFormat fmt = new SimpleDateFormat(null); - errln("SimpleDateFormat() doesn't throw NPE with null pattern"); + fail("SimpleDateFormat() doesn't throw NPE with null pattern"); } catch (NullPointerException e) { // Okay } try { Locale loc = null; SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd", loc); - errln("SimpleDateFormat() doesn't throw NPE with null locale"); + fail("SimpleDateFormat() doesn't throw NPE with null locale"); } catch (NullPointerException e) { // Okay } try { DateFormatSymbols symbols = null; SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd", symbols); - errln("SimpleDateFormat() doesn't throw NPE with null DateFormatSymbols"); + fail("SimpleDateFormat() doesn't throw NPE with null DateFormatSymbols"); } catch (NullPointerException e) { // Okay } try { SimpleDateFormat fmt = new SimpleDateFormat(); fmt.applyPattern(null); - errln("applyPattern() doesn't throw NPE with null pattern"); + fail("applyPattern() doesn't throw NPE with null pattern"); } catch (NullPointerException e) { // Okay } @@ -1051,7 +1073,7 @@ public void Test4326988() { for (int i = 0; i < wrongPatterns.length; i++) { try { SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i]); - errln("SimpleDateFormat(\"" + wrongPatterns[i] + "\")" + + fail("SimpleDateFormat(\"" + wrongPatterns[i] + "\")" + " doesn't throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { // Okay @@ -1059,7 +1081,7 @@ public void Test4326988() { try { SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i], DateFormatSymbols.getInstance()); - errln("SimpleDateFormat(\"" + wrongPatterns[i] + "\", DateFormatSymbols) doesn't " + + fail("SimpleDateFormat(\"" + wrongPatterns[i] + "\", DateFormatSymbols) doesn't " + "throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { // Okay @@ -1067,7 +1089,7 @@ public void Test4326988() { try { SimpleDateFormat fmt = new SimpleDateFormat(wrongPatterns[i], Locale.US); - errln("SimpleDateFormat(\"" + wrongPatterns[i] + + fail("SimpleDateFormat(\"" + wrongPatterns[i] + "\", Locale) doesn't throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { // Okay @@ -1075,7 +1097,7 @@ public void Test4326988() { try { SimpleDateFormat fmt = new SimpleDateFormat(); fmt.applyPattern(wrongPatterns[i]); - errln("SimpleDateFormat.applyPattern(\"" + wrongPatterns[i] + + fail("SimpleDateFormat.applyPattern(\"" + wrongPatterns[i] + "\") doesn't throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { // Okay @@ -1100,6 +1122,7 @@ public void Test4326988() { * Another round trip test */ @SuppressWarnings("deprecation") + @Test public void Test4486735() throws Exception { TimeZone initialTimeZone = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("GMT")); @@ -1109,7 +1132,7 @@ public void Test4486735() throws Exception { // Round to minutes. Some FULL formats don't have seconds. long time = System.currentTimeMillis()/60000 * 60000; Date date = new Date(time); - logln("the test date: " + date); + System.out.println("the test date: " + date); try { for (int z = 0; z < zones.length; z++) { @@ -1120,7 +1143,7 @@ public void Test4486735() throws Exception { DateFormat.FULL, loc); String s = df.format(date); - logln(s); + System.out.println(s); Date parsedDate = df.parse(s); long parsedTime = parsedDate.getTime(); if (time != parsedTime) { @@ -1133,7 +1156,7 @@ public void Test4486735() throws Exception { continue; } } - errln("round trip conversion failed: timezone="+zones[z]+ + fail("round trip conversion failed: timezone="+zones[z]+ ", locale=" + loc + ", expected=" + time + ", got=" + parsedTime); } @@ -1191,13 +1214,13 @@ public void Test4486735() throws Exception { SimpleDateFormat sdf = new SimpleDateFormat(pat); String s = sdf.format(new Date(2001-1900, Calendar.JANUARY, 1)); if (!expected.equals(s)) { - errln("wrong format result: expected="+expected+", got="+s); + fail("wrong format result: expected="+expected+", got="+s); } Date longday = sdf.parse(s); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(longday); if (cal.get(YEAR) != 2001) { - errln("wrong parse result: expected=2001, got=" + cal.get(YEAR)); + fail("wrong parse result: expected=2001, got=" + cal.get(YEAR)); } } catch (Exception e) { throw e; @@ -1207,6 +1230,7 @@ public void Test4486735() throws Exception { } } + @Test public void Test8216969() throws Exception { Locale locale = Locale.of("ru"); String format = "\u0434\u0435\u043a"; diff --git a/test/jdk/java/text/Format/DateFormat/IntlTestDateFormat.java b/test/jdk/java/text/Format/DateFormat/IntlTestDateFormat.java index bc37d4f7fba..ebac773bd7e 100644 --- a/test/jdk/java/text/Format/DateFormat/IntlTestDateFormat.java +++ b/test/jdk/java/text/Format/DateFormat/IntlTestDateFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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,8 +25,7 @@ * @test * @summary test International Date Format * @bug 8008577 - * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI IntlTestDateFormat + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI IntlTestDateFormat * @key randomness */ /* @@ -44,7 +43,11 @@ import java.text.*; import java.util.*; -public class IntlTestDateFormat extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class IntlTestDateFormat { // Values in milliseconds (== Date) private static final long ONESECOND = 1000; private static final long ONEMINUTE = 60 * ONESECOND; @@ -62,10 +65,7 @@ public class IntlTestDateFormat extends IntlTest { private String fTestName = new String("getInstance"); private int fLimit = 3; // How many iterations it should take to reach convergence - public static void main(String[] args) throws Exception { - new IntlTestDateFormat().run(args); - } - + @Test public void TestLocale() { localeTest(Locale.getDefault(), "Default Locale"); } @@ -85,7 +85,7 @@ public void localeTest(final Locale locale, final String localeName) { fFormat = DateFormat.getTimeInstance(timeStyle, locale); } catch(StringIndexOutOfBoundsException e) { - errln("FAIL: localeTest time getTimeInstance exception"); + fail("FAIL: localeTest time getTimeInstance exception"); throw e; } TestFormat(); @@ -99,7 +99,7 @@ public void localeTest(final Locale locale, final String localeName) { fFormat = DateFormat.getDateInstance(dateStyle, locale); } catch(StringIndexOutOfBoundsException e) { - errln("FAIL: localeTest date getTimeInstance exception"); + fail("FAIL: localeTest date getTimeInstance exception"); throw e; } TestFormat(); @@ -112,7 +112,7 @@ public void localeTest(final Locale locale, final String localeName) { fFormat = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); } catch(StringIndexOutOfBoundsException e) { - errln("FAIL: localeTest date/time getDateTimeInstance exception"); + fail("FAIL: localeTest date/time getDateTimeInstance exception"); throw e; } TestFormat(); @@ -120,9 +120,10 @@ public void localeTest(final Locale locale, final String localeName) { } } + @Test public void TestFormat() { if (fFormat == null) { - errln("FAIL: DateFormat creation failed"); + fail("FAIL: DateFormat creation failed"); return; } // logln("TestFormat: " + fTestName); @@ -142,13 +143,13 @@ public void TestFormat() { private void describeTest() { if (fFormat == null) { - errln("FAIL: no DateFormat"); + fail("FAIL: no DateFormat"); return; } // Assume it's a SimpleDateFormat and get some info SimpleDateFormat s = (SimpleDateFormat) fFormat; - logln(fTestName + " Pattern " + s.toPattern()); + System.out.println(fTestName + " Pattern " + s.toPattern()); } private void tryDate(Date theDate) { @@ -169,7 +170,7 @@ private void tryDate(Date theDate) { } catch (ParseException e) { describeTest(); - errln("********** FAIL: Parse of " + string[i-1] + " failed."); + fail("********** FAIL: Parse of " + string[i-1] + " failed."); dump = true; break; } @@ -180,14 +181,14 @@ private void tryDate(Date theDate) { if (dateMatch == 0 && date[i] == date[i-1]) dateMatch = i; else if (dateMatch > 0 && date[i] != date[i-1]) { describeTest(); - errln("********** FAIL: Date mismatch after match."); + fail("********** FAIL: Date mismatch after match."); dump = true; break; } if (stringMatch == 0 && string[i] == string[i-1]) stringMatch = i; else if (stringMatch > 0 && string[i] != string[i-1]) { describeTest(); - errln("********** FAIL: String mismatch after match."); + fail("********** FAIL: String mismatch after match."); dump = true; break; } @@ -198,13 +199,13 @@ else if (stringMatch > 0 && string[i] != string[i-1]) { if (stringMatch > fLimit || dateMatch > fLimit) { describeTest(); - errln("********** FAIL: No string and/or date match within " + fLimit + " iterations."); + fail("********** FAIL: No string and/or date match within " + fLimit + " iterations."); dump = true; } if (dump) { for (int k=0; k<=i; ++k) { - logln("" + k + ": " + date[k] + " F> " + string[k] + " P> "); + System.out.println("" + k + ": " + date[k] + " F> " + string[k] + " P> "); } } } @@ -235,34 +236,36 @@ private double randDouble() { return rand.nextDouble(); } + @Test public void TestAvailableLocales() { final Locale[] locales = DateFormat.getAvailableLocales(); long count = locales.length; - logln("" + count + " available locales"); + System.out.println("" + count + " available locales"); if (locales != null && count != 0) { StringBuffer all = new StringBuffer(); for (int i=0; i subsitution failed. result = " + tempBuffer.toString()); - logln("Formatted with extra params : " + tempBuffer); + fail("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString()); + System.out.println("Formatted with extra params : " + tempBuffer); //This statement gives an exception while formatting... //If we use pattern[1] for the message with param, //we get an NullPointerException in MessageFormat.java(617) @@ -103,28 +104,30 @@ public void Test4074764() { //in applyPattern() when the pattern does not //contain any param. } catch (Exception foo) { - errln("Exception when formatting with no params."); + fail("Exception when formatting with no params."); } } /* @bug 4058973 * MessageFormat.toPattern has weird rounding behavior. */ + @Test public void Test4058973() { MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}"); String pat = fmt.toPattern(); if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) { - errln("MessageFormat.toPattern failed"); + fail("MessageFormat.toPattern failed"); } } /* @bug 4031438 * More robust message formats. */ + @Test public void Test4031438() { Locale locale = Locale.getDefault(); if (!TestUtils.usesAsciiDigits(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -134,91 +137,94 @@ public void Test4031438() { MessageFormat messageFormatter = new MessageFormat(""); try { - logln("Apply with pattern : " + pattern1); + System.out.println("Apply with pattern : " + pattern1); messageFormatter.applyPattern(pattern1); Object[] params = {7}; String tempBuffer = messageFormatter.format(params); if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}.")) - errln("Tests arguments < substitution failed. Formatted text=" + + fail("Tests arguments < substitution failed. Formatted text=" + "<" + tempBuffer + ">"); - logln("Formatted with 7 : " + tempBuffer); + System.out.println("Formatted with 7 : " + tempBuffer); ParsePosition status = new ParsePosition(0); Object[] objs = messageFormatter.parse(tempBuffer, status); if (objs[params.length] != null) - errln("Parse failed with more than expected arguments"); + fail("Parse failed with more than expected arguments"); for (int i = 0; i < objs.length; i++) { if (objs[i] != null && !objs[i].toString().equals(params[i].toString())) { - errln("Parse failed on object " + objs[i] + " at index : " + i); + fail("Parse failed on object " + objs[i] + " at index : " + i); } } tempBuffer = messageFormatter.format(null); if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}.")) - errln("Tests with no arguments failed"); - logln("Formatted with null : " + tempBuffer); - logln("Apply with pattern : " + pattern2); + fail("Tests with no arguments failed"); + System.out.println("Formatted with null : " + tempBuffer); + System.out.println("Apply with pattern : " + pattern2); messageFormatter.applyPattern(pattern2); tempBuffer = messageFormatter.format(params); if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus other {2} stuff.")) - errln("quote format test (w/ params) failed."); - logln("Formatted with params : " + tempBuffer); + fail("quote format test (w/ params) failed."); + System.out.println("Formatted with params : " + tempBuffer); tempBuffer = messageFormatter.format(null); if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff.")) - errln("quote format test (w/ null) failed."); - logln("Formatted with null : " + tempBuffer); - logln("toPattern : " + messageFormatter.toPattern()); + fail("quote format test (w/ null) failed."); + System.out.println("Formatted with null : " + tempBuffer); + System.out.println("toPattern : " + messageFormatter.toPattern()); } catch (Exception foo) { - errln("Exception when formatting in bug 4031438. "+foo.getMessage()); + fail("Exception when formatting in bug 4031438. "+foo.getMessage()); } } + @Test public void Test4052223() { ParsePosition pos = new ParsePosition(0); if (pos.getErrorIndex() != -1) { - errln("ParsePosition.getErrorIndex initialization failed."); + fail("ParsePosition.getErrorIndex initialization failed."); } MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree."); String str = new String("There is one apple growing on the peach tree."); Object[] objs = fmt.parse(str, pos); - logln("unparsable string , should fail at " + pos.getErrorIndex()); + System.out.println("unparsable string , should fail at " + pos.getErrorIndex()); if (pos.getErrorIndex() == -1) - errln("Bug 4052223 failed : parsing string " + str); + fail("Bug 4052223 failed : parsing string " + str); pos.setErrorIndex(4); if (pos.getErrorIndex() != 4) - errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4"); + fail("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4"); ChoiceFormat f = new ChoiceFormat( "-1#are negative|0#are no or fraction|1#is one|1.0 " + + fail("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " + out + "; want \"" + DATA[i+1+j] + '"'); } String pat = cf.toPattern(); String pat2 = new ChoiceFormat(pat).toPattern(); if (!pat.equals(pat2)) - errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); + fail("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); else - logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); + System.out.println("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); } catch (IllegalArgumentException e) { - errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e); + fail("Fail: Pattern \"" + DATA[i] + "\" -> " + e); } } } @@ -587,17 +607,18 @@ public void TestChoicePatternQuote() { * MessageFormat.equals(null) throws a NullPointerException. The JLS states * that it should return false. */ + @Test public void Test4112104() { MessageFormat format = new MessageFormat(""); try { // This should NOT throw an exception if (format.equals(null)) { // It also should return false - errln("MessageFormat.equals(null) returns false"); + fail("MessageFormat.equals(null) returns false"); } } catch (NullPointerException e) { - errln("MessageFormat.equals(null) throws " + e); + fail("MessageFormat.equals(null) throws " + e); } } @@ -605,15 +626,17 @@ public void Test4112104() { * @bug 4169959 * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG. */ + @Test public void Test4169959() { // This works - logln(MessageFormat.format( "This will {0}", "work")); + System.out.println(MessageFormat.format( "This will {0}", "work")); // This fails - logln(MessageFormat.format( "This will {0}", + System.out.println(MessageFormat.format( "This will {0}", new Object[]{ null } ) ); } + @Test public void test4232154() { boolean gotException = false; try { @@ -632,6 +655,7 @@ public void test4232154() { } } + @Test public void test4293229() { MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''"); Object[] args = { null }; @@ -647,6 +671,7 @@ public void test4293229() { * @bug 8187551 * test MessageFormat.setFormat() method to throw AIOOBE on invalid index. */ + @Test public void test8187551() { //invalid cases ("pattern", "invalid format element index") String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"}, diff --git a/test/jdk/java/text/Format/MessageFormat/MessageTest.java b/test/jdk/java/text/Format/MessageFormat/MessageTest.java index a7542689563..674ce1d3152 100644 --- a/test/jdk/java/text/Format/MessageFormat/MessageTest.java +++ b/test/jdk/java/text/Format/MessageFormat/MessageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,8 +23,8 @@ /* * @test - * @library /java/text/testlib * @summary test MessageFormat + * @run junit MessageTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -43,13 +43,14 @@ import java.io.*; import java.text.*; -public class MessageTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new MessageTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class MessageTest { + @Test public void TestMSGPatternTest() { Object[] testArgs = { 1D, 3456D, @@ -71,12 +72,12 @@ public void TestMSGPatternTest() { Locale save = Locale.getDefault(); try { Locale.setDefault(Locale.US); - logln(""); - logln( i + " Pat in: " + testCases[i]); + System.out.println(""); + System.out.println( i + " Pat in: " + testCases[i]); MessageFormat form = new MessageFormat(testCases[i]); - logln( i + " Pat out: " + form.toPattern()); + System.out.println( i + " Pat out: " + form.toPattern()); String result = form.format(testArgs); - logln( i + " Result: " + result); + System.out.println( i + " Result: " + result); Object[] values = form.parse(result); for (int j = 0; j < testArgs.length; ++j) { Object testArg = testArgs[j]; @@ -86,8 +87,8 @@ public void TestMSGPatternTest() { } if ((testArg == null && value != null) || (testArg != null && !testArg.equals(value))) { - logln( i + " " + j + " old: " + testArg); - logln( i + " " + j + " new: " + value); + System.out.println( i + " " + j + " old: " + testArg); + System.out.println( i + " " + j + " new: " + value); } } } diff --git a/test/jdk/java/text/Format/MessageFormat/bug4492719.java b/test/jdk/java/text/Format/MessageFormat/bug4492719.java index 6a1d2184ffe..3243b3c8ee2 100644 --- a/test/jdk/java/text/Format/MessageFormat/bug4492719.java +++ b/test/jdk/java/text/Format/MessageFormat/bug4492719.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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,27 +25,35 @@ * @test * * @bug 4492719 - * @library /java/text/testlib * @summary Confirm that Message.parse() interprets time zone which uses "GMT+/-" format correctly and doesn't throw ParseException. + * @run junit/othervm bug4492719 */ import java.util.*; import java.text.*; -public class bug4492719 extends IntlTest { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { +import static org.junit.jupiter.api.Assertions.fail; + +public class bug4492719 { + + // MessageFormat.parse() should be able to interpret a time zone + // that uses "GMT+/-". + @Test + public void testParse() throws Exception { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); MessageFormat mf; boolean err =false; String[] formats = { - "short", "medium", "long", "full" + "short", "medium", "long", "full" }; String[] timezones = { - "America/Los_Angeles", "GMT", "GMT+09:00", "GMT-8:00", - "GMT+123", "GMT-1234", "GMT+2", "GMT-13" + "America/Los_Angeles", "GMT", "GMT+09:00", "GMT-8:00", + "GMT+123", "GMT-1234", "GMT+2", "GMT-13" }; String text; @@ -58,14 +66,14 @@ public static void main(String[] args) throws Exception { for (int j = 0; j < formats.length; j++) { mf = new MessageFormat("{0,time," + formats[j] + "} - time"); text = MessageFormat.format("{0,time," + formats[j] + "} - time", - new Object [] { new Date(123456789012L)}); + new Object [] { new Date(123456789012L)}); Object[] objs = mf.parse(text); } } } catch (ParseException e) { err = true; System.err.println("Invalid ParseException occurred : " + - e.getMessage()); + e.getMessage()); System.err.println(" TimeZone=" + TimeZone.getDefault()); } finally { diff --git a/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java b/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java index 2803bc8228e..ddb713929b4 100644 --- a/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java +++ b/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,8 +25,7 @@ * @test * @bug 4018937 8008577 * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected. - * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalFormat + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalFormat */ import java.math.BigDecimal; @@ -34,11 +33,11 @@ import java.text.*; import java.util.*; -public class BigDecimalFormat extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new BigDecimalFormat().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class BigDecimalFormat { static final String nonsep_int = "123456789012345678901234567890123456789012345678901234567890" + @@ -998,7 +997,7 @@ void test_Format_in_MessageFormat() { ; if (!expected.equals(mf.format(testArgs))) { - errln("Wrong format.\n got:\n" + mf.format(testArgs) + + fail("Wrong format.\n got:\n" + mf.format(testArgs) + " expected:\n" + expected); } } @@ -1014,7 +1013,7 @@ private void setDigits(NumberFormat nf, private void checkFormat(String orig, StringBuffer got, String expected, int multiplier) { if (!expected.equals(new String(got))) { - errln("Formatting... failed." + + fail("Formatting... failed." + "\n original: " + orig + "\n multiplier: " + multiplier + "\n formatted: " + got + @@ -1027,14 +1026,14 @@ private void checkFieldPosition(String orig, FieldPosition fp, int begin, int position; if ((position = fp.getBeginIndex()) != begin) { - errln("Formatting... wrong Begin index returned for " + + fail("Formatting... wrong Begin index returned for " + fp.getFieldAttribute() + "." + "\n original: " + orig + "\n got: " + position + "\n expected: " + begin + "\n"); } if ((position = fp.getEndIndex()) != end) { - errln("Formatting... wrong End index returned for " + + fail("Formatting... wrong End index returned for " + fp.getFieldAttribute() + "." + "\n original: " + orig + "\n got: " + position + diff --git a/test/jdk/java/text/Format/NumberFormat/BigDecimalParse.java b/test/jdk/java/text/Format/NumberFormat/BigDecimalParse.java index 972cfa2851f..c878165c5ba 100644 --- a/test/jdk/java/text/Format/NumberFormat/BigDecimalParse.java +++ b/test/jdk/java/text/Format/NumberFormat/BigDecimalParse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,27 +25,27 @@ * @test * @bug 4018937 8008577 * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected. - * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse */ import java.math.BigDecimal; import java.text.*; import java.util.*; -public class BigDecimalParse extends IntlTest { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - Locale loc = Locale.getDefault(); - try { - Locale.setDefault(Locale.US); - new BigDecimalParse().run(args); - } finally { - // restore the reserved locale - Locale.setDefault(loc); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class BigDecimalParse { + + // Change JVM default Locale + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); } + static final String nonsep_int = "123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890" + @@ -108,7 +108,8 @@ public static void main(String[] args) throws Exception { /** * Test for normal big numbers which have the fraction part */ - void test_Parse_in_DecimalFormat_BigDecimal() { + @Test + public void test_Parse_in_DecimalFormat_BigDecimal() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -150,7 +151,8 @@ void test_Parse_in_DecimalFormat_BigDecimal() { /** * Test for normal big numbers which have the fraction part with multiplier */ - void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() { + @Test + public void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -192,7 +194,8 @@ void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() { /** * Test for division by zero (BigDecimal) */ - void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() { + @Test + public void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() { df = new DecimalFormat(); df.setParseBigDecimal(true); df.setMultiplier(0); @@ -213,7 +216,8 @@ void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() { /** * Test for division by zero (Double) */ - void test_Parse_in_DecimalFormat_Double_DivisionByZero() { + @Test + public void test_Parse_in_DecimalFormat_Double_DivisionByZero() { df = new DecimalFormat(); df.setParseBigDecimal(false); df.setMultiplier(0); @@ -250,7 +254,8 @@ void test_Parse_in_DecimalFormat_Double_DivisionByZero() { /** * Test for division by zero (Long) */ - void test_Parse_in_DecimalFormat_Long_DivisionByZero() { + @Test + public void test_Parse_in_DecimalFormat_Long_DivisionByZero() { df = new DecimalFormat(); df.setParseBigDecimal(false); df.setMultiplier(0); @@ -271,7 +276,8 @@ void test_Parse_in_DecimalFormat_Long_DivisionByZero() { /** * Test for normal big numbers which don't have the fraction part */ - void test_Parse_in_DecimalFormat_BigInteger() { + @Test + public void test_Parse_in_DecimalFormat_BigInteger() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -296,7 +302,8 @@ void test_Parse_in_DecimalFormat_BigInteger() { * Test for normal big numbers which don't have the fraction part with * multiplier */ - void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() { + @Test + public void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -337,7 +344,8 @@ void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() { * Double.POSITIVE_INFINITY * Double.NEGATIVE_INFINITY */ - void test_Parse_in_DecimalFormat_SpecialNumber() { + @Test + public void test_Parse_in_DecimalFormat_SpecialNumber() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -378,7 +386,8 @@ void test_Parse_in_DecimalFormat_SpecialNumber() { /** * Test for special numbers */ - void test_Parse_in_DecimalFormat_Other() { + @Test + public void test_Parse_in_DecimalFormat_Other() { df = new DecimalFormat(); df.setParseBigDecimal(true); @@ -472,7 +481,8 @@ void test_Parse_in_DecimalFormat_Other() { /** * Test for MessageFormat: setParseIntegerOnly(false) */ - void test_Parse_in_MessageFormat_NotParseIntegerOnly() { + @Test + public void test_Parse_in_MessageFormat_NotParseIntegerOnly() { for (int i=0; i < patterns.length; i++) { pp = new ParsePosition(0); Object[] parsed = null; @@ -487,19 +497,19 @@ void test_Parse_in_MessageFormat_NotParseIntegerOnly() { parsed = mf.parse(from[i], pp); if (pp.getErrorIndex() != -1) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getErrorIndex() returns wrong value. expected:-1, got:"+ pp.getErrorIndex() + " for " + from[i]); } if (pp.getIndex() != parsePosition1[i]) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getIndex() returns wrong value. expected:" + parsePosition1[i] + ", got:"+ pp.getIndex() + " for " + from[i]); } } catch(Exception e) { - errln("Unexpected exception: " + e.getMessage()); + fail("Unexpected exception: " + e.getMessage()); } checkType(from[i], getType(new BigDecimal(expected1[i])), @@ -558,7 +568,8 @@ void test_Parse_in_MessageFormat_NotParseIntegerOnly() { /** * Test for MessageFormat: setParseIntegerOnly(true) */ - void test_Parse_in_MessageFormat_ParseIntegerOnly() { + @Test + public void test_Parse_in_MessageFormat_ParseIntegerOnly() { for (int i=0; i < patterns.length; i++) { pp = new ParsePosition(0); Object[] parsed = null; @@ -574,20 +585,20 @@ void test_Parse_in_MessageFormat_ParseIntegerOnly() { parsed = mf.parse(from[i], pp); if (pp.getErrorIndex() != parsePosition2[i][0]) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getErrorIndex() returns wrong value. expected:" + parsePosition2[i][0] + ", got:"+ pp.getErrorIndex() + " for " + from[i]); } if (pp.getIndex() != parsePosition2[i][1]) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getIndex() returns wrong value. expected:" + parsePosition2[i][1] + ", got:"+ pp.getIndex() + " for " + from[i]); } } catch(Exception e) { - errln("Unexpected exception: " + e.getMessage()); + fail("Unexpected exception: " + e.getMessage()); } if (parsePosition2[i][0] == -1) { @@ -624,7 +635,8 @@ void test_Parse_in_MessageFormat_ParseIntegerOnly() { /** * Test for DecimalFormat: setParseIntegerOnly(true) */ - void test_Parse_in_DecimalFormat_ParseIntegerOnly() { + @Test + public void test_Parse_in_DecimalFormat_ParseIntegerOnly() { DecimalFormat df = (DecimalFormat)NumberFormat.getIntegerInstance(); df.setParseBigDecimal(true); @@ -636,20 +648,20 @@ void test_Parse_in_DecimalFormat_ParseIntegerOnly() { parsed = df.parse(from3[i], pp); if (pp.getErrorIndex() != parsePosition3[i][0]) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getErrorIndex() returns wrong value. expected:" + parsePosition3[i][0] + ", got:"+ pp.getErrorIndex() + " for " + from3[i]); } if (pp.getIndex() != parsePosition3[i][1]) { - errln("Case" + (i+1) + + fail("Case" + (i+1) + ": getIndex() returns wrong value. expected:" + parsePosition3[i][1] + ", got:"+ pp.getIndex() + " for " + from3[i]); } } catch(Exception e) { - errln("Unexpected exception: " + e.getMessage()); + fail("Unexpected exception: " + e.getMessage()); } if (parsePosition3[i][0] == -1) { @@ -667,7 +679,7 @@ protected void check(String from, Number to) { } catch(Exception e) { exceptionOccurred = true; - errln(e.getMessage()); + fail(e.getMessage()); } if (!exceptionOccurred) { checkParse(from, to, parsed); @@ -678,7 +690,7 @@ protected void check(String from, Number to) { private void checkParse(String orig, Number expected, Number got) { if (!expected.equals(got)) { - errln("Parsing... failed." + + fail("Parsing... failed." + "\n original: " + orig + "\n parsed: " + got + "\n expected: " + expected + "\n"); @@ -687,7 +699,7 @@ private void checkParse(String orig, Number expected, Number got) { private void checkType(String orig, String expected, String got) { if (!expected.equals(got)) { - errln("Parsing... unexpected Class returned." + + fail("Parsing... unexpected Class returned." + "\n original: " + orig + "\n got: " + got + "\n expected: " + expected + "\n"); @@ -696,7 +708,7 @@ private void checkType(String orig, String expected, String got) { private void checkParsePosition(String orig, int expected, int got) { if (expected != got) { - errln("Parsing... wrong ParsePosition returned." + + fail("Parsing... wrong ParsePosition returned." + "\n original: " + orig + "\n got: " + got + "\n expected: " + expected + "\n"); diff --git a/test/jdk/java/text/Format/NumberFormat/Bug4838107.java b/test/jdk/java/text/Format/NumberFormat/Bug4838107.java index 72cad141174..452660b1ab2 100644 --- a/test/jdk/java/text/Format/NumberFormat/Bug4838107.java +++ b/test/jdk/java/text/Format/NumberFormat/Bug4838107.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,15 +25,18 @@ * @test * @bug 4838107 8008577 * @summary Confirm that DecimalFormat can format a number with negative exponent number correctly. - * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI Bug4838107 + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI Bug4838107 */ import java.math.*; import java.util.*; import java.text.*; -public class Bug4838107 extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class Bug4838107 { static DecimalFormat df; static DecimalFormatSymbols dfs; diff --git a/test/jdk/java/text/Format/NumberFormat/DFSExponential.java b/test/jdk/java/text/Format/NumberFormat/DFSExponential.java index 898fb3feccb..8ad22872ae8 100644 --- a/test/jdk/java/text/Format/NumberFormat/DFSExponential.java +++ b/test/jdk/java/text/Format/NumberFormat/DFSExponential.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -24,21 +24,21 @@ /** * @test * @bug 4068067 - * @library /java/text/testlib * @summary test NumberFormat with exponential separator symbols. It also tests the new * public methods in DecimalFormatSymbols, setExponentSeparator() and * getExponentSeparator() + * @run junit DFSExponential */ import java.util.*; import java.text.*; -public class DFSExponential extends IntlTest -{ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; - public static void main(String[] args) throws Exception { - new DFSExponential().run(args); - } +public class DFSExponential +{ public void DFSExponenTest() throws Exception { @@ -55,30 +55,30 @@ public void DFSExponenTest() throws Exception { int ival = 0, ilval = 0; - logln("Default exponent separator: "+sym.getExponentSeparator()); + System.out.println("Default exponent separator: "+sym.getExponentSeparator()); try { sym.setExponentSeparator("x10^"); } catch (NullPointerException e){ - errln("null String was passed to set an exponent separator symbol"); + fail("null String was passed to set an exponent separator symbol"); throw new RuntimeException("Test Malfunction: null String was passed to set an exponent separator symbol" ); } - logln("Current exponent separator: "+sym.getExponentSeparator()); + System.out.println("Current exponent separator: "+sym.getExponentSeparator()); for (int p=0; p "+s); + System.out.println(" " + val[v]+" --> "+s); if(valFormat[p][v].equals(s)){ - logln(": Passed"); + System.out.println(": Passed"); }else{ - errln(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s); + fail(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s); throw new RuntimeException(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s); } } diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java index 78bd1389786..7e27a7ac265 100644 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java +++ b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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,8 +25,8 @@ * @test * @bug 4068067 * @library /java/text/testlib - * @build DFSSerialization IntlTest HexDumpReader - * @run main DFSSerialization + * @build DFSSerialization HexDumpReader + * @run junit DFSSerialization * @summary Three different tests are done. * 1. read from the object created using jdk1.4.2 * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object @@ -43,10 +43,11 @@ import java.text.DecimalFormatSymbols; import java.util.Locale; -public class DFSSerialization extends IntlTest{ - public static void main(String[] args) throws Exception { - new DFSSerialization().run(args); - } +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class DFSSerialization{ public void TestDFSSerialization(){ /* * 1. read from the object created using jdk1.4.2 @@ -56,9 +57,9 @@ public void TestDFSSerialization(){ if (dfs142 != null){ if (dfs142.getExponentSeparator().equals("E") && dfs142.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ System.out.println("\n Deserialization of JDK1.4.2 Object from the current JDK: Passed."); - logln(" Deserialization of JDK1.4.2 Object from the current JDK: Passed."); + System.out.println(" Deserialization of JDK1.4.2 Object from the current JDK: Passed."); } else { - errln(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" + fail(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator()); /* * logically should not throw this exception as errln throws exception @@ -79,9 +80,9 @@ public void TestDFSSerialization(){ if (dfsValid.getExponentSeparator().equals("*SpecialExponentSeparator*") && dfsValid.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); - logln(" Deserialization of current JDK Object from the current JDK: Passed."); + System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); } else { - errln(" Deserialization of current JDK Object from the current JDK was Failed:" + fail(" Deserialization of current JDK Object from the current JDK was Failed:" +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator()); /* * logically should not throw this exception as errln throws exception @@ -102,11 +103,11 @@ public void TestDFSSerialization(){ } catch (NullPointerException npe){ npePassed = true; System.out.println(" Trying to set exponent separator with null: Passed."); - logln(" Trying to set exponent separator with null: Passed."); + System.out.println(" Trying to set exponent separator with null: Passed."); } if (!npePassed){ System.out.println(" Trying to set exponent separator with null:Failed."); - errln(" Trying to set exponent separator with null:Failed."); + fail(" Trying to set exponent separator with null:Failed."); /* * logically should not throw this exception as errln throws exception * if not thrown yet - but in case errln got changed @@ -124,7 +125,7 @@ private DecimalFormatSymbols readTestObject(File inputFile){ DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject(); return dfs; } catch (Exception e) { - errln("Test Malfunction in DFSSerialization: Exception while reading the object"); + fail("Test Malfunction in DFSSerialization: Exception while reading the object"); /* * logically should not throw this exception as errln throws exception * if not thrown yet - but in case errln got changed @@ -137,8 +138,8 @@ private File createTestObject(String objectName, String expString){ DecimalFormatSymbols dfs= new DecimalFormatSymbols(); dfs.setExponentSeparator(expString); dfs.setCurrencySymbol("*SpecialCurrencySymbol*"); - logln(" The special exponent separator is set : " + dfs.getExponentSeparator()); - logln(" The special currency symbol is set : " + dfs.getCurrencySymbol()); + System.out.println(" The special exponent separator is set : " + dfs.getExponentSeparator()); + System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); // 6345659: create a test object in the test.class dir where test user has a write permission. File file = new File(System.getProperty("test.class", "."), objectName); @@ -148,7 +149,7 @@ private File createTestObject(String objectName, String expString){ //System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); return file; } catch (Exception e){ - errln("Test Malfunction in DFSSerialization: Exception while creating an object"); + fail("Test Malfunction in DFSSerialization: Exception while creating an object"); /* * logically should not throw this exception as errln throws exception * if not thrown yet - but in case errln got changed diff --git a/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java b/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java index fcda5b863b4..8234ae8a163 100644 --- a/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java +++ b/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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,8 +23,8 @@ /* * @test - * @library /java/text/testlib * @summary test International Decimal Format API + * @run junit IntlTestDecimalFormatAPI */ /* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved @@ -41,23 +41,24 @@ import java.text.*; import java.util.*; -public class IntlTestDecimalFormatAPI extends IntlTest -{ - public static void main(String[] args) throws Exception { - new IntlTestDecimalFormatAPI().run(args); - } +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class IntlTestDecimalFormatAPI +{ // This test checks various generic API methods in DecimalFormat to achieve 100% API coverage. + @Test public void TestAPI() { Locale reservedLocale = Locale.getDefault(); try { - logln("DecimalFormat API test---"); logln(""); + System.out.println("DecimalFormat API test---"); System.out.println(""); Locale.setDefault(Locale.ENGLISH); // ======= Test constructors - logln("Testing DecimalFormat constructors"); + System.out.println("Testing DecimalFormat constructors"); DecimalFormat def = new DecimalFormat(); @@ -67,7 +68,7 @@ public void TestAPI() pat = new DecimalFormat(pattern); } catch (IllegalArgumentException e) { - errln("ERROR: Could not create DecimalFormat (pattern)"); + fail("ERROR: Could not create DecimalFormat (pattern)"); } DecimalFormatSymbols symbols = @@ -77,16 +78,16 @@ public void TestAPI() // ======= Test clone(), assignment, and equality - logln("Testing clone() and equality operators"); + System.out.println("Testing clone() and equality operators"); Format clone = (Format) def.clone(); if( ! def.equals(clone)) { - errln("ERROR: Clone() failed"); + fail("ERROR: Clone() failed"); } // ======= Test various format() methods - logln("Testing various format() methods"); + System.out.println("Testing various format() methods"); // final double d = -10456.0037; // this appears as // -10456.003700000001 on NT @@ -94,7 +95,7 @@ public void TestAPI() // -1.0456003700000002E-4 on NT final double d = -10456.00370000000000; // this works! final long l = 100000000; - logln("" + d + " is the double value"); + System.out.println("" + d + " is the double value"); StringBuffer res1 = new StringBuffer(); StringBuffer res2 = new StringBuffer(); @@ -106,20 +107,20 @@ public void TestAPI() FieldPosition pos4 = new FieldPosition(0); res1 = def.format(d, res1, pos1); - logln("" + d + " formatted to " + res1); + System.out.println("" + d + " formatted to " + res1); res2 = pat.format(l, res2, pos2); - logln("" + l + " formatted to " + res2); + System.out.println("" + l + " formatted to " + res2); res3 = cust1.format(d, res3, pos3); - logln("" + d + " formatted to " + res3); + System.out.println("" + d + " formatted to " + res3); res4 = cust1.format(l, res4, pos4); - logln("" + l + " formatted to " + res4); + System.out.println("" + l + " formatted to " + res4); // ======= Test parse() - logln("Testing parse()"); + System.out.println("Testing parse()"); String text = new String("-10,456.0037"); ParsePosition pos = new ParsePosition(0); @@ -127,109 +128,109 @@ public void TestAPI() pat.applyPattern(patt); double d2 = pat.parse(text, pos).doubleValue(); if(d2 != d) { - errln("ERROR: Roundtrip failed (via parse(" + + fail("ERROR: Roundtrip failed (via parse(" + d2 + " != " + d + ")) for " + text); } - logln(text + " parsed into " + (long) d2); + System.out.println(text + " parsed into " + (long) d2); // ======= Test getters and setters - logln("Testing getters and setters"); + System.out.println("Testing getters and setters"); final DecimalFormatSymbols syms = pat.getDecimalFormatSymbols(); def.setDecimalFormatSymbols(syms); if(!pat.getDecimalFormatSymbols().equals( def.getDecimalFormatSymbols())) { - errln("ERROR: set DecimalFormatSymbols() failed"); + fail("ERROR: set DecimalFormatSymbols() failed"); } String posPrefix; pat.setPositivePrefix("+"); posPrefix = pat.getPositivePrefix(); - logln("Positive prefix (should be +): " + posPrefix); + System.out.println("Positive prefix (should be +): " + posPrefix); if(posPrefix != "+") { - errln("ERROR: setPositivePrefix() failed"); + fail("ERROR: setPositivePrefix() failed"); } String negPrefix; pat.setNegativePrefix("-"); negPrefix = pat.getNegativePrefix(); - logln("Negative prefix (should be -): " + negPrefix); + System.out.println("Negative prefix (should be -): " + negPrefix); if(negPrefix != "-") { - errln("ERROR: setNegativePrefix() failed"); + fail("ERROR: setNegativePrefix() failed"); } String posSuffix; pat.setPositiveSuffix("_"); posSuffix = pat.getPositiveSuffix(); - logln("Positive suffix (should be _): " + posSuffix); + System.out.println("Positive suffix (should be _): " + posSuffix); if(posSuffix != "_") { - errln("ERROR: setPositiveSuffix() failed"); + fail("ERROR: setPositiveSuffix() failed"); } String negSuffix; pat.setNegativeSuffix("~"); negSuffix = pat.getNegativeSuffix(); - logln("Negative suffix (should be ~): " + negSuffix); + System.out.println("Negative suffix (should be ~): " + negSuffix); if(negSuffix != "~") { - errln("ERROR: setNegativeSuffix() failed"); + fail("ERROR: setNegativeSuffix() failed"); } long multiplier = 0; pat.setMultiplier(8); multiplier = pat.getMultiplier(); - logln("Multiplier (should be 8): " + multiplier); + System.out.println("Multiplier (should be 8): " + multiplier); if(multiplier != 8) { - errln("ERROR: setMultiplier() failed"); + fail("ERROR: setMultiplier() failed"); } int groupingSize = 0; pat.setGroupingSize(2); groupingSize = pat.getGroupingSize(); - logln("Grouping size (should be 2): " + (long) groupingSize); + System.out.println("Grouping size (should be 2): " + (long) groupingSize); if(groupingSize != 2) { - errln("ERROR: setGroupingSize() failed"); + fail("ERROR: setGroupingSize() failed"); } pat.setDecimalSeparatorAlwaysShown(true); boolean tf = pat.isDecimalSeparatorAlwaysShown(); - logln("DecimalSeparatorIsAlwaysShown (should be true) is " + + System.out.println("DecimalSeparatorIsAlwaysShown (should be true) is " + (tf ? "true" : "false")); if(tf != true) { - errln("ERROR: setDecimalSeparatorAlwaysShown() failed"); + fail("ERROR: setDecimalSeparatorAlwaysShown() failed"); } String funkyPat; funkyPat = pat.toPattern(); - logln("Pattern is " + funkyPat); + System.out.println("Pattern is " + funkyPat); String locPat; locPat = pat.toLocalizedPattern(); - logln("Localized pattern is " + locPat); + System.out.println("Localized pattern is " + locPat); // ======= Test applyPattern() - logln("Testing applyPattern()"); + System.out.println("Testing applyPattern()"); String p1 = new String("#,##0.0#;(#,##0.0#)"); - logln("Applying pattern " + p1); + System.out.println("Applying pattern " + p1); pat.applyPattern(p1); String s2; s2 = pat.toPattern(); - logln("Extracted pattern is " + s2); + System.out.println("Extracted pattern is " + s2); if( ! s2.equals(p1) ) { - errln("ERROR: toPattern() result did not match " + + fail("ERROR: toPattern() result did not match " + "pattern applied"); } String p2 = new String("#,##0.0# FF;(#,##0.0# FF)"); - logln("Applying pattern " + p2); + System.out.println("Applying pattern " + p2); pat.applyLocalizedPattern(p2); String s3; s3 = pat.toLocalizedPattern(); - logln("Extracted pattern is " + s3); + System.out.println("Extracted pattern is " + s3); if( ! s3.equals(p2) ) { - errln("ERROR: toLocalizedPattern() result did not match " + + fail("ERROR: toLocalizedPattern() result did not match " + "pattern applied"); } diff --git a/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java b/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java index 30905ee46f1..75c9199c95b 100644 --- a/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java +++ b/test/jdk/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -24,8 +24,8 @@ /* * @test * @bug 8282625 - * @library /java/text/testlib * @summary test International Decimal Format Symbols + * @run junit IntlTestDecimalFormatSymbols */ /* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved @@ -42,13 +42,14 @@ import java.text.*; import java.util.*; -public class IntlTestDecimalFormatSymbols extends IntlTest -{ - public static void main(String[] args) throws Exception { - new IntlTestDecimalFormatSymbols().run(args); - } +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class IntlTestDecimalFormatSymbols +{ // Test the API of DecimalFormatSymbols; primarily a simple get/set set. + @Test public void TestSymbols() { DecimalFormatSymbols fr = new DecimalFormatSymbols(Locale.FRENCH); @@ -56,79 +57,79 @@ public void TestSymbols() DecimalFormatSymbols en = new DecimalFormatSymbols(Locale.ENGLISH); if(en.equals(fr)) { - errln("ERROR: English DecimalFormatSymbols equal to French"); + fail("ERROR: English DecimalFormatSymbols equal to French"); } // just do some VERY basic tests to make sure that get/set work if (!fr.getLocale().equals(Locale.FRENCH)) { - errln("ERROR: French DecimalFormatSymbols not Locale.FRENCH"); + fail("ERROR: French DecimalFormatSymbols not Locale.FRENCH"); } if (!en.getLocale().equals(Locale.ENGLISH)) { - errln("ERROR: English DecimalFormatSymbols not Locale.ENGLISH"); + fail("ERROR: English DecimalFormatSymbols not Locale.ENGLISH"); } char zero = en.getZeroDigit(); fr.setZeroDigit(zero); if(fr.getZeroDigit() != en.getZeroDigit()) { - errln("ERROR: get/set ZeroDigit failed"); + fail("ERROR: get/set ZeroDigit failed"); } char group = en.getGroupingSeparator(); fr.setGroupingSeparator(group); if(fr.getGroupingSeparator() != en.getGroupingSeparator()) { - errln("ERROR: get/set GroupingSeparator failed"); + fail("ERROR: get/set GroupingSeparator failed"); } char decimal = en.getDecimalSeparator(); fr.setDecimalSeparator(decimal); if(fr.getDecimalSeparator() != en.getDecimalSeparator()) { - errln("ERROR: get/set DecimalSeparator failed"); + fail("ERROR: get/set DecimalSeparator failed"); } char perMill = en.getPerMill(); fr.setPerMill(perMill); if(fr.getPerMill() != en.getPerMill()) { - errln("ERROR: get/set PerMill failed"); + fail("ERROR: get/set PerMill failed"); } char percent = en.getPercent(); fr.setPercent(percent); if(fr.getPercent() != en.getPercent()) { - errln("ERROR: get/set Percent failed"); + fail("ERROR: get/set Percent failed"); } char digit = en.getDigit(); fr.setDigit(digit); if(fr.getPercent() != en.getPercent()) { - errln("ERROR: get/set Percent failed"); + fail("ERROR: get/set Percent failed"); } char patternSeparator = en.getPatternSeparator(); fr.setPatternSeparator(patternSeparator); if(fr.getPatternSeparator() != en.getPatternSeparator()) { - errln("ERROR: get/set PatternSeparator failed"); + fail("ERROR: get/set PatternSeparator failed"); } String infinity = en.getInfinity(); fr.setInfinity(infinity); String infinity2 = fr.getInfinity(); if(! infinity.equals(infinity2)) { - errln("ERROR: get/set Infinity failed"); + fail("ERROR: get/set Infinity failed"); } String nan = en.getNaN(); fr.setNaN(nan); String nan2 = fr.getNaN(); if(! nan.equals(nan2)) { - errln("ERROR: get/set NaN failed"); + fail("ERROR: get/set NaN failed"); } char minusSign = en.getMinusSign(); fr.setMinusSign(minusSign); if(fr.getMinusSign() != en.getMinusSign()) { - errln("ERROR: get/set MinusSign failed"); + fail("ERROR: get/set MinusSign failed"); } // char exponential = en.getExponentialSymbol(); @@ -142,7 +143,7 @@ public void TestSymbols() en = (DecimalFormatSymbols) fr.clone(); if(! en.equals(fr)) { - errln("ERROR: Clone failed"); + fail("ERROR: Clone failed"); } } } diff --git a/test/jdk/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java b/test/jdk/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java index 011db2bdea3..73b2a2d3d1a 100644 --- a/test/jdk/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java +++ b/test/jdk/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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,9 +23,9 @@ /* * @test - * @library /java/text/testlib * @summary test International Number Format API * @modules jdk.localedata + * @run junit IntlTestNumberFormatAPI */ /* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved @@ -42,23 +42,24 @@ import java.text.*; import java.util.*; -public class IntlTestNumberFormatAPI extends IntlTest -{ - public static void main(String[] args) throws Exception { - new IntlTestNumberFormatAPI().run(args); - } +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class IntlTestNumberFormatAPI +{ // This test checks various generic API methods in DecimalFormat to achieve 100% API coverage. + @Test public void TestAPI() { Locale reservedLocale = Locale.getDefault(); try { - logln("NumberFormat API test---"); logln(""); + System.out.println("NumberFormat API test---"); System.out.println(""); Locale.setDefault(Locale.ENGLISH); // ======= Test constructors - logln("Testing NumberFormat constructors"); + System.out.println("Testing NumberFormat constructors"); NumberFormat def = NumberFormat.getInstance(); @@ -76,15 +77,15 @@ public void TestAPI() // ======= Test equality - logln("Testing equality operator"); + System.out.println("Testing equality operator"); if( per_fr.equals(cur_fr) ) { - errln("ERROR: == failed"); + fail("ERROR: == failed"); } // ======= Test various format() methods - logln("Testing various format() methods"); + System.out.println("Testing various format() methods"); // final double d = -10456.0037; // this appears as // -10456.003700000001 on NT @@ -105,27 +106,27 @@ public void TestAPI() FieldPosition pos4 = new FieldPosition(0); res1 = cur_fr.format(d); - logln( "" + d + " formatted to " + res1); + System.out.println( "" + d + " formatted to " + res1); res2 = cur_fr.format(l); - logln("" + l + " formatted to " + res2); + System.out.println("" + l + " formatted to " + res2); res3 = cur_fr.format(d, res3, pos1); - logln( "" + d + " formatted to " + res3); + System.out.println( "" + d + " formatted to " + res3); res4 = cur_fr.format(l, res4, pos2); - logln("" + l + " formatted to " + res4); + System.out.println("" + l + " formatted to " + res4); res5 = cur_fr.format(d, res5, pos3); - logln("" + d + " formatted to " + res5); + System.out.println("" + d + " formatted to " + res5); res6 = cur_fr.format(l, res6, pos4); - logln("" + l + " formatted to " + res6); + System.out.println("" + l + " formatted to " + res6); // ======= Test parse() - logln("Testing parse()"); + System.out.println("Testing parse()"); // String text = new String("-10,456.0037"); String text = new String("-10456,0037"); @@ -133,70 +134,70 @@ public void TestAPI() ParsePosition pos01 = new ParsePosition(0); double d1 = ((Number)fr.parseObject(text, pos)).doubleValue(); if(d1 != d) { - errln("ERROR: Roundtrip failed (via parse()) for " + text); + fail("ERROR: Roundtrip failed (via parse()) for " + text); } - logln(text + " parsed into " + d1); + System.out.println(text + " parsed into " + d1); double d2 = fr.parse(text, pos01).doubleValue(); if(d2 != d) { - errln("ERROR: Roundtrip failed (via parse()) for " + text); + fail("ERROR: Roundtrip failed (via parse()) for " + text); } - logln(text + " parsed into " + d2); + System.out.println(text + " parsed into " + d2); double d3 = 0; try { d3 = fr.parse(text).doubleValue(); } catch (ParseException e) { - errln("ERROR: parse() failed"); + fail("ERROR: parse() failed"); } if(d3 != d) { - errln("ERROR: Roundtrip failed (via parse()) for " + text); + fail("ERROR: Roundtrip failed (via parse()) for " + text); } - logln(text + " parsed into " + d3); + System.out.println(text + " parsed into " + d3); // ======= Test getters and setters - logln("Testing getters and setters"); + System.out.println("Testing getters and setters"); final Locale[] locales = NumberFormat.getAvailableLocales(); long count = locales.length; - logln("Got " + count + " locales" ); + System.out.println("Got " + count + " locales" ); for(int i = 0; i < count; i++) { String name; name = locales[i].getDisplayName(); - logln(name); + System.out.println(name); } fr.setParseIntegerOnly( def.isParseIntegerOnly() ); if(fr.isParseIntegerOnly() != def.isParseIntegerOnly() ) { - errln("ERROR: setParseIntegerOnly() failed"); + fail("ERROR: setParseIntegerOnly() failed"); } fr.setGroupingUsed( def.isGroupingUsed() ); if(fr.isGroupingUsed() != def.isGroupingUsed() ) { - errln("ERROR: setGroupingUsed() failed"); + fail("ERROR: setGroupingUsed() failed"); } fr.setMaximumIntegerDigits( def.getMaximumIntegerDigits() ); if(fr.getMaximumIntegerDigits() != def.getMaximumIntegerDigits() ) { - errln("ERROR: setMaximumIntegerDigits() failed"); + fail("ERROR: setMaximumIntegerDigits() failed"); } fr.setMinimumIntegerDigits( def.getMinimumIntegerDigits() ); if(fr.getMinimumIntegerDigits() != def.getMinimumIntegerDigits() ) { - errln("ERROR: setMinimumIntegerDigits() failed"); + fail("ERROR: setMinimumIntegerDigits() failed"); } fr.setMaximumFractionDigits( def.getMaximumFractionDigits() ); if(fr.getMaximumFractionDigits() != def.getMaximumFractionDigits() ) { - errln("ERROR: setMaximumFractionDigits() failed"); + fail("ERROR: setMaximumFractionDigits() failed"); } fr.setMinimumFractionDigits( def.getMinimumFractionDigits() ); if(fr.getMinimumFractionDigits() != def.getMinimumFractionDigits() ) { - errln("ERROR: setMinimumFractionDigits() failed"); + fail("ERROR: setMinimumFractionDigits() failed"); } // ======= Test getStaticClassID() diff --git a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java index 820b965f7e4..3ef134ee4dd 100644 --- a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java +++ b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -32,11 +32,11 @@ * 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 * @summary Regression tests for NumberFormat and associated classes * @library /java/text/testlib - * @build IntlTest HexDumpReader TestUtils + * @build HexDumpReader TestUtils * @modules java.base/sun.util.resources * jdk.localedata * @compile -XDignore.symbol.file NumberRegression.java - * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberRegression + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI NumberRegression */ /* @@ -58,23 +58,24 @@ import java.math.BigInteger; import sun.util.resources.LocaleData; -public class NumberRegression extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new NumberRegression().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class NumberRegression { /** * NumberFormat.equals comparing with null should always return false. */ + @Test public void Test4075713(){ try { MyNumberFormatTest tmp = new MyNumberFormatTest(); if (!tmp.equals(null)) - logln("NumberFormat.equals passed"); + System.out.println("NumberFormat.equals passed"); } catch (NullPointerException e) { - errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); + fail("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); } } @@ -82,6 +83,7 @@ public void Test4075713(){ * NumberFormat.equals comparing two obj equal even the setGroupingUsed * flag is different. */ + @Test public void Test4074620() { MyNumberFormatTest nf1 = new MyNumberFormatTest(); @@ -90,8 +92,8 @@ public void Test4074620() { nf1.setGroupingUsed(false); nf2.setGroupingUsed(true); - if (nf1.equals(nf2)) errln("Test for bug 4074620 failed"); - else logln("Test for bug 4074620 passed."); + if (nf1.equals(nf2)) fail("Test for bug 4074620 failed"); + else System.out.println("Test for bug 4074620 passed."); return; } @@ -100,10 +102,11 @@ public void Test4074620() { * DecimalFormat.format() incorrectly uses maxFractionDigits setting. */ + @Test public void Test4088161 (){ Locale locale = Locale.getDefault(); if (!TestUtils.usesAsciiDigits(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -113,39 +116,41 @@ public void Test4088161 (){ df.setMaximumFractionDigits(16); StringBuffer sBuf1 = new StringBuffer(""); FieldPosition fp1 = new FieldPosition(0); - logln("d = " + d); - logln("maxFractionDigits = " + df.getMaximumFractionDigits()); - logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'"); + System.out.println("d = " + d); + System.out.println("maxFractionDigits = " + df.getMaximumFractionDigits()); + System.out.println(" format(d) = '" + df.format(d, sBuf1, fp1) + "'"); df.setMaximumFractionDigits(17); StringBuffer sBuf2 = new StringBuffer(""); FieldPosition fp2 = new FieldPosition(0); - logln("maxFractionDigits = " + df.getMaximumFractionDigits()); + System.out.println("maxFractionDigits = " + df.getMaximumFractionDigits()); df.format(d, sBuf2, fp2); String expected = "100"; if (!sBuf2.toString().equals(expected)) - errln(" format(d) = '" + sBuf2 + "'"); + fail(" format(d) = '" + sBuf2 + "'"); } /** * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. * DecimalFormat(String, DecimalFormatSymbols). */ + @Test public void Test4087245 (){ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(); DecimalFormat df = new DecimalFormat("#,##0.0", symbols); long n = 123; StringBuffer buf1 = new StringBuffer(); StringBuffer buf2 = new StringBuffer(); - logln("format(" + n + ") = " + + System.out.println("format(" + n + ") = " + df.format(n, buf1, new FieldPosition(0))); symbols.setDecimalSeparator('p'); // change value of field - logln("format(" + n + ") = " + + System.out.println("format(" + n + ") = " + df.format(n, buf2, new FieldPosition(0))); if (!buf1.toString().equals(buf2.toString())) - errln("Test for bug 4087245 failed"); + fail("Test for bug 4087245 failed"); } /** * DecimalFormat.format() incorrectly formats 0.0 */ + @Test public void Test4087535 () { DecimalFormat df = new DecimalFormat(); @@ -155,31 +160,33 @@ public void Test4087535 () String buffer = new String(); buffer = df.format(n); if (buffer.length() == 0) - errln(n + ": '" + buffer + "'"); + fail(n + ": '" + buffer + "'"); n = 0.1; buffer = df.format(n); if (buffer.length() == 0) - errln(n + ": '" + buffer + "'"); + fail(n + ": '" + buffer + "'"); } /** * DecimalFormat.format fails when groupingSize is set to 0. */ + @Test public void Test4088503 (){ DecimalFormat df = new DecimalFormat(); df.setGroupingSize(0); StringBuffer sBuf = new StringBuffer(""); FieldPosition fp = new FieldPosition(0); try { - logln(df.format(123, sBuf, fp).toString()); + System.out.println(df.format(123, sBuf, fp).toString()); } catch (Exception foo) { - errln("Test for bug 4088503 failed."); + fail("Test for bug 4088503 failed."); } } /** * NumberFormat.getCurrencyInstance is wrong. */ + @Test public void Test4066646 () { float returnfloat = 0.0f; assignFloatValue(2.04f); @@ -190,42 +197,45 @@ public void Test4066646 () { public float assignFloatValue(float returnfloat) { - logln(" VALUE " + returnfloat); + System.out.println(" VALUE " + returnfloat); NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US); nfcommon.setGroupingUsed(false); String stringValue = nfcommon.format(returnfloat).substring(1); if (Float.valueOf(stringValue).floatValue() != returnfloat) - errln(" DISPLAYVALUE " + stringValue); + fail(" DISPLAYVALUE " + stringValue); return returnfloat; } // End Of assignFloatValue() /** * DecimalFormat throws exception when parsing "0" */ + @Test public void Test4059870() { DecimalFormat format = new DecimalFormat("00"); try { - logln(format.parse("0").toString()); - } catch (Exception e) { errln("Test for bug 4059870 failed : " + e); } + System.out.println(format.parse("0").toString()); + } catch (Exception e) { fail("Test for bug 4059870 failed : " + e); } } /** * DecimalFormatSymbol.equals should always return false when * comparing with null. */ + @Test public void Test4083018 (){ DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(); try { if (!dfs.equals(null)) - logln("Test Passed!"); + System.out.println("Test Passed!"); } catch (Exception foo) { - errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); + fail("Test for bug 4083018 failed => Message : " + foo.getMessage()); } } /** * DecimalFormat does not round up correctly. */ + @Test public void Test4071492 (){ Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -233,10 +243,10 @@ public void Test4071492 (){ NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(4); String out = nf.format(x); - logln("0.00159999 formats with 4 fractional digits to " + out); + System.out.println("0.00159999 formats with 4 fractional digits to " + out); String expected = "0.0016"; if (!out.equals(expected)) - errln("FAIL: Expected " + expected); + fail("FAIL: Expected " + expected); Locale.setDefault(savedLocale); } @@ -244,33 +254,34 @@ public void Test4071492 (){ * A space as a group separator for localized pattern causes * wrong format. WorkAround : use non-breaking space. */ + @Test public void Test4086575() { NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); - logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern()); - logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern()); + System.out.println("nf toPattern1: " + ((DecimalFormat)nf).toPattern()); + System.out.println("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern()); // No group separator - logln("...applyLocalizedPattern ###,00;(###,00) "); + System.out.println("...applyLocalizedPattern ###,00;(###,00) "); ((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)"); - logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); - logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); + System.out.println("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); + System.out.println("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); - logln("nf: " + nf.format(1234)); // 1234,00 - logln("nf: " + nf.format(-1234)); // (1234,00) + System.out.println("nf: " + nf.format(1234)); // 1234,00 + System.out.println("nf: " + nf.format(-1234)); // (1234,00) // Space as group separator - logln("...applyLocalizedPattern # ###,00;(# ###,00) "); + System.out.println("...applyLocalizedPattern # ###,00;(# ###,00) "); ((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); - logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); - logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); + System.out.println("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); + System.out.println("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); String buffer = nf.format(1234); if (!buffer.equals("1\u00a0234,00")) - errln("nf : " + buffer); // Expect 1 234,00 + fail("nf : " + buffer); // Expect 1 234,00 buffer = nf.format(-1234); if (!buffer.equals("(1\u00a0234,00)")) - errln("nf : " + buffer); // Expect (1 234,00) + fail("nf : " + buffer); // Expect (1 234,00) // Erroneously prints: // 1234,00 , @@ -280,16 +291,17 @@ public void Test4086575() { /** * DecimalFormat.parse returns wrong value */ + @Test public void Test4068693() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); - logln("----- Test Application -----"); + System.out.println("----- Test Application -----"); ParsePosition pos; DecimalFormat df = new DecimalFormat(); Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0)); if (!d.toString().equals("123.55456")) { - errln("Result -> " + d); + fail("Result -> " + d); } Locale.setDefault(savedLocale); } @@ -298,53 +310,56 @@ public void Test4068693() * null pointer thrown when accessing a deserialized DecimalFormat * object. */ + @Test public void Test4069754() { try { myformat it = new myformat(); - logln(it.Now()); + System.out.println(it.Now()); FileOutputStream ostream = new FileOutputStream("t.tmp"); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeObject(it); ostream.close(); - logln("Saved ok."); + System.out.println("Saved ok."); FileInputStream istream = new FileInputStream("t.tmp"); ObjectInputStream p2 = new ObjectInputStream(istream); myformat it2 = (myformat)p2.readObject(); - logln(it2.Now()); + System.out.println(it2.Now()); istream.close(); - logln("Loaded ok."); + System.out.println("Loaded ok."); } catch (Exception foo) { - errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); + fail("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); } } /** * DecimalFormat.applyPattern(String) allows illegal patterns */ + @Test public void Test4087251 (){ DecimalFormat df = new DecimalFormat(); try { df.applyPattern("#.#.#"); - logln("toPattern() returns \"" + df.toPattern() + "\""); - errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); + System.out.println("toPattern() returns \"" + df.toPattern() + "\""); + fail("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); } catch (IllegalArgumentException e) { - logln("Caught Illegal Argument Error !"); + System.out.println("Caught Illegal Argument Error !"); } // Second test; added 5/11/98 when reported to fail on 1.2b3 try { df.applyPattern("#0.0#0#0"); - logln("toPattern() returns \"" + df.toPattern() + "\""); - errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); + System.out.println("toPattern() returns \"" + df.toPattern() + "\""); + fail("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); } catch (IllegalArgumentException e) { - logln("Ok - IllegalArgumentException for #0.0#0#0"); + System.out.println("Ok - IllegalArgumentException for #0.0#0#0"); } } /** * DecimalFormat.format() loses precision */ + @Test public void Test4090489 (){ Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -355,11 +370,11 @@ public void Test4090489 (){ BigDecimal bd = new BigDecimal(d); StringBuffer sb = new StringBuffer(""); FieldPosition fp = new FieldPosition(0); - logln("d = " + d); - logln("BigDecimal.toString(): " + bd.toString()); + System.out.println("d = " + d); + System.out.println("BigDecimal.toString(): " + bd.toString()); df.format(d, sb, fp); if (!sb.toString().equals("10000000.0000000100")) { - errln("DecimalFormat.format(): " + sb.toString()); + fail("DecimalFormat.format(): " + sb.toString()); } Locale.setDefault(savedLocale); } @@ -367,10 +382,11 @@ public void Test4090489 (){ /** * DecimalFormat.format() loses precision */ + @Test public void Test4090504 () { double d = 1; - logln("d = " + d); + System.out.println("d = " + d); DecimalFormat df = new DecimalFormat(); StringBuffer sb; FieldPosition fp; @@ -379,16 +395,17 @@ public void Test4090504 () df.setMaximumFractionDigits(i); sb = new StringBuffer(""); fp = new FieldPosition(0); - logln(" getMaximumFractionDigits() = " + i); - logln(" formated: " + df.format(d, sb, fp)); + System.out.println(" getMaximumFractionDigits() = " + i); + System.out.println(" formated: " + df.format(d, sb, fp)); } } catch (Exception foo) { - errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); + fail("Bug 4090504 regression test failed. Message : " + foo.getMessage()); } } /** * DecimalFormat.parse(String str, ParsePosition pp) loses precision */ + @Test public void Test4095713 () { Locale savedLocale = Locale.getDefault(); @@ -397,15 +414,16 @@ public void Test4095713 () String str = "0.1234"; Double d1 = 0.1234; Double d2 = (Double) df.parse(str, new ParsePosition(0)); - logln(d1.toString()); + System.out.println(d1.toString()); if (d2.doubleValue() != d1.doubleValue()) - errln("Bug 4095713 test failed, new double value : " + d2); + fail("Bug 4095713 test failed, new double value : " + d2); Locale.setDefault(savedLocale); } /** * DecimalFormat.parse() fails when multiplier is not set to 1 */ + @Test public void Test4092561 () { Locale savedLocale = Locale.getDefault(); @@ -413,32 +431,32 @@ public void Test4092561 () DecimalFormat df = new DecimalFormat(); String str = Long.toString(Long.MIN_VALUE); - logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); + System.out.println("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); df.setMultiplier(100); Number num = df.parse(str, new ParsePosition(0)); if (num.doubleValue() != -9.223372036854776E16) { - errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); + fail("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); } df.setMultiplier(-100); num = df.parse(str, new ParsePosition(0)); if (num.doubleValue() != 9.223372036854776E16) { - errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); + fail("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); } str = Long.toString(Long.MAX_VALUE); - logln("Long.MAX_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); + System.out.println("Long.MAX_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); df.setMultiplier(100); num = df.parse(str, new ParsePosition(0)); if (num.doubleValue() != 9.223372036854776E16) { - errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); + fail("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); } df.setMultiplier(-100); num = df.parse(str, new ParsePosition(0)); if (num.doubleValue() != -9.223372036854776E16) { - errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); + fail("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); } Locale.setDefault(savedLocale); @@ -447,6 +465,7 @@ public void Test4092561 () /** * DecimalFormat: Negative format ignored. */ + @Test public void Test4092480 () { DecimalFormat dfFoo = new DecimalFormat("000"); @@ -454,28 +473,28 @@ public void Test4092480 () try { dfFoo.applyPattern("0000;-000"); if (!dfFoo.toPattern().equals("#0000")) - errln("dfFoo.toPattern : " + dfFoo.toPattern()); - logln(dfFoo.format(42)); - logln(dfFoo.format(-42)); + fail("dfFoo.toPattern : " + dfFoo.toPattern()); + System.out.println(dfFoo.format(42)); + System.out.println(dfFoo.format(-42)); dfFoo.applyPattern("000;-000"); if (!dfFoo.toPattern().equals("#000")) - errln("dfFoo.toPattern : " + dfFoo.toPattern()); - logln(dfFoo.format(42)); - logln(dfFoo.format(-42)); + fail("dfFoo.toPattern : " + dfFoo.toPattern()); + System.out.println(dfFoo.format(42)); + System.out.println(dfFoo.format(-42)); dfFoo.applyPattern("000;-0000"); if (!dfFoo.toPattern().equals("#000")) - errln("dfFoo.toPattern : " + dfFoo.toPattern()); - logln(dfFoo.format(42)); - logln(dfFoo.format(-42)); + fail("dfFoo.toPattern : " + dfFoo.toPattern()); + System.out.println(dfFoo.format(42)); + System.out.println(dfFoo.format(-42)); dfFoo.applyPattern("0000;-000"); if (!dfFoo.toPattern().equals("#0000")) - errln("dfFoo.toPattern : " + dfFoo.toPattern()); - logln(dfFoo.format(42)); - logln(dfFoo.format(-42)); + fail("dfFoo.toPattern : " + dfFoo.toPattern()); + System.out.println(dfFoo.format(42)); + System.out.println(dfFoo.format(-42)); } catch (Exception foo) { - errln("Message " + foo.getMessage()); + fail("Message " + foo.getMessage()); } } /** @@ -486,6 +505,7 @@ public void Test4092480 () * never contain the monetary separator! Decimal separator in pattern is * interpreted as monetary separator if currency symbol is seen! */ + @Test public void Test4087244 () { Locale de = Locale.of("pt", "PT"); DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de); @@ -496,7 +516,7 @@ public void Test4087244 () { char monSep = sym.getMonetaryDecimalSeparator(); char zero = sym.getZeroDigit(); if (decSep == monSep) { - errln("ERROR in test: want decimal sep != monetary sep"); + fail("ERROR in test: want decimal sep != monetary sep"); } else { df.setMinimumIntegerDigits(1); df.setMinimumFractionDigits(2); @@ -504,10 +524,10 @@ public void Test4087244 () { String monStr = "1" + monSep + "23"; String decStr = "1" + decSep + "23"; if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) { - logln("OK: 1.23 -> \"" + str + "\" contains \"" + + System.out.println("OK: 1.23 -> \"" + str + "\" contains \"" + monStr + "\" and not \"" + decStr + '"'); } else { - errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" + + fail("FAIL: 1.23 -> \"" + str + "\", should contain \"" + monStr + "\" and not \"" + decStr + '"'); } @@ -516,6 +536,7 @@ public void Test4087244 () { /** * Number format data rounding errors for locale FR */ + @Test public void Test4070798 () { NumberFormat formatter; String tempString; @@ -533,9 +554,9 @@ public void Test4070798 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedDefault)) { - logln ("Bug 4070798 default test passed."); + System.out.println("Bug 4070798 default test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedDefault + " Received " + tempString ); } @@ -545,9 +566,9 @@ public void Test4070798 () { tempString = formatter.format( 5789.9876 ); if (tempString.equals(expectedCurrency) ) { - logln ("Bug 4070798 currency test assed."); + System.out.println("Bug 4070798 currency test assed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedCurrency + " Received " + tempString ); } @@ -557,9 +578,9 @@ public void Test4070798 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedPercent) ) { - logln ("Bug 4070798 percentage test passed."); + System.out.println("Bug 4070798 percentage test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedPercent + " Received " + tempString ); } @@ -567,6 +588,7 @@ public void Test4070798 () { /** * Data rounding errors for French (Canada) locale */ + @Test public void Test4071005 () { NumberFormat formatter; @@ -584,9 +606,9 @@ public void Test4071005 () { formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH); tempString = formatter.format (-5789.9876); if (tempString.equals(expectedDefault)) { - logln ("Bug 4071005 default test passed."); + System.out.println("Bug 4071005 default test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedDefault + " Received " + tempString ); } @@ -595,9 +617,9 @@ public void Test4071005 () { tempString = formatter.format( 5789.9876 ) ; if (tempString.equals(expectedCurrency) ) { - logln ("Bug 4071005 currency test passed."); + System.out.println("Bug 4071005 currency test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedCurrency + " Received " + tempString ); } @@ -605,9 +627,9 @@ public void Test4071005 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedPercent) ) { - logln ("Bug 4071005 percentage test passed."); + System.out.println("Bug 4071005 percentage test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedPercent + " Received " + tempString ); } @@ -616,6 +638,7 @@ public void Test4071005 () { /** * Data rounding errors for German (Germany) locale */ + @Test public void Test4071014 () { NumberFormat formatter; String tempString; @@ -632,9 +655,9 @@ public void Test4071014 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedDefault)) { - logln ("Bug 4071014 default test passed."); + System.out.println("Bug 4071014 default test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedDefault + " Received " + tempString ); } @@ -643,9 +666,9 @@ public void Test4071014 () { tempString = formatter.format( 5789.9876 ) ; if (tempString.equals(expectedCurrency) ) { - logln ("Bug 4071014 currency test passed."); + System.out.println("Bug 4071014 currency test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedCurrency + " Received " + tempString ); } @@ -654,9 +677,9 @@ public void Test4071014 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedPercent) ) { - logln ("Bug 4071014 percentage test passed."); + System.out.println("Bug 4071014 percentage test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedPercent + " Received " + tempString ); } @@ -665,6 +688,7 @@ public void Test4071014 () { /** * Data rounding errors for Italian locale number formats */ + @Test public void Test4071859 () { NumberFormat formatter; String tempString; @@ -681,9 +705,9 @@ public void Test4071859 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedDefault)) { - logln ("Bug 4071859 default test passed."); + System.out.println("Bug 4071859 default test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedDefault + " Received " + tempString ); } @@ -692,9 +716,9 @@ public void Test4071859 () { tempString = formatter.format( -5789.9876 ) ; if (tempString.equals(expectedCurrency) ) { - logln ("Bug 4071859 currency test passed."); + System.out.println("Bug 4071859 currency test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedCurrency + " Received " + tempString ); } @@ -703,9 +727,9 @@ public void Test4071859 () { tempString = formatter.format (-5789.9876); if (tempString.equals(expectedPercent) ) { - logln ("Bug 4071859 percentage test passed."); + System.out.println("Bug 4071859 percentage test passed."); } else { - errln("Failed:" + + fail("Failed:" + " Expected " + expectedPercent + " Received " + tempString ); } @@ -715,6 +739,7 @@ public void Test4071859 () { /* bug 4071859 * Test rounding for nearest even. */ + @Test public void Test4093610() { Locale savedLocale = Locale.getDefault(); @@ -739,20 +764,21 @@ public void Test4093610() void roundingTest(DecimalFormat df, double x, String expected) { String out = df.format(x); - logln("" + x + " formats with 1 fractional digits to " + out); - if (!out.equals(expected)) errln("FAIL: Expected " + expected); + System.out.println("" + x + " formats with 1 fractional digits to " + out); + if (!out.equals(expected)) fail("FAIL: Expected " + expected); } /** * Tests the setMaximumFractionDigits limit. */ + @Test public void Test4098741() { try { NumberFormat fmt = NumberFormat.getPercentInstance(); fmt.setMaximumFractionDigits(20); - logln(fmt.format(.001)); + System.out.println(fmt.format(.001)); } catch (Exception foo) { - errln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); + fail("Bug 4098471 failed with exception thrown : " + foo.getMessage()); } } /** @@ -760,19 +786,20 @@ public void Test4098741() * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. * Part2 has been fixed. */ + @Test public void Test4074454() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); try { DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#"); - logln("Inconsistent negative pattern is fine."); + System.out.println("Inconsistent negative pattern is fine."); DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces"); String tempString = newFmt.format(3456.78); if (!tempString.equals("3,456.78 p'ieces")) - errln("Failed! 3,456.78 p'ieces expected, but got : " + tempString); + fail("Failed! 3,456.78 p'ieces expected, but got : " + tempString); } catch (Exception foo) { - errln("An exception was thrown for any inconsistent negative pattern."); + fail("An exception was thrown for any inconsistent negative pattern."); } Locale.setDefault(savedLocale); } @@ -796,46 +823,50 @@ public void Test4074454() * Otherwise, an IllegalArgumentException will be thrown when formatting * "January 35". See GregorianCalendar class javadoc for more details. */ + @Test public void Test4099404() { try { DecimalFormat fmt = new DecimalFormat("000.0#0"); - errln("Bug 4099404 failed applying illegal pattern \"000.0#0\""); + fail("Bug 4099404 failed applying illegal pattern \"000.0#0\""); } catch (Exception foo) { - logln("Bug 4099404 pattern \"000.0#0\" passed"); + System.out.println("Bug 4099404 pattern \"000.0#0\" passed"); } try { DecimalFormat fmt = new DecimalFormat("0#0.000"); - errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); + fail("Bug 4099404 failed applying illegal pattern \"0#0.000\""); } catch (Exception foo) { - logln("Bug 4099404 pattern \"0#0.000\" passed"); + System.out.println("Bug 4099404 pattern \"0#0.000\" passed"); } } /** * DecimalFormat.applyPattern doesn't set minimum integer digits */ + @Test public void Test4101481() { DecimalFormat sdf = new DecimalFormat("#,##0"); if (sdf.getMinimumIntegerDigits() != 1) - errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits()); + fail("Minimum integer digits : " + sdf.getMinimumIntegerDigits()); } /** * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). */ + @Test public void Test4052223() { try { DecimalFormat fmt = new DecimalFormat("#,#00.00"); Number num = fmt.parse("abc3"); - errln("Bug 4052223 failed : can't parse string \"a\". Got " + num); + fail("Bug 4052223 failed : can't parse string \"a\". Got " + num); } catch (ParseException foo) { - logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); + System.out.println("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); } } /** * API tests for API addition request A9. */ + @Test public void Test4061302() { DecimalFormatSymbols fmt = DecimalFormatSymbols.getInstance(); @@ -845,9 +876,9 @@ public void Test4061302() if (currency.equals("") || intlCurrency.equals("") || monDecSeparator == 0) { - errln("getCurrencySymbols failed, got empty string."); + fail("getCurrencySymbols failed, got empty string."); } - logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); + System.out.println("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); fmt.setCurrencySymbol("XYZ"); fmt.setInternationalCurrencySymbol("ABC"); fmt.setMonetaryDecimalSeparator('*'); @@ -857,14 +888,15 @@ public void Test4061302() if (!currency.equals("XYZ") || !intlCurrency.equals("ABC") || monDecSeparator != '*') { - errln("setCurrencySymbols failed."); + fail("setCurrencySymbols failed."); } - logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); + System.out.println("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); } /** * API tests for API addition request A23. FieldPosition.getBeginIndex and * FieldPosition.getEndIndex. */ + @Test public void Test4062486() { DecimalFormat fmt = new DecimalFormat("#,##0.00"); @@ -873,16 +905,17 @@ public void Test4062486() Double num = 1234.5; fmt.format(num, formatted, field); if (field.getBeginIndex() != 0 && field.getEndIndex() != 5) - errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); + fail("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); field.setBeginIndex(7); field.setEndIndex(4); if (field.getBeginIndex() != 7 && field.getEndIndex() != 4) - errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); + fail("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); } /** * DecimalFormat.parse incorrectly works with a group separator. */ + @Test public void Test4108738() { @@ -891,16 +924,17 @@ public void Test4108738() String text = "1.222,111"; Number num = df.parse(text,new ParsePosition(0)); if (!num.toString().equals("1.222")) - errln("\"" + text + "\" is parsed as " + num); + fail("\"" + text + "\" is parsed as " + num); text = "1.222x111"; num = df.parse(text,new ParsePosition(0)); if (!num.toString().equals("1.222")) - errln("\"" + text + "\" is parsed as " + num); + fail("\"" + text + "\" is parsed as " + num); } /** * DecimalFormat.format() incorrectly formats negative doubles. */ + @Test public void Test4106658() { Locale savedLocale = Locale.getDefault(); @@ -909,15 +943,15 @@ public void Test4106658() double d1 = -0.0; double d2 = -0.0001; StringBuffer buffer = new StringBuffer(); - logln("pattern: \"" + df.toPattern() + "\""); + System.out.println("pattern: \"" + df.toPattern() + "\""); df.format(d1, buffer, new FieldPosition(0)); if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 - errln(d1 + " is formatted as " + buffer); + fail(d1 + " is formatted as " + buffer); } buffer.setLength(0); df.format(d2, buffer, new FieldPosition(0)); if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 - errln(d2 + " is formatted as " + buffer); + fail(d2 + " is formatted as " + buffer); } Locale.setDefault(savedLocale); } @@ -925,40 +959,43 @@ public void Test4106658() /** * DecimalFormat.parse returns 0 if string parameter is incorrect. */ + @Test public void Test4106662() { DecimalFormat df = new DecimalFormat(); String text = "x"; ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0); - logln("pattern: \"" + df.toPattern() + "\""); + System.out.println("pattern: \"" + df.toPattern() + "\""); Number num = df.parse(text, pos1); if (num != null) { - errln("Test Failed: \"" + text + "\" is parsed as " + num); + fail("Test Failed: \"" + text + "\" is parsed as " + num); } df = null; df = new DecimalFormat("$###.00"); num = df.parse("$", pos2); if (num != null){ - errln("Test Failed: \"$\" is parsed as " + num); + fail("Test Failed: \"$\" is parsed as " + num); } } /** * NumberFormat.parse doesn't return null */ + @Test public void Test4114639() { NumberFormat format = NumberFormat.getInstance(); String text = "time 10:x"; ParsePosition pos = new ParsePosition(8); Number result = format.parse(text, pos); - if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't + if (result != null) fail("Should return null but got : " + result); // Should be null; it isn't } /** * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. */ + @Test public void Test4106664() { DecimalFormat df = new DecimalFormat(); @@ -968,13 +1005,14 @@ public void Test4106664() bigN = bigN.multiply(BigInteger.valueOf(m)); df.setMultiplier(m); df.setGroupingUsed(false); - logln("formated: " + + System.out.println("formated: " + df.format(n, new StringBuffer(), new FieldPosition(0))); - logln("expected: " + bigN.toString()); + System.out.println("expected: " + bigN.toString()); } /** * DecimalFormat.format incorrectly formats -0.0. */ + @Test public void Test4106667() { Locale savedLocale = Locale.getDefault(); @@ -982,11 +1020,11 @@ public void Test4106667() DecimalFormat df = new DecimalFormat(); df.setPositivePrefix("+"); double d = -0.0; - logln("pattern: \"" + df.toPattern() + "\""); + System.out.println("pattern: \"" + df.toPattern() + "\""); StringBuffer buffer = new StringBuffer(); df.format(d, buffer, new FieldPosition(0)); if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 - errln(d + " is formatted as " + buffer); + fail(d + " is formatted as " + buffer); } Locale.setDefault(savedLocale); } @@ -994,13 +1032,14 @@ public void Test4106667() /** * DecimalFormat.setMaximumIntegerDigits() works incorrectly. */ + @Test public void Test4110936() { NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumIntegerDigits(128); - logln("setMaximumIntegerDigits(128)"); + System.out.println("setMaximumIntegerDigits(128)"); if (nf.getMaximumIntegerDigits() != 128) - errln("getMaximumIntegerDigits() returns " + + fail("getMaximumIntegerDigits() returns " + nf.getMaximumIntegerDigits()); } @@ -1011,6 +1050,7 @@ public void Test4110936() * 2) Make sure we get the same results using the generic symbol or a * hard-coded one. */ + @Test public void Test4122840() { Locale[] locales = NumberFormat.getAvailableLocales(); @@ -1027,7 +1067,7 @@ public void Test4122840() String pattern = numPatterns[1]; if (pattern.indexOf("\u00A4") == -1 ) { - errln("Currency format for " + locales[i] + + fail("Currency format for " + locales[i] + " does not contain generic currency symbol:" + pattern ); } @@ -1058,7 +1098,7 @@ public void Test4122840() String result2 = fmt2.format(1.111); if (!result1.equals(result2)) { - errln("Results for " + locales[i] + " differ: " + + fail("Results for " + locales[i] + " differ: " + result1 + " vs " + result2); } } @@ -1067,23 +1107,24 @@ public void Test4122840() /** * DecimalFormat.format() delivers wrong string. */ + @Test public void Test4125885() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); double rate = 12.34; DecimalFormat formatDec = new DecimalFormat ("000.00"); - logln("toPattern: " + formatDec.toPattern()); + System.out.println("toPattern: " + formatDec.toPattern()); String rateString= formatDec.format(rate); if (!rateString.equals("012.34")) - errln("result : " + rateString + " expected : 012.34"); + fail("result : " + rateString + " expected : 012.34"); rate = 0.1234; formatDec = null; formatDec = new DecimalFormat ("+000.00%;-000.00%"); - logln("toPattern: " + formatDec.toPattern()); + System.out.println("toPattern: " + formatDec.toPattern()); rateString= formatDec.format(rate); if (!rateString.equals("+012.34%")) - errln("result : " + rateString + " expected : +012.34%"); + fail("result : " + rateString + " expected : +012.34%"); Locale.setDefault(savedLocale); } @@ -1091,16 +1132,17 @@ public void Test4125885() ** * DecimalFormat produces extra zeros when formatting numbers. */ + @Test public void Test4134034() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); DecimalFormat nf = new DecimalFormat("##,###,###.00"); String f = nf.format(9.02); - if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02"); + if (f.equals("9.02")) System.out.println(f + " ok"); else fail("9.02 -> " + f + "; want 9.02"); f = nf.format(0); - if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00"); + if (f.equals(".00")) System.out.println(f + " ok"); else fail("0 -> " + f + "; want .00"); Locale.setDefault(savedLocale); } @@ -1128,6 +1170,7 @@ public void Test4134034() { * Value 1.2 Format #0.0# Result '1.2' * Value 1.2 Format #0.00 Result '1.20' */ + @Test public void Test4134300() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -1142,11 +1185,11 @@ public void Test4134300() { for (int i=0; i " + s); + fail("Fail: Format empty pattern x 123.456 => " + s); s = f.format(-123.456); if (!s.equals("-123.456")) - errln("Fail: Format empty pattern x -123.456 => " + s); + fail("Fail: Format empty pattern x -123.456 => " + s); } } /** * BigDecimal numbers get their fractions truncated by NumberFormat. */ + @Test public void Test4141750() { try { String str = "12345.67"; @@ -1188,11 +1233,11 @@ public void Test4141750() { NumberFormat nf = NumberFormat.getInstance(Locale.US); String sd = nf.format(bd); if (!sd.endsWith("67")) { - errln("Fail: " + str + " x format -> " + sd); + fail("Fail: " + str + " x format -> " + sd); } } catch (Exception e) { - errln(e.toString()); + fail(e.toString()); e.printStackTrace(); } } @@ -1201,6 +1246,7 @@ public void Test4141750() { * DecimalFormat toPattern() doesn't quote special characters or handle * single quotes. */ + @Test public void Test4145457() { try { DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); @@ -1223,25 +1269,25 @@ public void Test4145457() { double val2 = nf.parse(out2).doubleValue(); if (!pat.equals(pat2)) - errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" + + fail("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" + pat + "\" vs. \"" + pat2 + "\""); else - logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"'); + System.out.println("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"'); if (val == val2 && out.equals(out2)) { - logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" + + System.out.println("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" + out + "\" -> " + val + " -> \"" + out2 + "\" -> " + val2); } else { - errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" + + fail("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" + out + "\" -> " + val + " -> \"" + out2 + "\" -> " + val2); } } } catch (ParseException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } } @@ -1251,19 +1297,20 @@ public void Test4145457() { * CANNOT REPRODUCE * This bug is a duplicate of 4139344, which is a duplicate of 4134300 */ + @Test public void Test4147295() { DecimalFormat sdf = new DecimalFormat(); String pattern = "#,###"; - logln("Applying pattern \"" + pattern + "\""); + System.out.println("Applying pattern \"" + pattern + "\""); sdf.applyPattern(pattern); int minIntDig = sdf.getMinimumIntegerDigits(); if (minIntDig != 0) { - errln("Test failed"); - errln(" Minimum integer digits : " + minIntDig); - errln(" new pattern: " + sdf.toPattern()); + fail("Test failed" + + "\n Minimum integer digits : " + minIntDig + + "\n new pattern: " + sdf.toPattern()); } else { - logln("Test passed"); - logln(" Minimum integer digits : " + minIntDig); + System.out.println("Test passed"); + System.out.println(" Minimum integer digits : " + minIntDig); } } @@ -1271,6 +1318,7 @@ public void Test4147295() { * DecimalFormat formats -0.0 as +0.0 * See also older related bug 4106658, 4106667 */ + @Test public void Test4147706() { DecimalFormat df = new DecimalFormat("#,##0.0##"); df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH)); @@ -1279,39 +1327,41 @@ public void Test4147706() { StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0)); StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0)); if (!f1.toString().equals("-0.0")) { - errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"'); + fail(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"'); } if (!f2.toString().equals("-0.0")) { - errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"'); + fail(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"'); } } /** * NumberFormat cannot format Double.MAX_VALUE */ + @Test public void Test4162198() { double dbl = Double.MAX_VALUE; NumberFormat f = NumberFormat.getInstance(); f.setMaximumFractionDigits(Integer.MAX_VALUE); f.setMaximumIntegerDigits(Integer.MAX_VALUE); String s = f.format(dbl); - logln("The number " + dbl + " formatted to " + s); + System.out.println("The number " + dbl + " formatted to " + s); Number n = null; try { n = f.parse(s); } catch (java.text.ParseException e) { - errln("Caught a ParseException:"); + fail("Caught a ParseException:"); e.printStackTrace(); } - logln("The string " + s + " parsed as " + n); + System.out.println("The string " + s + " parsed as " + n); if (n.doubleValue() != dbl) { - errln("Round trip failure"); + fail("Round trip failure"); } } /** * NumberFormat does not parse negative zero. */ + @Test public void Test4162852() throws ParseException { for (int i=0; i<2; ++i) { NumberFormat f = (i == 0) ? NumberFormat.getInstance() @@ -1319,12 +1369,12 @@ public void Test4162852() throws ParseException { double d = -0.0; String s = f.format(d); double e = f.parse(s).doubleValue(); - logln("" + + System.out.println("" + d + " -> " + '"' + s + '"' + " -> " + e); if (e != 0.0 || 1.0/e > 0.0) { - logln("Failed to parse negative zero"); + System.out.println("Failed to parse negative zero"); } } } @@ -1332,6 +1382,7 @@ public void Test4162852() throws ParseException { /** * NumberFormat truncates data */ + @Test public void Test4167494() throws Exception { NumberFormat fmt = NumberFormat.getInstance(Locale.US); @@ -1340,9 +1391,9 @@ public void Test4167494() throws Exception { double b = fmt.parse(s).doubleValue(); boolean match = a == b; if (match) { - logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); + System.out.println("" + a + " -> \"" + s + "\" -> " + b + " ok"); } else { - errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); + fail("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); } // We don't test Double.MIN_VALUE because the locale data for the US @@ -1355,9 +1406,9 @@ public void Test4167494() throws Exception { b = fmt.parse(s).doubleValue(); match = a == b; if (match) { - logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); + System.out.println("" + a + " -> \"" + s + "\" -> " + b + " ok"); } else { - errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); + fail("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); } } } @@ -1365,6 +1416,7 @@ public void Test4167494() throws Exception { /** * DecimalFormat.parse() fails when ParseIntegerOnly set to true */ + @Test public void Test4170798() { Locale savedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -1373,7 +1425,7 @@ public void Test4170798() { Number n = df.parse("-0.0", new ParsePosition(0)); if (!(n instanceof Long || n instanceof Integer) || n.intValue() != 0) { - errln("FAIL: parse(\"-0.0\") returns " + + fail("FAIL: parse(\"-0.0\") returns " + n + " (" + n.getClass().getName() + ')'); } Locale.setDefault(savedLocale); @@ -1382,6 +1434,7 @@ public void Test4170798() { /** * toPattern only puts the first grouping separator in. */ + @Test public void Test4176114() { String[] DATA = { "00", "#00", @@ -1398,7 +1451,7 @@ public void Test4176114() { DecimalFormat df = new DecimalFormat(DATA[i]); String s = df.toPattern(); if (!s.equals(DATA[i+1])) { - errln("FAIL: " + DATA[i] + " -> " + s + ", want " + DATA[i+1]); + fail("FAIL: " + DATA[i] + " -> " + s + ", want " + DATA[i+1]); } } } @@ -1406,6 +1459,7 @@ public void Test4176114() { /** * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 */ + @Test public void Test4179818() { String DATA[] = { // Input Pattern Expected output @@ -1422,14 +1476,15 @@ public void Test4179818() { fmt.applyPattern(pat); String out = fmt.format(in); if (out.equals(exp)) { - logln("Ok: " + in + " x " + pat + " = " + out); + System.out.println("Ok: " + in + " x " + pat + " = " + out); } else { - errln("FAIL: " + in + " x " + pat + " = " + out + + fail("FAIL: " + in + " x " + pat + " = " + out + ", expected " + exp); } } } + @Test public void Test4185761() throws IOException, ClassNotFoundException { /* Code used to write out the initial files, which are * then edited manually: @@ -1456,13 +1511,13 @@ public void Test4185761() throws IOException, ClassNotFoundException { ObjectInputStream p = new ObjectInputStream(istream); try { NumberFormat nf = (NumberFormat) p.readObject(); - errln("FAIL: Deserialized bogus NumberFormat int:" + + fail("FAIL: Deserialized bogus NumberFormat int:" + nf.getMinimumIntegerDigits() + ".." + nf.getMaximumIntegerDigits() + " frac:" + nf.getMinimumFractionDigits() + ".." + nf.getMaximumFractionDigits()); } catch (InvalidObjectException e) { - logln("Ok: " + e.getMessage()); + System.out.println("Ok: " + e.getMessage()); } istream.close(); @@ -1470,13 +1525,13 @@ public void Test4185761() throws IOException, ClassNotFoundException { p = new ObjectInputStream(istream); try { NumberFormat nf = (NumberFormat) p.readObject(); - errln("FAIL: Deserialized bogus DecimalFormat int:" + + fail("FAIL: Deserialized bogus DecimalFormat int:" + nf.getMinimumIntegerDigits() + ".." + nf.getMaximumIntegerDigits() + " frac:" + nf.getMinimumFractionDigits() + ".." + nf.getMaximumFractionDigits()); } catch (InvalidObjectException e) { - logln("Ok: " + e.getMessage()); + System.out.println("Ok: " + e.getMessage()); } istream.close(); } @@ -1488,6 +1543,7 @@ public void Test4185761() throws IOException, ClassNotFoundException { * symbol, percent, and permille. This is filed as bugs 4212072 and * 4212073. */ + @Test public void Test4212072() throws IOException, ClassNotFoundException { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); DecimalFormat fmt = new DecimalFormat("#", sym); @@ -1495,11 +1551,11 @@ public void Test4212072() throws IOException, ClassNotFoundException { sym.setMinusSign('^'); fmt.setDecimalFormatSymbols(sym); if (!fmt.format(-1).equals("^1")) { - errln("FAIL: -1 x (minus=^) -> " + fmt.format(-1) + + fail("FAIL: -1 x (minus=^) -> " + fmt.format(-1) + ", exp ^1"); } if (!fmt.getNegativePrefix().equals("^")) { - errln("FAIL: (minus=^).getNegativePrefix -> " + + fail("FAIL: (minus=^).getNegativePrefix -> " + fmt.getNegativePrefix() + ", exp ^"); } sym.setMinusSign('-'); @@ -1508,11 +1564,11 @@ public void Test4212072() throws IOException, ClassNotFoundException { sym.setPercent('^'); fmt.setDecimalFormatSymbols(sym); if (!fmt.format(0.25).equals("25^")) { - errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) + + fail("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) + ", exp 25^"); } if (!fmt.getPositiveSuffix().equals("^")) { - errln("FAIL: (percent=^).getPositiveSuffix -> " + + fail("FAIL: (percent=^).getPositiveSuffix -> " + fmt.getPositiveSuffix() + ", exp ^"); } sym.setPercent('%'); @@ -1521,11 +1577,11 @@ public void Test4212072() throws IOException, ClassNotFoundException { sym.setPerMill('^'); fmt.setDecimalFormatSymbols(sym); if (!fmt.format(0.25).equals("250^")) { - errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) + + fail("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) + ", exp 250^"); } if (!fmt.getPositiveSuffix().equals("^")) { - errln("FAIL: (permill=^).getPositiveSuffix -> " + + fail("FAIL: (permill=^).getPositiveSuffix -> " + fmt.getPositiveSuffix() + ", exp ^"); } sym.setPerMill('\u2030'); @@ -1534,11 +1590,11 @@ public void Test4212072() throws IOException, ClassNotFoundException { sym.setCurrencySymbol("usd"); fmt.setDecimalFormatSymbols(sym); if (!fmt.format(12.5).equals("usd12.50")) { - errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) + + fail("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) + ", exp usd12.50"); } if (!fmt.getPositivePrefix().equals("usd")) { - errln("FAIL: (currency=usd).getPositivePrefix -> " + + fail("FAIL: (currency=usd).getPositivePrefix -> " + fmt.getPositivePrefix() + ", exp usd"); } sym.setCurrencySymbol("$"); @@ -1547,11 +1603,11 @@ public void Test4212072() throws IOException, ClassNotFoundException { sym.setInternationalCurrencySymbol("DOL"); fmt.setDecimalFormatSymbols(sym); if (!fmt.format(12.5).equals("DOL12.50")) { - errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) + + fail("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) + ", exp DOL12.50"); } if (!fmt.getPositivePrefix().equals("DOL")) { - errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " + + fail("FAIL: (intlcurrency=DOL).getPositivePrefix -> " + fmt.getPositivePrefix() + ", exp DOL"); } sym.setInternationalCurrencySymbol("USD"); @@ -1580,7 +1636,7 @@ public void Test4212072() throws IOException, ClassNotFoundException { DecimalFormatSymbols symb = DecimalFormatSymbols.getInstance(avail[i]); DecimalFormat f2 = new DecimalFormat(pat, symb); if (!df.equals(f2)) { - errln("FAIL: " + avail[i] + " -> \"" + pat + + fail("FAIL: " + avail[i] + " -> \"" + pat + "\" -> \"" + f2.toPattern() + '"'); } @@ -1588,7 +1644,7 @@ public void Test4212072() throws IOException, ClassNotFoundException { pat = df.toLocalizedPattern(); f2.applyLocalizedPattern(pat); if (!df.equals(f2)) { - errln("FAIL: " + avail[i] + " -> localized \"" + pat + + fail("FAIL: " + avail[i] + " -> localized \"" + pat + "\" -> \"" + f2.toPattern() + '"'); } @@ -1603,7 +1659,7 @@ public void Test4212072() throws IOException, ClassNotFoundException { new ObjectInputStream(new ByteArrayInputStream(bytes)); f2 = (DecimalFormat) ois.readObject(); if (!df.equals(f2)) { - errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat + + fail("FAIL: Stream in/out " + avail[i] + " -> \"" + pat + "\" -> " + (f2 != null ? ("\""+f2.toPattern()+'"') : "null")); } @@ -1615,6 +1671,7 @@ public void Test4212072() throws IOException, ClassNotFoundException { /** * DecimalFormat.parse() fails for mulipliers 2^n. */ + @Test public void Test4216742() throws ParseException { DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US); long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L}; @@ -1624,7 +1681,7 @@ public void Test4216742() throws ParseException { fmt.setMultiplier(m); long n = fmt.parse(str).longValue(); if (n > 0 != DATA[i] > 0) { - errln("\"" + str + "\" parse(x " + fmt.getMultiplier() + + fail("\"" + str + "\" parse(x " + fmt.getMultiplier() + ") => " + n); } } @@ -1635,6 +1692,7 @@ public void Test4216742() throws ParseException { * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction * digits. */ + @Test public void Test4217661() { Object[] DATA = { 0.001, "0", @@ -1647,7 +1705,7 @@ public void Test4217661() { for (int i=0; i 0 && args[0].equals("-debug")) { - DEBUG = true; - String[] newargs = new String[args.length - 1]; - System.arraycopy(args, 1, newargs, 0, newargs.length); - args = newargs; - } - new NumberRoundTrip().run(args); - } - + @Test public void TestNumberFormatRoundTrip() { - logln("Default Locale"); + System.out.println("Default Locale"); localeName = "Default Locale"; formatName = "getInstance"; doTest(NumberFormat.getInstance()); @@ -74,7 +70,7 @@ public void TestNumberFormatRoundTrip() { Locale[] loc = NumberFormat.getAvailableLocales(); for (int i=0; i " + escape(s)); + System.out.println(" " + value + " F> " + escape(s)); n = fmt.parse(s); - if (DEBUG) logln(" " + escape(s) + " P> " + n); + System.out.println(" " + escape(s) + " P> " + n); s2 = fmt.format(n); - if (DEBUG) logln(" " + n + " F> " + escape(s2)); + System.out.println(" " + n + " F> " + escape(s2)); if (STRING_COMPARE) { if (!s.equals(s2)) { if (fmt instanceof DecimalFormat) { - logln("Text mismatch: expected: " + s + ", got: " + s2 + " --- Try BigDecimal parsing."); + System.out.println("Text mismatch: expected: " + s + ", got: " + s2 + " --- Try BigDecimal parsing."); ((DecimalFormat)fmt).setParseBigDecimal(true); n = fmt.parse(s); - if (DEBUG) logln(" " + escape(s) + " P> " + n); + System.out.println(" " + escape(s) + " P> " + n); s2 = fmt.format(n); - if (DEBUG) logln(" " + n + " F> " + escape(s2)); + System.out.println(" " + n + " F> " + escape(s2)); ((DecimalFormat)fmt).setParseBigDecimal(false); if (!s.equals(s2)) { @@ -197,14 +193,14 @@ public void doTest(NumberFormat fmt, Number value) { n + typeOf(n) + " F> " + escape(s2); if (err.length() > 0) { - errln("*** " + err + " with " + + fail("*** " + err + " with " + formatName + " in " + localeName + " " + message); } else { - logln(message); + System.out.println(message); } } catch (ParseException e) { - errln("*** " + e.toString() + " with " + + fail("*** " + e.toString() + " with " + formatName + " in " + localeName); } } diff --git a/test/jdk/java/text/Format/NumberFormat/NumberTest.java b/test/jdk/java/text/Format/NumberFormat/NumberTest.java index fd78223ccca..fc24322ada9 100644 --- a/test/jdk/java/text/Format/NumberFormat/NumberTest.java +++ b/test/jdk/java/text/Format/NumberFormat/NumberTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,24 +25,24 @@ * @test * @bug 4122840 4135202 4408066 4838107 8008577 * @summary test NumberFormat - * @library /java/text/testlib * @modules java.base/sun.util.resources * jdk.localedata * @compile -XDignore.symbol.file NumberTest.java - * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberTest + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI NumberTest */ import java.util.*; import java.text.*; import sun.util.resources.LocaleData; -public class NumberTest extends IntlTest -{ - public static void main(String[] args) throws Exception { - new NumberTest().run(args); - } +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +public class NumberTest +{ // Test pattern handling + @Test public void TestPatterns() { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); @@ -54,20 +54,21 @@ public void TestPatterns() DecimalFormat fmt = new DecimalFormat(pat[i], sym); String newp = fmt.toPattern(); if (!newp.equals(newpat[i])) - errln("FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] + + fail("FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] + "; " + newp + " seen instead"); String s = fmt.format(0); if (!s.equals(num[i])) { - errln("FAIL: Pattern " + pat[i] + " should format zero as " + num[i] + + fail("FAIL: Pattern " + pat[i] + " should format zero as " + num[i] + "; " + s + " seen instead"); - logln("Min integer digits = " + fmt.getMinimumIntegerDigits()); + System.out.println("Min integer digits = " + fmt.getMinimumIntegerDigits()); } } } // Test exponential pattern + @Test public void TestExponential() { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); String pat[] = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" }; @@ -100,14 +101,14 @@ public void TestExponential() { int ival = 0, ilval = 0; for (int p=0; p \"" + + System.out.println("Pattern \"" + pat[p] + "\" -toPattern-> \"" + fmt.toPattern() + '"'); for (int v=0; v " + escape(s)); + System.out.println(" Format " + val[v] + " -> " + escape(s)); if (!s.equals(valFormat[v+ival])) { - errln("FAIL: Expected " + valFormat[v+ival] + + fail("FAIL: Expected " + valFormat[v+ival] + ", got " + s + ", pattern=" + fmt.toPattern()); } @@ -115,22 +116,22 @@ public void TestExponential() { ParsePosition pos = new ParsePosition(0); Number a = fmt.parse(s, pos); if (pos.getIndex() == s.length()) { - logln(" Parse -> " + a); + System.out.println(" Parse -> " + a); if (a.doubleValue() != valParse[v+ival]) { - errln("FAIL: Expected " + valParse[v+ival] + + fail("FAIL: Expected " + valParse[v+ival] + ", got " + a.doubleValue() + ", pattern=" + fmt.toPattern()); } } else { - errln(" FAIL: Partial parse (" + pos.getIndex() + + fail(" FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); } } for (int v=0; v " + escape(s)); + System.out.println(" Format " + lval[v] + "L -> " + escape(s)); if (!s.equals(lvalFormat[v+ilval])) { - errln("ERROR: Expected " + lvalFormat[v+ilval] + + fail("ERROR: Expected " + lvalFormat[v+ilval] + ", got " + s + ", pattern=" + fmt.toPattern()); } @@ -138,14 +139,14 @@ public void TestExponential() { ParsePosition pos = new ParsePosition(0); Number a = fmt.parse(s, pos); if (pos.getIndex() == s.length()) { - logln(" Parse -> " + a); + System.out.println(" Parse -> " + a); if (a.longValue() != lvalParse[v+ilval]) { - errln("FAIL: Expected " + lvalParse[v+ilval] + + fail("FAIL: Expected " + lvalParse[v+ilval] + ", got " + a + ", pattern=" + fmt.toPattern()); } } else { - errln(" FAIL: Partial parse (" + pos.getIndex() + + fail(" FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); } } @@ -155,24 +156,26 @@ public void TestExponential() { } // Test the handling of quotes + @Test public void TestQuotes() { String pat; DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); DecimalFormat fmt = new DecimalFormat(pat = "a'fo''o'b#", sym); String s = fmt.format(123); - logln("Pattern \"" + pat + "\""); - logln(" Format 123 -> " + escape(s)); - if (!s.equals("afo'ob123")) errln("FAIL: Expected afo'ob123"); + System.out.println("Pattern \"" + pat + "\""); + System.out.println(" Format 123 -> " + escape(s)); + if (!s.equals("afo'ob123")) fail("FAIL: Expected afo'ob123"); fmt = new DecimalFormat(pat = "a''b#", sym); s = fmt.format(123); - logln("Pattern \"" + pat + "\""); - logln(" Format 123 -> " + escape(s)); - if (!s.equals("a'b123")) errln("FAIL: Expected a'b123"); + System.out.println("Pattern \"" + pat + "\""); + System.out.println(" Format 123 -> " + escape(s)); + if (!s.equals("a'b123")) fail("FAIL: Expected a'b123"); } // Test the use of the currency sign + @Test public void TestCurrencySign() { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); @@ -181,21 +184,21 @@ public void TestCurrencySign() // DecimalFormatSymbols sym = fmt.getDecimalFormatSymbols(); String s = fmt.format(1234.56); - logln("Pattern \"" + fmt.toPattern() + "\""); - logln(" Format " + 1234.56 + " -> " + escape(s)); - if (!s.equals("$1,234.56")) errln("FAIL: Expected $1,234.56"); + System.out.println("Pattern \"" + fmt.toPattern() + "\""); + System.out.println(" Format " + 1234.56 + " -> " + escape(s)); + if (!s.equals("$1,234.56")) fail("FAIL: Expected $1,234.56"); s = fmt.format(-1234.56); - logln(" Format " + -1234.56 + " -> " + escape(s)); - if (!s.equals("-$1,234.56")) errln("FAIL: Expected -$1,234.56"); + System.out.println(" Format " + -1234.56 + " -> " + escape(s)); + if (!s.equals("-$1,234.56")) fail("FAIL: Expected -$1,234.56"); fmt = new DecimalFormat("\u00A4\u00A4 #,##0.00;\u00A4\u00A4 -#,##0.00", sym); s = fmt.format(1234.56); - logln("Pattern \"" + fmt.toPattern() + "\""); - logln(" Format " + 1234.56 + " -> " + escape(s)); - if (!s.equals("USD 1,234.56")) errln("FAIL: Expected USD 1,234.56"); + System.out.println("Pattern \"" + fmt.toPattern() + "\""); + System.out.println(" Format " + 1234.56 + " -> " + escape(s)); + if (!s.equals("USD 1,234.56")) fail("FAIL: Expected USD 1,234.56"); s = fmt.format(-1234.56); - logln(" Format " + -1234.56 + " -> " + escape(s)); - if (!s.equals("USD -1,234.56")) errln("FAIL: Expected USD -1,234.56"); + System.out.println(" Format " + -1234.56 + " -> " + escape(s)); + if (!s.equals("USD -1,234.56")) fail("FAIL: Expected USD -1,234.56"); } static String escape(String s) { @@ -219,25 +222,26 @@ static String escape(String s) // Test simple currency format // Bug 4024941; this code used to throw a NumberFormat exception + @Test public void TestCurrency() { NumberFormat currencyFmt = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH); String s = currencyFmt.format(1.50); - logln("Un pauvre ici a..........." + s); + System.out.println("Un pauvre ici a..........." + s); if (!s.equals("1,50 $")) { - errln("FAIL: Expected 1,50 $; got " + s + "; "+ dumpFmt(currencyFmt)); + fail("FAIL: Expected 1,50 $; got " + s + "; "+ dumpFmt(currencyFmt)); } currencyFmt = NumberFormat.getCurrencyInstance(Locale.GERMANY); s = currencyFmt.format(1.50); - logln("Un pauvre en Allemagne a.." + s); + System.out.println("Un pauvre en Allemagne a.." + s); if (!s.equals("1,50 \u20AC")) { - errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); + fail("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); } currencyFmt = NumberFormat.getCurrencyInstance(Locale.FRANCE); s = currencyFmt.format(1.50); - logln("Un pauvre en France a....." + s); + System.out.println("Un pauvre en France a....." + s); if (!s.equals("1,50 \u20AC")) { - errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); + fail("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); } } @@ -254,18 +258,20 @@ String dumpFmt(NumberFormat numfmt) { // Test numeric parsing // Bug 4059870 + @Test public void TestParse() { String arg = "0"; java.text.DecimalFormat format = new java.text.DecimalFormat("00"); try { Number n = format.parse(arg); - logln("parse(" + arg + ") = " + n); - if (n.doubleValue() != 0.0) errln("FAIL: Expected 0"); - } catch (Exception e) { errln("Exception caught: " + e); } + System.out.println("parse(" + arg + ") = " + n); + if (n.doubleValue() != 0.0) fail("FAIL: Expected 0"); + } catch (Exception e) { fail("Exception caught: " + e); } } // Test rounding + @Test public void TestRounding487() { NumberFormat nf = NumberFormat.getInstance(Locale.US); roundingTest(nf, 0.00159999, 4, "0.0016"); @@ -278,9 +284,9 @@ public void TestRounding487() { void roundingTest(NumberFormat nf, double x, int maxFractionDigits, String expected) { nf.setMaximumFractionDigits(maxFractionDigits); String out = nf.format(x); - logln("" + x + " formats with " + maxFractionDigits + " fractional digits to " + out); + System.out.println("" + x + " formats with " + maxFractionDigits + " fractional digits to " + out); if (!out.equals(expected)) { - errln("FAIL: Expected " + expected + ", got " + out); + fail("FAIL: Expected " + expected + ", got " + out); } } @@ -292,6 +298,7 @@ void roundingTest(NumberFormat nf, double x, int maxFractionDigits, String expec * a couple. * @see java.lang.Character#isDigit(char) */ + @Test public void TestUnicodeDigits() { char[] zeros = { 0x0030, // ISO-LATIN-1 digits ('0' through '9') @@ -324,9 +331,9 @@ public void TestUnicodeDigits() { } catch (ParseException e) { n = -2; } if (n != 314) - errln("Can't parse Unicode " + Integer.toHexString(zero) + " as digit (" + n + ")"); + fail("Can't parse Unicode " + Integer.toHexString(zero) + " as digit (" + n + ")"); else - logln("Parse digit " + Integer.toHexString(zero) + " ok"); + System.out.println("Parse digit " + Integer.toHexString(zero) + " ok"); } } @@ -334,6 +341,7 @@ public void TestUnicodeDigits() { * Bug 4122840 * Make sure that the currency symbol is not hard-coded in any locale. */ + @Test public void TestCurrencySubstitution() { final String SYM = ""; final String INTL_SYM = ""; @@ -356,36 +364,37 @@ public void TestCurrencySubstitution() { String customPos = df.format(1234.5678); String customNeg = df.format(-1234.5678); if (genericPos.equals(customPos) || genericNeg.equals(customNeg)) { - errln("FAIL: " + locales[i] + + fail("FAIL: " + locales[i] + " not using currency symbol substitution: " + genericPos); } else { if (customPos.indexOf(SYM) >= 0) { if (customNeg.indexOf(INTL_SYM) >= 0) - errln("Fail: Positive and negative patterns use different symbols"); + fail("Fail: Positive and negative patterns use different symbols"); else - logln("Ok: " + locales[i] + + System.out.println("Ok: " + locales[i] + " uses currency symbol: " + genericPos + ", " + customPos); } else if (customPos.indexOf(INTL_SYM) >= 0) { if (customNeg.indexOf(SYM) >= 0) - errln("Fail: Positive and negative patterns use different symbols"); + fail("Fail: Positive and negative patterns use different symbols"); else - logln("Ok: " + locales[i] + + System.out.println("Ok: " + locales[i] + " uses intl. currency symbol: " + genericPos + ", " + customPos); } else { - errln("FAIL: " + locales[i] + + fail("FAIL: " + locales[i] + " contains no currency symbol (impossible!)"); } } } - else logln("Skipping " + locales[i] + "; not a DecimalFormat"); + else System.out.println("Skipping " + locales[i] + "; not a DecimalFormat"); } } + @Test public void TestIntegerFormat() throws ParseException { NumberFormat format = NumberFormat.getIntegerInstance(Locale.GERMANY); @@ -395,7 +404,7 @@ public void TestIntegerFormat() throws ParseException { for (int i = 0; i < formatInput.length; i++) { String result = format.format(formatInput[i]); if (!result.equals(formatExpected[i])) { - errln("FAIL: Expected " + formatExpected[i] + ", got " + result); + fail("FAIL: Expected " + formatExpected[i] + ", got " + result); } } @@ -405,7 +414,7 @@ public void TestIntegerFormat() throws ParseException { for (int i = 0; i < parseInput.length; i++) { float result = format.parse(parseInput[i]).floatValue(); if (result != parseExpected[i]) { - errln("FAIL: Expected " + parseExpected[i] + ", got " + result); + fail("FAIL: Expected " + parseExpected[i] + ", got " + result); } } } diff --git a/test/jdk/java/text/Format/NumberFormat/PositionTest.java b/test/jdk/java/text/Format/NumberFormat/PositionTest.java index 31a5a3dbebd..d916e0ab1ed 100644 --- a/test/jdk/java/text/Format/NumberFormat/PositionTest.java +++ b/test/jdk/java/text/Format/NumberFormat/PositionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -24,8 +24,8 @@ /** * @test * @bug 4109023 4153060 4153061 - * @library /java/text/testlib * @summary test ParsePosition and FieldPosition + * @run junit PositionTest */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved @@ -42,33 +42,34 @@ import java.text.*; import java.io.*; -public class PositionTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new PositionTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class PositionTest { + @Test public void TestParsePosition() { ParsePosition pp1 = new ParsePosition(0); if (pp1.getIndex() == 0) { - logln("PP constructor() tested."); + System.out.println("PP constructor() tested."); }else{ - errln("*** PP getIndex or constructor() result"); + fail("*** PP getIndex or constructor() result"); } { int to = 5; ParsePosition pp2 = new ParsePosition ( to ); if (pp2.getIndex() == 5) { - logln("PP getIndex and constructor(TextOffset) tested."); + System.out.println("PP getIndex and constructor(TextOffset) tested."); }else{ - errln("*** PP getIndex or constructor(TextOffset) result"); + fail("*** PP getIndex or constructor(TextOffset) result"); } pp2.setIndex( 3 ); if (pp2.getIndex() == 3) { - logln("PP setIndex tested."); + System.out.println("PP setIndex tested."); }else{ - errln("*** PP getIndex or setIndex result"); + fail("*** PP getIndex or setIndex result"); } } @@ -77,37 +78,38 @@ public void TestParsePosition() { pp3 = new ParsePosition( 5 ); ParsePosition pp4 = new ParsePosition(5); if (! pp2.equals(pp3)) { - logln("PP not equals tested."); + System.out.println("PP not equals tested."); }else{ - errln("*** PP not equals fails"); + fail("*** PP not equals fails"); } if (pp3.equals(pp4)) { - logln("PP equals tested."); + System.out.println("PP equals tested."); }else{ - errln("*** PP equals fails (" + pp3.getIndex() + " != " + pp4.getIndex() + ")"); + fail("*** PP equals fails (" + pp3.getIndex() + " != " + pp4.getIndex() + ")"); } ParsePosition pp5; pp5 = pp4; if (pp4.equals(pp5)) { - logln("PP operator= tested."); + System.out.println("PP operator= tested."); }else{ - errln("*** PP operator= operator== or operator != result"); + fail("*** PP operator= operator== or operator != result"); } } + @Test public void TestFieldPosition() { FieldPosition fp = new FieldPosition( 7 ); if (fp.getField() == 7) { - logln("FP constructor(int) and getField tested."); + System.out.println("FP constructor(int) and getField tested."); }else{ - errln("*** FP constructor(int) or getField"); + fail("*** FP constructor(int) or getField"); } FieldPosition fph = new FieldPosition( 3 ); - if ( fph.getField() != 3) errln("*** FP getField or heap constr."); + if ( fph.getField() != 3) fail("*** FP getField or heap constr."); boolean err1 = false; boolean err2 = false; @@ -121,24 +123,25 @@ public void TestFieldPosition() { // if (fp.getEndIndex() != i+7) err3 = true; // } if (!err1) { - logln("FP setField and getField tested."); + System.out.println("FP setField and getField tested."); }else{ - errln("*** FP setField or getField"); + fail("*** FP setField or getField"); } if (!err2) { - logln("FP setBeginIndex and getBeginIndex tested."); + System.out.println("FP setBeginIndex and getBeginIndex tested."); }else{ - errln("*** FP setBeginIndex or getBeginIndex"); + fail("*** FP setBeginIndex or getBeginIndex"); } if (!err3) { - logln("FP setEndIndex and getEndIndex tested."); + System.out.println("FP setEndIndex and getEndIndex tested."); }else{ - errln("*** FP setEndIndex or getEndIndex"); + fail("*** FP setEndIndex or getEndIndex"); } - logln(""); + System.out.println(""); } + @Test public void TestFieldPosition_example() { //***** no error detection yet !!!!!!! //***** this test is for compiler checks and visual verification only. @@ -164,41 +167,43 @@ public void TestFieldPosition_example() { tempLen : (tempLen - pos.getEndIndex()); for (int j=0; j contents = parser.parse(new BufferedReader( new FileReader(file))); List test = (List)contents.get("tests"); for (int counter = 0; counter < test.size(); counter++) { - logln("creating: " + (counter / 2)); + System.out.println("creating: " + (counter / 2)); AttributedCharacterIterator iterator = create((Map)test.get(counter)); - logln("verifying: " + (counter / 2)); + System.out.println("verifying: " + (counter / 2)); verify(iterator, (Map)test.get(++counter)); } } catch (IOException ioe) { - errln("Error reading: " + ioe); + fail("Error reading: " + ioe); } } @@ -175,20 +169,20 @@ public void verify(AttributedCharacterIterator iterator,Map table escapeIfNecessary((String)table.get("text")))) { String text = getText(iterator); - errln("text doesn't match, got: " + getText(iterator)); + fail("text doesn't match, got: " + getText(iterator)); } if (iterator.getBeginIndex() != 0) { - errln("Bogus start: " + iterator.getBeginIndex()); + fail("Bogus start: " + iterator.getBeginIndex()); } if (iterator.getEndIndex() != length) { - errln("Bogus end: " + iterator.getEndIndex()); + fail("Bogus end: " + iterator.getEndIndex()); } for (int counter = 0; counter < length; counter++) { iterator.setIndex(counter); if (!verifyAttributes(iterator.getAttributes().keySet(), makeAttributes((List)table.get(Integer. toString(counter))))) { - errln("Attributes don't match at " + counter + " expecting " + + fail("Attributes don't match at " + counter + " expecting " + makeAttributes((List)table.get(Integer.toString (counter))) + " got " + iterator.getAttributes().keySet()); @@ -199,7 +193,7 @@ public void verify(AttributedCharacterIterator iterator,Map table if (!verifyAttributes(iterator.getAttributes().keySet(), makeAttributes((List)table.get(Integer. toString(counter))))) { - errln("Attributes don't match at " + counter + " expecting " + + fail("Attributes don't match at " + counter + " expecting " + makeAttributes((List)table.get(Integer.toString (counter))) + " got " + iterator.getAttributes().keySet()); @@ -243,22 +237,22 @@ private void verifyLimit(AttributedCharacterIterator iterator, for (int counter = begin; counter < end; counter++) { iterator.setIndex(counter); if (iterator.getRunStart() != begin) { - errln("Begin doesn't match want " + begin + " got " + + fail("Begin doesn't match want " + begin + " got " + iterator.getRunStart() + " at " + counter + " attrs " + attrs); } if (iterator.getRunStart(attrs) != begin2) { - errln("Begin2 doesn't match want " + begin2 + " got " + + fail("Begin2 doesn't match want " + begin2 + " got " + iterator.getRunStart(attrs) + " at " + counter + " attrs " + attrs); } if (iterator.getRunLimit() != end) { - errln("End doesn't match want " + end + " got " + + fail("End doesn't match want " + end + " got " + iterator.getRunLimit() + " at " + counter + " attrs " + attrs); } if (iterator.getRunLimit(attrs) != end2) { - errln("End2 doesn't match want " + end2 + " got " + + fail("End2 doesn't match want " + end2 + " got " + iterator.getRunLimit(attrs) + " at " + counter + " attrs " + attrs); } @@ -312,15 +306,15 @@ private void verifyFieldPosition(FieldPosition fp, int begin, int end, format.format(value, buffer, fp); if (fp.getBeginIndex() != begin) { - errln("bogus begin want " + begin + " got " + fp.getBeginIndex() + + fail("bogus begin want " + begin + " got " + fp.getBeginIndex() + " for " + fp + " at " + index); } if (fp.getEndIndex() != end) { - errln("bogus end want " + end + " got " + fp.getEndIndex() + + fail("bogus end want " + end + " got " + fp.getEndIndex() + " for " + fp + " at " + index); } if (!buffer.toString().equals(text)) { - errln("Text does not match, want !" + buffer.toString() + + fail("Text does not match, want !" + buffer.toString() + "! got !" + text + "!"); } } @@ -331,11 +325,11 @@ public AttributedCharacterIterator create(Map table) { value = createInstance((String)table.get("valueClass"), ((List)table.get("valueArgs")).toArray()); - logln("Created format: " + format + " value " + value); + System.out.println("Created format: " + format + " value " + value); AttributedCharacterIterator aci = format. formatToCharacterIterator(value); - logln("Obtained Iterator: " + aci); + System.out.println("Obtained Iterator: " + aci); return aci; } @@ -373,7 +367,7 @@ private Object createInstance(String className, Object[] args) { return value; } } catch (Throwable th) { - errln("Error creating instance " + th); + fail("Error creating instance " + th); return null; } } @@ -413,7 +407,7 @@ private Object lookupField(String name) { } catch (Throwable th) { error = th; } - errln("Could not lookup field " + name + " " + error); + fail("Could not lookup field " + name + " " + error); return null; } diff --git a/test/jdk/java/text/Normalizer/ICUBasicTest.java b/test/jdk/java/text/Normalizer/ICUBasicTest.java index 206291b99a7..62761a2f545 100644 --- a/test/jdk/java/text/Normalizer/ICUBasicTest.java +++ b/test/jdk/java/text/Normalizer/ICUBasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,9 +26,8 @@ * @summary Confirm Normalizer's fundamental behavior. Imported from ICU4J 3.2's * src/com/ibm/icu/dev/test and modified. * @modules java.base/sun.text java.base/jdk.internal.icu.text - * @library /java/text/testlib * @compile -XDignore.symbol.file ICUBasicTest.java - * @run main/timeout=30 ICUBasicTest + * @run junit/timeout=30 ICUBasicTest */ /* @@ -45,11 +44,11 @@ import static java.text.Normalizer.Form.*; -public class ICUBasicTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new ICUBasicTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class ICUBasicTest { /* * Normalization modes @@ -77,6 +76,7 @@ public static void main(String[] args) throws Exception { * PRI #29 is supported in Unicode 4.1.0. Therefore, expected results are * different for earlier Unicode versions. */ + @Test public void TestComposition() { final TestCompositionCase cases[] = new TestCompositionCase[] { @@ -116,10 +116,7 @@ public void TestComposition() { output = Normalizer.normalize(cases[i].input, cases[i].form, cases[i].options); if (!output.equals(cases[i].expect)) { - errln("unexpected result for case " + i + ". Expected=" - + cases[i].expect + ", Actual=" + output); - } else if (verbose) { - logln("expected result for case " + i + ". Expected=" + fail("unexpected result for case " + i + ". Expected=" + cases[i].expect + ", Actual=" + output); } } @@ -144,13 +141,14 @@ private final static class TestCompositionCase { /* * Added in order to detect a regression. */ + @Test public void TestCombiningMarks() { String src = "\u0f71\u0f72\u0f73\u0f74\u0f75"; String expected = "\u0F71\u0F71\u0F71\u0F72\u0F72\u0F74\u0F74"; String result = NormalizerBase.normalize(src, NFD); if (!expected.equals(result)) { - errln("Reordering of combining marks failed. Expected: " + + fail("Reordering of combining marks failed. Expected: " + HexFormat.of().withDelimiter(" ").formatHex(expected.getBytes()) + " Got: "+ HexFormat.of().withDelimiter(" ").formatHex(result.getBytes())); } @@ -159,12 +157,13 @@ public void TestCombiningMarks() { /* * Added in order to detect a regression. */ + @Test public void TestBengali() throws Exception { String input = "\u09bc\u09be\u09cd\u09be"; String output=NormalizerBase.normalize(input, NFC); if (!input.equals(output)) { - errln("ERROR in NFC of string"); + fail("ERROR in NFC of string"); } return; } @@ -178,6 +177,7 @@ public void TestBengali() throws Exception { * characters at the start of a string are not put in canonical * order correctly by compose() if there is no starter. */ + @Test public void TestVerisign() throws Exception { String[] inputs = { "\u05b8\u05b9\u05b1\u0591\u05c3\u05b0\u05ac\u059f", @@ -194,7 +194,7 @@ public void TestVerisign() throws Exception { String result = NormalizerBase.normalize(input, NFD); if (!result.equals(output)) { - errln("FAIL input: " + HexFormat.of().withDelimiter(" ") + fail("FAIL input: " + HexFormat.of().withDelimiter(" ") .formatHex(input.getBytes()) + "\n" + " decompose: " + HexFormat.of().withDelimiter(" ") .formatHex(result.getBytes()) + "\n" + @@ -204,7 +204,7 @@ public void TestVerisign() throws Exception { result = NormalizerBase.normalize(input, NFC); if (!result.equals(output)) { - errln("FAIL input: " + HexFormat.of().withDelimiter(" ") + fail("FAIL input: " + HexFormat.of().withDelimiter(" ") .formatHex(input.getBytes()) + "\n" + " compose: " + HexFormat.of().withDelimiter(" ") .formatHex(output.getBytes()) + "\n" + @@ -223,6 +223,7 @@ public void TestVerisign() throws Exception { * map to the same canonical class, which is not the case, in * reality. */ + @Test public void TestZeroIndex() throws Exception { String[] DATA = { // Expect col1 x COMPOSE_COMPAT => col2 @@ -240,12 +241,12 @@ public void TestZeroIndex() throws Exception { String exp = DATA[i+1]; if (b.equals(exp)) { - logln("Ok: " + HexFormat.of().withDelimiter(" ") + System.out.println("Ok: " + HexFormat.of().withDelimiter(" ") .formatHex(a.getBytes()) + " x COMPOSE_COMPAT => " + HexFormat.of().withDelimiter(" ") .formatHex(b.getBytes())); } else { - errln("FAIL: " + HexFormat.of().withDelimiter(" ") + fail("FAIL: " + HexFormat.of().withDelimiter(" ") .formatHex(b.getBytes()) + " x COMPOSE_COMPAT => " + HexFormat.of().withDelimiter(" ") .formatHex(a.getBytes()) + ", expect " + @@ -256,10 +257,10 @@ public void TestZeroIndex() throws Exception { a = NormalizerBase.normalize(b, NFD); exp = DATA[i+2]; if (a.equals(exp)) { - logln("Ok: " + HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x DECOMP => " + + System.out.println("Ok: " + HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x DECOMP => " + HexFormat.of().withDelimiter(" ").formatHex(a.getBytes())); } else { - errln("FAIL: " + HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x DECOMP => " + + fail("FAIL: " + HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x DECOMP => " + HexFormat.of().withDelimiter(" ").formatHex(a.getBytes()) + ", expect " + HexFormat.of().withDelimiter(" ").formatHex(exp.getBytes())); } } @@ -269,6 +270,7 @@ public void TestZeroIndex() throws Exception { * Make sure characters in the CompositionExclusion.txt list do not get * composed to. */ + @Test public void TestCompositionExclusion() throws Exception { // This list is generated from CompositionExclusion.txt. // Update whenever the normalizer tables are updated. Note @@ -397,14 +399,7 @@ private void checkCompositionExclusion_320(String s) throws Exception { String c = NormalizerBase.normalize(b, NFC); if (c.equals(a)) { - errln("FAIL: " + HexFormat.of().withDelimiter(" ") - .formatHex(a.getBytes()) + " x DECOMP_COMPAT => " + - HexFormat.of().withDelimiter(" ") - .formatHex(b.getBytes()) + " x COMPOSE => " + - HexFormat.of().withDelimiter(" ") - .formatHex(c.getBytes()) + " for the latest Unicode"); - } else if (verbose) { - logln("Ok: " + HexFormat.of().withDelimiter(" ") + fail("FAIL: " + HexFormat.of().withDelimiter(" ") .formatHex(a.getBytes()) + " x DECOMP_COMPAT => " + HexFormat.of().withDelimiter(" ") .formatHex(b.getBytes()) + " x COMPOSE => " + @@ -415,18 +410,14 @@ private void checkCompositionExclusion_320(String s) throws Exception { b = NormalizerBase.normalize(a, NFKD, Normalizer.UNICODE_3_2); c = NormalizerBase.normalize(b, NFC, Normalizer.UNICODE_3_2); if (c.equals(a)) { - errln("FAIL: " + HexFormat.of().withDelimiter(" ") - .formatHex(a.getBytes()) + " x DECOMP_COMPAT => " + - HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x COMPOSE => " + - HexFormat.of().withDelimiter(" ").formatHex(c.getBytes()) + " for Unicode 3.2.0"); - } else if (verbose) { - logln("Ok: " + HexFormat.of().withDelimiter(" ") + fail("FAIL: " + HexFormat.of().withDelimiter(" ") .formatHex(a.getBytes()) + " x DECOMP_COMPAT => " + HexFormat.of().withDelimiter(" ").formatHex(b.getBytes()) + " x COMPOSE => " + HexFormat.of().withDelimiter(" ").formatHex(c.getBytes()) + " for Unicode 3.2.0"); } } + @Test public void TestTibetan() throws Exception { String[][] decomp = { { "\u0f77", "\u0f77", "\u0fb2\u0f71\u0f80" } @@ -441,6 +432,7 @@ public void TestTibetan() throws Exception { staticTest(NFKC,compose, 2); } + @Test public void TestExplodingBase() throws Exception{ // \u017f - Latin small letter long s // \u0307 - combining dot above @@ -574,18 +566,22 @@ public void TestExplodingBase() throws Exception{ { "\u30AB\uFF9E", "\u30AB\u3099", "\u30AC" }, }; + @Test public void TestNFD() throws Exception{ staticTest(NFD, canonTests, 1); } + @Test public void TestNFC() throws Exception{ staticTest(NFC, canonTests, 2); } + @Test public void TestNFKD() throws Exception{ staticTest(NFKD, compatTests, 1); } + @Test public void TestNFKC() throws Exception{ staticTest(NFKC, compatTests, 2); } @@ -595,14 +591,14 @@ private void staticTest(java.text.Normalizer.Form form, int outCol) throws Exception { for (int i = 0; i < tests.length; i++) { String input = tests[i][0]; - logln("Normalizing '" + input + "' (" + HexFormat.of() + System.out.println("Normalizing '" + input + "' (" + HexFormat.of() .withDelimiter(" ").formatHex(input.getBytes()) + ")" ); String expect =tests[i][outCol]; String output = java.text.Normalizer.normalize(input, form); if (!output.equals(expect)) { - errln("FAIL: case " + i + fail("FAIL: case " + i + " expected '" + expect + "' (" + HexFormat.of() .withDelimiter(" ").formatHex(expect.getBytes()) + ")" + " but got '" + output + "' (" + HexFormat.of() @@ -621,13 +617,15 @@ private void staticTest(java.text.Normalizer.Form form, { "\u1111\u1171\u11b6", "\u1111\u1171\u11b6", "\ud4db" }, }; + @Test public void TestHangulCompose() throws Exception{ - logln("Canonical composition..."); + System.out.println("Canonical composition..."); staticTest(NFC, hangulCanon, 2); } + @Test public void TestHangulDecomp() throws Exception{ - logln("Canonical decomposition..."); + System.out.println("Canonical decomposition..."); staticTest(NFD, hangulCanon, 1); } diff --git a/test/jdk/java/text/Normalizer/NormalizerAPITest.java b/test/jdk/java/text/Normalizer/NormalizerAPITest.java index 00deb3c843c..d696d5cbc2d 100644 --- a/test/jdk/java/text/Normalizer/NormalizerAPITest.java +++ b/test/jdk/java/text/Normalizer/NormalizerAPITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,14 +26,17 @@ * @bug 4221795 8174270 * @summary Confirm Normalizer's fundamental behavior * @modules java.base/sun.text java.base/jdk.internal.icu.text - * @library /java/text/testlib * @compile -XDignore.symbol.file NormalizerAPITest.java - * @run main/timeout=30 NormalizerAPITest + * @run junit/timeout=30 NormalizerAPITest */ import java.text.Normalizer; import java.nio.CharBuffer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /* * Tests around null/"" arguments for public methods. @@ -41,7 +44,7 @@ * You may think that so elaborate testing for such a part is not necessary. * But I actually detected a bug by this program during my porting work. */ -public class NormalizerAPITest extends IntlTest { +public class NormalizerAPITest { // // Shortcuts @@ -71,13 +74,10 @@ public class NormalizerAPITest extends IntlTest { static final String nonNullStr = "testdata"; - public static void main(String[] args) throws Exception { - new NormalizerAPITest().run(args); - } - /* * Check if normalize(null) throws NullPointerException as expected. */ + @Test public void Test_NullPointerException_java_normalize() { boolean error = false; @@ -100,13 +100,14 @@ public void Test_NullPointerException_java_normalize() { } if (error) { - errln("normalize(null) should throw NullPointerException."); + fail("normalize(null) should throw NullPointerException."); } } /* * Check if normalize(null) throws NullPointerException as expected. */ + @Test public void Test_NullPointerException_sun_normalize() { boolean error = false; @@ -131,13 +132,14 @@ public void Test_NullPointerException_sun_normalize() { } if (error) { - errln("normalize(null) should throw NullPointerException."); + fail("normalize(null) should throw NullPointerException."); } } /* * Check if isNormalized(null) throws NullPointerException as expected. */ + @Test public void Test_NullPointerException_java_isNormalized() { boolean error = false; @@ -160,13 +162,14 @@ public void Test_NullPointerException_java_isNormalized() { catch (NullPointerException e) { } if (error) { - errln("isNormalized(null) should throw NullPointerException."); + fail("isNormalized(null) should throw NullPointerException."); } } /* * Check if isNormalized(null) throws NullPointerException as expected. */ + @Test public void Test_NullPointerException_sun_isNormalized() { boolean error = false; @@ -191,7 +194,7 @@ public void Test_NullPointerException_sun_isNormalized() { } if (error) { - errln("isNormalized(null) should throw NullPointerException."); + fail("isNormalized(null) should throw NullPointerException."); } } @@ -199,6 +202,7 @@ public void Test_NullPointerException_sun_isNormalized() { * Check if isNormalized("") doesn't throw NullPointerException and returns * "" as expected. */ + @Test public void Test_No_NullPointerException_java_normalize() { boolean error = false; @@ -215,7 +219,7 @@ public void Test_No_NullPointerException_java_normalize() { } if (error) { - errln("normalize() for String(\"\") should return \"\"."); + fail("normalize() for String(\"\") should return \"\"."); } } @@ -223,6 +227,7 @@ public void Test_No_NullPointerException_java_normalize() { * Check if isNormalized("") doesn't throw NullPointerException and returns * "" as expected. */ + @Test public void Test_No_NullPointerException_sun_normalize() { boolean error = false; @@ -240,7 +245,7 @@ public void Test_No_NullPointerException_sun_normalize() { } } if (error) { - errln("normalize() for String(\"\") should return \"\"."); + fail("normalize() for String(\"\") should return \"\"."); } } @@ -248,6 +253,7 @@ public void Test_No_NullPointerException_sun_normalize() { * Check if isNormalized("") doesn't throw NullPointerException and returns * "" as expected. */ + @Test public void Test_No_NullPointerException_java_isNormalized() { boolean error = false; @@ -263,7 +269,7 @@ public void Test_No_NullPointerException_java_isNormalized() { } } if (error) { - errln("isNormalized() for String(\"\") should not return true."); + fail("isNormalized() for String(\"\") should not return true."); } } @@ -271,6 +277,7 @@ public void Test_No_NullPointerException_java_isNormalized() { * Check if isNormalized("") doesn't throw NullPointerException and returns * "" as expected. */ + @Test public void Test_No_NullPointerException_sun_isNormalized() { boolean error = false; @@ -288,7 +295,7 @@ public void Test_No_NullPointerException_sun_isNormalized() { } } if (error) { - errln("isNormalized() for String(\"\") should not return true."); + fail("isNormalized() for String(\"\") should not return true."); } } @@ -296,6 +303,7 @@ public void Test_No_NullPointerException_sun_isNormalized() { * Check if normalize() and isNormalized() work as expected for every * known class which implement CharSequence Interface. */ + @Test public void Test_CharSequence() { check_CharSequence(String.valueOf(inputData), @@ -315,23 +323,23 @@ public void Test_CharSequence() { void check_CharSequence(CharSequence in, CharSequence expected) { String out = Normalizer.normalize(in, NFD); if (!out.equals(expected.toString())) { - errln("java.text.Normalizer.normalize(" + + fail("java.text.Normalizer.normalize(" + in.getClass().getSimpleName() + ") failed."); } out = sun.text.Normalizer.normalize(in, NFD, jdk.internal.icu.text.NormalizerBase.UNICODE_LATEST); if (!out.equals(expected.toString())) { - errln("sun.text.Normalizer.normalize(" + + fail("sun.text.Normalizer.normalize(" + in.getClass().getSimpleName() + ") failed."); } if (!Normalizer.isNormalized(expected, NFD)) { - errln("java.text.Normalizer.isNormalize(" + + fail("java.text.Normalizer.isNormalize(" + in.getClass().getSimpleName() + ") failed."); } if (!sun.text.Normalizer.isNormalized(expected, NFD, jdk.internal.icu.text.NormalizerBase.UNICODE_LATEST)) { - errln("sun.text.Normalizer.isNormalize(" + + fail("sun.text.Normalizer.isNormalize(" + in.getClass().getSimpleName() + ") failed."); } } diff --git a/test/jdk/java/text/testlib/HexDumpReader.java b/test/jdk/java/text/testlib/HexDumpReader.java index 31a820d04d4..61fcf27832a 100644 --- a/test/jdk/java/text/testlib/HexDumpReader.java +++ b/test/jdk/java/text/testlib/HexDumpReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -27,6 +27,7 @@ import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -37,7 +38,11 @@ * * $ od -vw -t x1 foo | sed -r -e 's/^[0-9]+ ?//' -e 's/ //g' -e '/^$/d' */ -public class HexDumpReader { +public final class HexDumpReader { + + // Utility class should not be instantiated + private HexDumpReader() {} + public static InputStream getStreamFromHexDump(String fileName) { return getStreamFromHexDump(new File(System.getProperty("test.src", "."), fileName)); @@ -48,7 +53,7 @@ public static InputStream getStreamFromHexDump(File hexFile) { int lineNo = 0; try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(hexFile), - "us-ascii"))) { + StandardCharsets.US_ASCII))) { String line; while ((line = reader.readLine()) != null) { lineNo++; diff --git a/test/jdk/java/text/testlib/IntlTest.java b/test/jdk/java/text/testlib/IntlTest.java deleted file mode 100644 index a3f1f72ab3f..00000000000 --- a/test/jdk/java/text/testlib/IntlTest.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 1998, 2023, 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.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Map; -import java.util.LinkedHashMap; -import java.util.List; - -/** - * IntlTest is a base class for tests that can be run conveniently from - * the command line as well as under the Java test harness. - *

    - * Sub-classes implement a set of public void methods named "Test*" or - * "test*" with no arguments. Each of these methods performs some - * test. Test methods should indicate errors by calling either err() or - * errln(). This will increment the errorCount field and may optionally - * print a message to the log. Debugging information may also be added to - * the log via the log and logln methods. These methods will add their - * arguments to the log only if the test is being run in verbose mode. - */ -public abstract class IntlTest { - - //------------------------------------------------------------------------ - // Everything below here is boilerplate code that makes it possible - // to add a new test by simply adding a method to an existing class. - //------------------------------------------------------------------------ - protected IntlTest() { - Class testClass = getClass(); - testName = testClass.getCanonicalName(); - // Populate testMethods with all the test methods. - Method[] methods = testClass.getDeclaredMethods(); - for (Method method : methods) { - if (Modifier.isPublic(method.getModifiers()) - && method.getReturnType() == void.class - && method.getParameterCount() == 0) { - String name = method.getName(); - if (name.length() > 4) { - if (name.startsWith("Test") || name.startsWith("test")) { - testMethods.put(name, method); - } - } - } - } - } - - protected void run(String[] args) throws Exception { - // Set up the log and reference streams. We use PrintWriters in order to - // take advantage of character conversion. The JavaEsc converter will - // convert Unicode outside the ASCII range to Java's \\uxxxx notation. - log = new PrintWriter(System.out, true); - List testsToRun = configureTestsAndArgs(args); - System.out.println(testName + " {"); - indentLevel++; - - // Run the list of tests given in the test arguments - for (Method testMethod : testsToRun) { - int oldCount = errorCount; - String testName = testMethod.getName(); - writeTestName(testName); - try { - testMethod.invoke(this); - } catch (IllegalAccessException e) { - errln("Can't access test method " + testName); - } catch (InvocationTargetException e) { - // Log exception first, that way if -nothrow is - // not an arg, the original exception is still logged - logExc(e); - errln(String.format("$$$ Uncaught exception thrown in %s," + - " see above for cause", testName)); - } - writeTestResult(errorCount - oldCount); - } - indentLevel--; - if (prompt) { - System.out.println("Hit RETURN to exit..."); - try { - System.in.read(); - } catch (IOException e) { - System.out.println("Exception: " + e.toString() + e.getMessage()); - } - } - if (exitCode) { - System.exit(errorCount); - } - if (errorCount > 0) { - throw new RuntimeException(String.format( - "$$$ %s FAILED with %s failures%n", testName, errorCount)); - } else { - log.println(String.format("\t$$$ %s PASSED%n", testName)); - } - } - - private List configureTestsAndArgs(String[] args) { - // Parse the test arguments. They can be either the flag - // "-verbose" or names of test methods. Create a list of - // tests to be run. - List testsToRun = new ArrayList<>(args.length); - for (String arg : args) { - switch (arg) { - case "-verbose" -> verbose = true; - case "-prompt" -> prompt = true; - case "-nothrow" -> nothrow = true; - case "-exitcode" -> exitCode = true; - default -> { - Method m = testMethods.get(arg); - if (m == null) { - System.out.println("Method " + arg + ": not found"); - usage(); - return testsToRun; - } - testsToRun.add(m); - } - } - } - // If no test method names were given explicitly, run them all. - if (testsToRun.isEmpty()) { - testsToRun.addAll(testMethods.values()); - } - // Arbitrarily sort the tests, so that they are run in the same order every time - testsToRun.sort(Comparator.comparing(Method::getName)); - return testsToRun; - } - - /** - * Adds the given message to the log if we are in verbose mode. - */ - protected void log(String message) { - logImpl(message, false); - } - - protected void logln(String message) { - logImpl(message, true); - } - - protected void logln() { - logImpl(null, true); - } - - private void logImpl(String message, boolean newline) { - if (verbose) { - if (message != null) { - indent(indentLevel + 1); - log.print(message); - } - if (newline) { - log.println(); - } - } - } - - private void logExc(InvocationTargetException ite) { - indent(indentLevel); - ite.getTargetException().printStackTrace(this.log); - } - - protected void err(String message) { - errImpl(message, false); - } - - protected void errln(String message) { - errImpl(message, true); - } - - private void errImpl(String message, boolean newline) { - errorCount++; - indent(indentLevel + 1); - log.print(message); - if (newline) { - log.println(); - } - log.flush(); - - if (!nothrow) { - throw new RuntimeException(message); - } - } - - protected int getErrorCount() { - return errorCount; - } - - protected void writeTestName(String testName) { - indent(indentLevel); - log.print(testName); - log.flush(); - needLineFeed = true; - } - - protected void writeTestResult(int count) { - if (!needLineFeed) { - indent(indentLevel); - log.print("}"); - } - needLineFeed = false; - - if (count != 0) { - log.println(" FAILED"); - } else { - log.println(" Passed"); - } - } - - private void indent(int distance) { - if (needLineFeed) { - log.println(" {"); - needLineFeed = false; - } - log.print(SPACES.substring(0, distance * 2)); - } - - /** - * Print a usage message for this test class. - */ - void usage() { - System.out.println(getClass().getName() + - ": [-verbose] [-nothrow] [-exitcode] [-prompt] [test names]"); - - System.out.println(" Available test names:"); - for (String methodName : testMethods.keySet()) { - System.out.println("\t" + methodName); - } - } - private final String testName; - private boolean prompt; - private boolean nothrow; - protected boolean verbose; - private boolean exitCode; - private PrintWriter log; - private int indentLevel; - private boolean needLineFeed; - private int errorCount; - - private final Map testMethods = new LinkedHashMap<>(); - - private static final String SPACES = " "; -} diff --git a/test/jdk/java/text/testlib/TestUtils.java b/test/jdk/java/text/testlib/TestUtils.java index 309df451697..f2f7e57e197 100644 --- a/test/jdk/java/text/testlib/TestUtils.java +++ b/test/jdk/java/text/testlib/TestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,23 +21,35 @@ * questions. */ +import java.text.CollationElementIterator; +import java.text.CollationKey; +import java.text.Collator; import java.text.DecimalFormatSymbols; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Locale; -import java.util.Locale.Builder; - /** - * TestUtils provides utility methods to get a locale-dependent attribute. - * For example, - * - whether or not a non-Gregorian calendar is used - * - whether or not non-ASCII digits are used - * + * TestUtils provides utility methods used by i18n related tests. * This class was developed to help testing for internationalization & - * localization and is not versatile. + * localization and is not versatile. This class is split into the following sections, + * 1) Methods to get a locale-dependent attribute. + * For example, + * - whether a non-Gregorian calendar is used + * - whether non-ASCII digits are used + * 2) Methods that help Collator related tests + * For example, + * - compare CollationElementIterators + * - test the expected relation key result for a Collator */ -public class TestUtils { +public final class TestUtils { + + // Utility class should not be instantiated + private TestUtils() {} + + /* + * The below methods are utilities for getting locale-dependent attributes. + */ /** * Returns true if the give locale uses Gregorian calendar. @@ -56,7 +68,6 @@ public static boolean usesAsciiDigits(Locale locale) { /** * Returns true if the given locale has a special variant which is treated * as ill-formed in BCP 47. - * * BCP 47 requires a variant subtag to be 5 to 8 alphanumerics or a * single numeric followed by 3 alphanumerics. * However, note that this methods doesn't check a variant so rigorously @@ -71,4 +82,103 @@ public static boolean hasSpecialVariant(Locale locale) { && "JP".equals(variant) || "NY".equals(variant) || "TH".equals(variant); } + /* + * The below methods are utilities specific to the Collation tests + */ + + /** + * Compares two CollationElementIterators and throws an exception + * with a message detailing which collation elements were not equal + */ + public static void compareCollationElementIters(CollationElementIterator i1, CollationElementIterator i2) { + int c1, c2, count = 0; + do { + c1 = i1.next(); + c2 = i2.next(); + if (c1 != c2) { + throw new RuntimeException(" " + count + ": " + c1 + " != " + c2); + } + count++; + } while (c1 != CollationElementIterator.NULLORDER); + } + + // Replace non-printable characters with unicode escapes + public static String prettify(String str) { + StringBuilder result = new StringBuilder(); + + String zero = "0000"; + + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| (ch > 0x7E && ch < 0xA0) || ch > 0x100) { + String hex = Integer.toString((int)ch,16); + + result.append("\\u").append(zero.substring(0, 4 - hex.length())).append(hex); + } else { + result.append(ch); + } + } + return result.toString(); + } + + // Produce a printable representation of a CollationKey + public static String prettifyCKey(CollationKey key) { + StringBuilder result = new StringBuilder(); + byte[] bytes = key.toByteArray(); + + for (int i = 0; i < bytes.length; i += 2) { + int val = (bytes[i] << 8) + bytes[i+1]; + result.append(Integer.toString(val, 16)).append(" "); + } + return result.toString(); + } + + /** + * Utility to test a collator with an array of test values. + * See the other doTest() method for specific comparison details. + */ + public static void doCollatorTest(Collator col, int strength, + String[] source, String[] target, int[] result) { + if (source.length != target.length) { + throw new RuntimeException("Data size mismatch: source = " + + source.length + ", target = " + target.length); + } + if (source.length != result.length) { + throw new RuntimeException("Data size mismatch: source & target = " + + source.length + ", result = " + result.length); + } + + col.setStrength(strength); + for (int i = 0; i < source.length ; i++) { + doCollatorTest(col, source[i], target[i], result[i]); + } + } + + /** + * Test that a collator returns the correct relation result value when + * comparing a source and target string. Also tests that the compare and collation + * key results return the same value. + */ + public static void doCollatorTest(Collator col, + String source, String target, int result) { + char relation = '='; + if (result <= -1) { + relation = '<'; + } else if (result >= 1) { + relation = '>'; + } + + int compareResult = col.compare(source, target); + CollationKey sortKey1 = col.getCollationKey(source); + CollationKey sortKey2 = col.getCollationKey(target); + int keyResult = sortKey1.compareTo(sortKey2); + if (compareResult != keyResult) { + throw new RuntimeException("Compare and Collation Key results are different! Source = " + + source + " Target = " + target); + } + if (keyResult != result) { + throw new RuntimeException("Collation Test failed! Source = " + source + " Target = " + + target + " result should be " + relation); + } + } } diff --git a/test/jdk/java/util/Calendar/CalendarLimitTest.java b/test/jdk/java/util/Calendar/CalendarLimitTest.java index ec73cc27bc5..e8a92f180ec 100644 --- a/test/jdk/java/util/Calendar/CalendarLimitTest.java +++ b/test/jdk/java/util/Calendar/CalendarLimitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,12 +26,16 @@ * @bug 4033662 * @summary test for limit on Calendar * @library /java/text/testlib - * @run main CalendarLimitTest -verbose + * @run junit CalendarLimitTest */ import java.util.*; import java.text.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /** * This test verifies the behavior of Calendar around the very earliest limits * which it can handle. It also verifies the behavior for large values of millis. @@ -42,7 +46,7 @@ * March 17, 1998: Added code to make sure big + dates are big + AD years, and * big - dates are big + BC years. */ -public class CalendarLimitTest extends IntlTest +public class CalendarLimitTest { // This number determined empirically; this is the old limit, // which we test for to make sure it isn't there anymore. @@ -61,16 +65,6 @@ public class CalendarLimitTest extends IntlTest static long ORIGIN; // This is the *approximate* point at which BC switches to AD - public static void main(String argv[]) throws Exception { - Locale locale = Locale.getDefault(); - if (!TestUtils.usesGregorianCalendar(locale)) { - System.out.println("Skipping this test because locale is " + locale); - return; - } - - new CalendarLimitTest().run(argv); - } - /** * Converts Julian day to time as milliseconds. * @param julian the given Julian day number. @@ -108,32 +102,38 @@ int test(long millis, Calendar cal, DateFormat fmt) boolean ok = true; if (exception != null) { - errln("FAIL: Exception " + s); + fail("FAIL: Exception " + s); ok = false; } if (((millis >= ORIGIN) && (era != GregorianCalendar.AD)) || ((millis < ORIGIN) && (era != GregorianCalendar.BC)) || (year < 1)) { - errln("FAIL: Bad year/era " + s); + fail("FAIL: Bad year/era " + s); ok = false; } if (dom<1 || dom>31) { - errln("FAIL: Bad DOM " + s); + fail("FAIL: Bad DOM " + s); ok = false; } if (Math.abs(millis - rt.getTime()) > ONE_DAY) { - errln("FAIL: RT fail " + s + " -> 0x" + + fail("FAIL: RT fail " + s + " -> 0x" + Long.toHexString(rt.getTime()) + " " + fmt.format(rt)); ok = false; } - if (ok) logln(s); + if (ok) System.out.println(s); if (era==GregorianCalendar.BC) year = 1-year; return year; } + @Test public void TestCalendarLimit() { + Locale locale = Locale.getDefault(); + if (!TestUtils.usesGregorianCalendar(locale)) { + System.out.println("Skipping this test because locale is " + locale); + return; + } ORIGIN = julianDayToMillis(JAN_1_1_JULIAN_DAY); Calendar cal = Calendar.getInstance(); @@ -154,7 +154,7 @@ public void TestCalendarLimit() { int y = test(m, cal, dateFormat); if (!first && y > lastYear) - errln("FAIL: Years should be decreasing " + lastYear + " " + y); + fail("FAIL: Years should be decreasing " + lastYear + " " + y); first = false; lastYear = y; } @@ -165,7 +165,7 @@ public void TestCalendarLimit() { int y = test(m, cal, dateFormat); if (!first && y < lastYear) - errln("FAIL: Years should be increasing " + lastYear + " " + y); + fail("FAIL: Years should be increasing " + lastYear + " " + y); first = false; lastYear = y; } @@ -188,7 +188,7 @@ public void TestCalendarLimit() cal.set(292269055, Calendar.DECEMBER, dom, h, 0); Date d = cal.getTime(); cal.setTime(d); - logln("" + h + ":00 Dec "+dom+", 292269055 BC -> " + + System.out.println("" + h + ":00 Dec "+dom+", 292269055 BC -> " + Long.toHexString(d.getTime()) + " -> " + dateFormat.format(cal.getTime())); } @@ -197,7 +197,7 @@ public void TestCalendarLimit() long t = 0x80000000018c5c00L; // Dec 3, 292269055 BC while (t<0) { cal.setTime(new Date(t)); - logln("0x" + Long.toHexString(t) + " -> " + + System.out.println("0x" + Long.toHexString(t) + " -> " + dateFormat.format(cal.getTime())); t -= ONE_HOUR; } diff --git a/test/jdk/java/util/Calendar/CalendarRegression.java b/test/jdk/java/util/Calendar/CalendarRegression.java index 44da44a3133..24d34533bde 100644 --- a/test/jdk/java/util/Calendar/CalendarRegression.java +++ b/test/jdk/java/util/Calendar/CalendarRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -32,7 +32,7 @@ * 4652815 4652830 4740554 4936355 4738710 4633646 4846659 4822110 4960642 * 4973919 4980088 4965624 5013094 5006864 8152077 * @library /java/text/testlib - * @run main CalendarRegression + * @run junit CalendarRegression */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -53,22 +53,16 @@ import static java.util.Calendar.*; -public class CalendarRegression extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new CalendarRegression().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class CalendarRegression { /* Synopsis: java.sql.Timestamp constructor works wrong on Windows 95 ==== Here is the test ==== - public static void main (String args[]) { - java.sql.Timestamp t= new java.sql.Timestamp(0,15,5,5,8,13,123456700); - logln("expected=1901-04-05 05:08:13.1234567"); - logln(" result="+t); - } - ==== Here is the output of the test on Solaris or NT ==== expected=1901-04-05 05:08:13.1234567 result=1901-04-05 05:08:13.1234567 @@ -77,6 +71,7 @@ public static void main (String args[]) { expected=1901-04-05 05:08:13.1234567 result=1901-04-05 06:08:13.1234567 */ + @Test public void Test4031502() { // This bug actually occurs on Windows NT as well, and doesn't // require the host zone to be set; it can be set in Java. @@ -88,7 +83,7 @@ public void Test4031502() { cal.clear(); cal.set(1900, 15, 5, 5, 8, 13); if (cal.get(HOUR) != 5) { - logln(zone.getID() + " " + System.out.println(zone.getID() + " " + //zone.useDaylightTime() + " " + cal.get(DST_OFFSET) / (60 * 60 * 1000) + " " + zone.getRawOffset() / (60 * 60 * 1000) @@ -97,10 +92,11 @@ public void Test4031502() { } } if (bad) { - errln("TimeZone problems with GC"); + fail("TimeZone problems with GC"); } } + @Test public void Test4035301() { GregorianCalendar c = new GregorianCalendar(98, 8, 7); GregorianCalendar d = new GregorianCalendar(98, 8, 7); @@ -110,10 +106,11 @@ public void Test4035301() { || c.before(c) || !c.equals(c) || !c.equals(d)) { - errln("Fail"); + fail("Fail"); } } + @Test public void Test4040996() { String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]); @@ -125,97 +122,100 @@ public void Test4040996() { calendar.set(DAY_OF_MONTH, 18); calendar.set(SECOND, 30); - logln("MONTH: " + calendar.get(MONTH)); - logln("DAY_OF_MONTH: " + System.out.println("MONTH: " + calendar.get(MONTH)); + System.out.println("DAY_OF_MONTH: " + calendar.get(DAY_OF_MONTH)); - logln("MINUTE: " + calendar.get(MINUTE)); - logln("SECOND: " + calendar.get(SECOND)); + System.out.println("MINUTE: " + calendar.get(MINUTE)); + System.out.println("SECOND: " + calendar.get(SECOND)); calendar.add(SECOND, 6); //This will print out todays date for MONTH and DAY_OF_MONTH //instead of the date it was set to. //This happens when adding MILLISECOND or MINUTE also - logln("MONTH: " + calendar.get(MONTH)); - logln("DAY_OF_MONTH: " + System.out.println("MONTH: " + calendar.get(MONTH)); + System.out.println("DAY_OF_MONTH: " + calendar.get(DAY_OF_MONTH)); - logln("MINUTE: " + calendar.get(MINUTE)); - logln("SECOND: " + calendar.get(SECOND)); + System.out.println("MINUTE: " + calendar.get(MINUTE)); + System.out.println("SECOND: " + calendar.get(SECOND)); if (calendar.get(MONTH) != 3 || calendar.get(DAY_OF_MONTH) != 18 || calendar.get(SECOND) != 36) { - errln("Fail: Calendar.add misbehaves"); + fail("Fail: Calendar.add misbehaves"); } } + @Test public void Test4051765() { Calendar cal = Calendar.getInstance(); cal.setLenient(false); cal.set(DAY_OF_WEEK, 0); try { cal.getTime(); - errln("Fail: DAY_OF_WEEK 0 should be disallowed"); + fail("Fail: DAY_OF_WEEK 0 should be disallowed"); } catch (IllegalArgumentException e) { return; } } /* User error - no bug here + @Test public void Test4059524() { // Create calendar for April 10, 1997 GregorianCalendar calendar = new GregorianCalendar(); // print out a bunch of interesting things - logln("ERA: " + calendar.get(calendar.ERA)); - logln("YEAR: " + calendar.get(calendar.YEAR)); - logln("MONTH: " + calendar.get(calendar.MONTH)); - logln("WEEK_OF_YEAR: " + + System.out.println("ERA: " + calendar.get(calendar.ERA)); + System.out.println("YEAR: " + calendar.get(calendar.YEAR)); + System.out.println("MONTH: " + calendar.get(calendar.MONTH)); + System.out.println("WEEK_OF_YEAR: " + calendar.get(calendar.WEEK_OF_YEAR)); - logln("WEEK_OF_MONTH: " + + System.out.println("WEEK_OF_MONTH: " + calendar.get(calendar.WEEK_OF_MONTH)); - logln("DATE: " + calendar.get(calendar.DATE)); - logln("DAY_OF_MONTH: " + + System.out.println("DATE: " + calendar.get(calendar.DATE)); + System.out.println("DAY_OF_MONTH: " + calendar.get(calendar.DAY_OF_MONTH)); - logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); - logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); - logln("DAY_OF_WEEK_IN_MONTH: " + + System.out.println("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); + System.out.println("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); + System.out.println("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); - logln("AM_PM: " + calendar.get(calendar.AM_PM)); - logln("HOUR: " + calendar.get(calendar.HOUR)); - logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); - logln("MINUTE: " + calendar.get(calendar.MINUTE)); - logln("SECOND: " + calendar.get(calendar.SECOND)); - logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); - logln("ZONE_OFFSET: " + System.out.println("AM_PM: " + calendar.get(calendar.AM_PM)); + System.out.println("HOUR: " + calendar.get(calendar.HOUR)); + System.out.println("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); + System.out.println("MINUTE: " + calendar.get(calendar.MINUTE)); + System.out.println("SECOND: " + calendar.get(calendar.SECOND)); + System.out.println("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); + System.out.println("ZONE_OFFSET: " + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); - logln("DST_OFFSET: " + System.out.println("DST_OFFSET: " + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); calendar = new GregorianCalendar(1997,3,10); calendar.getTime(); - logln("April 10, 1997"); - logln("ERA: " + calendar.get(calendar.ERA)); - logln("YEAR: " + calendar.get(calendar.YEAR)); - logln("MONTH: " + calendar.get(calendar.MONTH)); - logln("WEEK_OF_YEAR: " + + System.out.println("April 10, 1997"); + System.out.println("ERA: " + calendar.get(calendar.ERA)); + System.out.println("YEAR: " + calendar.get(calendar.YEAR)); + System.out.println("MONTH: " + calendar.get(calendar.MONTH)); + System.out.println("WEEK_OF_YEAR: " + calendar.get(calendar.WEEK_OF_YEAR)); - logln("WEEK_OF_MONTH: " + + System.out.println("WEEK_OF_MONTH: " + calendar.get(calendar.WEEK_OF_MONTH)); - logln("DATE: " + calendar.get(calendar.DATE)); - logln("DAY_OF_MONTH: " + + System.out.println("DATE: " + calendar.get(calendar.DATE)); + System.out.println("DAY_OF_MONTH: " + calendar.get(calendar.DAY_OF_MONTH)); - logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); - logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); - logln("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); - logln("AM_PM: " + calendar.get(calendar.AM_PM)); - logln("HOUR: " + calendar.get(calendar.HOUR)); - logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); - logln("MINUTE: " + calendar.get(calendar.MINUTE)); - logln("SECOND: " + calendar.get(calendar.SECOND)); - logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); - logln("ZONE_OFFSET: " + System.out.println("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); + System.out.println("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); + System.out.println("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); + System.out.println("AM_PM: " + calendar.get(calendar.AM_PM)); + System.out.println("HOUR: " + calendar.get(calendar.HOUR)); + System.out.println("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); + System.out.println("MINUTE: " + calendar.get(calendar.MINUTE)); + System.out.println("SECOND: " + calendar.get(calendar.SECOND)); + System.out.println("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); + System.out.println("ZONE_OFFSET: " + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); // in hours - logln("DST_OFFSET: " + System.out.println("DST_OFFSET: " + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); // in hours } */ + @Test public void Test4059654() { GregorianCalendar gc = new GregorianCalendar(); @@ -231,10 +231,11 @@ public void Test4059654() { @SuppressWarnings("deprecation") Date exp = new Date(97, 3, 1, 0, 0, 0); if (!cd.equals(exp)) { - errln("Fail: Calendar.set broken. Got " + cd + " Want " + exp); + fail("Fail: Calendar.set broken. Got " + cd + " Want " + exp); } } + @Test public void Test4061476() { SimpleDateFormat fmt = new SimpleDateFormat("ddMMMyy", Locale.UK); Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"), @@ -246,14 +247,15 @@ public void Test4061476() { } catch (Exception e) { } cal.set(HOUR_OF_DAY, 13); - logln("Hour: " + cal.get(HOUR_OF_DAY)); + System.out.println("Hour: " + cal.get(HOUR_OF_DAY)); cal.add(HOUR_OF_DAY, 6); - logln("Hour: " + cal.get(HOUR_OF_DAY)); + System.out.println("Hour: " + cal.get(HOUR_OF_DAY)); if (cal.get(HOUR_OF_DAY) != 19) { - errln("Fail: Want 19 Got " + cal.get(HOUR_OF_DAY)); + fail("Fail: Want 19 Got " + cal.get(HOUR_OF_DAY)); } } + @Test public void Test4070502() { @SuppressWarnings("deprecation") Date d = getAssociatedDate(new Date(98, 0, 30)); @@ -261,7 +263,7 @@ public void Test4070502() { cal.setTime(d); if (cal.get(DAY_OF_WEEK) == SATURDAY || cal.get(DAY_OF_WEEK) == SUNDAY) { - errln("Fail: Want weekday Got " + d); + fail("Fail: Want weekday Got " + d); } } @@ -289,6 +291,7 @@ public static Date getAssociatedDate(Date d) { return cal.getTime(); } + @Test public void Test4071197() { dowTest(false); dowTest(true); @@ -303,29 +306,31 @@ void dowTest(boolean lenient) { int dow = cal.get(DAY_OF_WEEK); int min = cal.getMinimum(DAY_OF_WEEK); int max = cal.getMaximum(DAY_OF_WEEK); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (min != SUNDAY || max != SATURDAY) { - errln("FAIL: Min/max bad"); + fail("FAIL: Min/max bad"); } if (dow < min || dow > max) { - errln("FAIL: Day of week " + dow + " out of range"); + fail("FAIL: Day of week " + dow + " out of range"); } if (dow != SUNDAY) { - errln("FAIL: Day of week should be SUNDAY Got " + dow); + fail("FAIL: Day of week should be SUNDAY Got " + dow); } } @SuppressWarnings("deprecation") + @Test public void Test4071385() { Calendar cal = Calendar.getInstance(); cal.setTime(new Date(98, JUNE, 24)); cal.set(MONTH, NOVEMBER); // change a field - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(new Date(98, NOVEMBER, 24))) { - errln("Fail"); + fail("Fail"); } } + @Test public void Test4073929() { GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27); foo1.add(DAY_OF_MONTH, +1); @@ -335,10 +340,11 @@ public void Test4073929() { if (testyear != 1997 || testmonth != 8 || testday != 28) { - errln("Fail: Calendar not initialized"); + fail("Fail: Calendar not initialized"); } } + @Test public void Test4083167() { TimeZone saveZone = TimeZone.getDefault(); try { @@ -351,7 +357,7 @@ public void Test4083167() { + cal.get(SECOND) * 1000L + cal.get(MILLISECOND); - logln("Current time: " + firstDate.toString()); + System.out.println("Current time: " + firstDate.toString()); for (int validity = 0; validity < 30; validity++) { Date lastDate = new Date(firstDate.getTime() @@ -362,7 +368,7 @@ public void Test4083167() { + cal.get(SECOND) * 1000L + cal.get(MILLISECOND); if (firstMillisInDay != millisInDay) { - errln("Day has shifted " + lastDate); + fail("Day has shifted " + lastDate); } } } finally { @@ -370,6 +376,7 @@ public void Test4083167() { } } + @Test public void Test4086724() { SimpleDateFormat date; TimeZone saveZone = TimeZone.getDefault(); @@ -387,12 +394,12 @@ public void Test4086724() { Date now = cal.getTime(); String formattedDate = date.format(now); if (!formattedDate.equals(summerTime)) { - errln("Wrong display name \"" + formattedDate + fail("Wrong display name \"" + formattedDate + "\" for <" + now + ">"); } int weekOfYear = cal.get(WEEK_OF_YEAR); if (weekOfYear != 40) { - errln("Wrong week-of-year " + weekOfYear + fail("Wrong week-of-year " + weekOfYear + " for <" + now + ">"); } @@ -400,12 +407,12 @@ public void Test4086724() { now = cal.getTime(); formattedDate = date.format(now); if (!formattedDate.equals(standardTime)) { - errln("Wrong display name \"" + formattedDate + fail("Wrong display name \"" + formattedDate + "\" for <" + now + ">"); } weekOfYear = cal.get(WEEK_OF_YEAR); if (weekOfYear != 1) { - errln("Wrong week-of-year " + weekOfYear + fail("Wrong week-of-year " + weekOfYear + " for <" + now + ">"); } @@ -413,12 +420,12 @@ public void Test4086724() { now = cal.getTime(); formattedDate = date.format(now); if (!formattedDate.equals(standardTime)) { - errln("Wrong display name \"" + formattedDate + fail("Wrong display name \"" + formattedDate + "\" for <" + now + ">"); } weekOfYear = cal.get(WEEK_OF_YEAR); if (weekOfYear != 1) { - errln("Wrong week-of-year " + weekOfYear + fail("Wrong week-of-year " + weekOfYear + " for <" + now + ">"); } @@ -426,12 +433,12 @@ public void Test4086724() { now = cal.getTime(); formattedDate = date.format(now); if (!formattedDate.equals(standardTime)) { - errln("Wrong display name \"" + formattedDate + fail("Wrong display name \"" + formattedDate + "\" for <" + now + ">"); } weekOfYear = cal.get(WEEK_OF_YEAR); if (weekOfYear != 2) { - errln("Wrong week-of-year " + weekOfYear + fail("Wrong week-of-year " + weekOfYear + " for <" + now + ">"); } @@ -441,6 +448,7 @@ public void Test4086724() { } } + @Test public void Test4092362() { GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); /*cal1.set( Calendar.YEAR, 1997 ); @@ -450,8 +458,8 @@ public void Test4092362() { cal1.set( Calendar.MINUTE, 20 ); cal1.set( Calendar.SECOND, 40 ); */ - logln(" Cal1 = " + cal1.getTime().getTime()); - logln(" Cal1 time in ms = " + cal1.get(MILLISECOND)); + System.out.println(" Cal1 = " + cal1.getTime().getTime()); + System.out.println(" Cal1 time in ms = " + cal1.get(MILLISECOND)); for (int k = 0; k < 100; k++); GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); @@ -462,21 +470,23 @@ public void Test4092362() { cal2.set( Calendar.MINUTE, 20 ); cal2.set( Calendar.SECOND, 40 ); */ - logln(" Cal2 = " + cal2.getTime().getTime()); - logln(" Cal2 time in ms = " + cal2.get(MILLISECOND)); + System.out.println(" Cal2 = " + cal2.getTime().getTime()); + System.out.println(" Cal2 time in ms = " + cal2.get(MILLISECOND)); if (!cal1.equals(cal2)) { - errln("Fail: Milliseconds randomized"); + fail("Fail: Milliseconds randomized"); } } + @Test public void Test4095407() { GregorianCalendar a = new GregorianCalendar(1997, NOVEMBER, 13); int dow = a.get(DAY_OF_WEEK); if (dow != THURSDAY) { - errln("Fail: Want THURSDAY Got " + dow); + fail("Fail: Want THURSDAY Got " + dow); } } + @Test public void Test4096231() { TimeZone GMT = TimeZone.getTimeZone("GMT"); TimeZone PST = TimeZone.getTimeZone("PST"); @@ -485,19 +495,19 @@ public void Test4096231() { Calendar cal1 = new GregorianCalendar(PST); cal1.setTime(new Date(880698639000L)); int p; - logln("PST 1 is: " + (p = cal1.get(HOUR_OF_DAY))); + System.out.println("PST 1 is: " + (p = cal1.get(HOUR_OF_DAY))); cal1.setTimeZone(GMT); // Issue 1: Changing the timezone doesn't change the // represented time. int h1, h2; - logln("GMT 1 is: " + (h1 = cal1.get(HOUR_OF_DAY))); + System.out.println("GMT 1 is: " + (h1 = cal1.get(HOUR_OF_DAY))); cal1.setTime(new Date(880698639000L)); - logln("GMT 2 is: " + (h2 = cal1.get(HOUR_OF_DAY))); + System.out.println("GMT 2 is: " + (h2 = cal1.get(HOUR_OF_DAY))); // Note: This test had a bug in it. It wanted h1!=h2, when // what was meant was h1!=p. Fixed this concurrent with fix // to 4177484. if (p == h1 || h1 != h2) { - errln("Fail: Hour same in different zones"); + fail("Fail: Hour same in different zones"); } Calendar cal2 = new GregorianCalendar(GMT); @@ -513,11 +523,11 @@ public void Test4096231() { cal1.get(SECOND)); long t1, t2, t3, t4; - logln("RGMT 1 is: " + (t1 = cal2.getTime().getTime())); + System.out.println("RGMT 1 is: " + (t1 = cal2.getTime().getTime())); cal3.set(year, month, day, hr, min, sec); - logln("RPST 1 is: " + (t2 = cal3.getTime().getTime())); + System.out.println("RPST 1 is: " + (t2 = cal3.getTime().getTime())); cal3.setTimeZone(GMT); - logln("RGMT 2 is: " + (t3 = cal3.getTime().getTime())); + System.out.println("RGMT 2 is: " + (t3 = cal3.getTime().getTime())); cal3.set(cal1.get(YEAR), cal1.get(MONTH), cal1.get(DAY_OF_MONTH), @@ -527,40 +537,42 @@ public void Test4096231() { // Issue 2: Calendar continues to use the timezone in its // constructor for set() conversions, regardless // of calls to setTimeZone() - logln("RGMT 3 is: " + (t4 = cal3.getTime().getTime())); + System.out.println("RGMT 3 is: " + (t4 = cal3.getTime().getTime())); if (t1 == t2 || t1 != t4 || t2 != t3) { - errln("Fail: Calendar zone behavior faulty"); + fail("Fail: Calendar zone behavior faulty"); } } + @Test public void Test4096539() { int[] y = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (int x = 0; x < 12; x++) { GregorianCalendar gc = new GregorianCalendar(1997, x, y[x]); int m1, m2; - log((m1 = gc.get(MONTH) + 1) + "/" + System.out.println((m1 = gc.get(MONTH) + 1) + "/" + gc.get(DATE) + "/" + gc.get(YEAR) + " + 1mo = "); gc.add(MONTH, 1); - logln((m2 = gc.get(MONTH) + 1) + "/" + System.out.println((m2 = gc.get(MONTH) + 1) + "/" + gc.get(DATE) + "/" + gc.get(YEAR) ); int m = (m1 % 12) + 1; if (m2 != m) { - errln("Fail: Want " + m + " Got " + m2); + fail("Fail: Want " + m + " Got " + m2); } } } + @Test public void Test4100311() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -568,16 +580,17 @@ public void Test4100311() { cal.set(YEAR, 1997); cal.set(DAY_OF_YEAR, 1); Date d = cal.getTime(); // Should be Jan 1 - logln(d.toString()); + System.out.println(d.toString()); if (cal.get(DAY_OF_YEAR) != 1) { - errln("Fail: DAY_OF_YEAR not set"); + fail("Fail: DAY_OF_YEAR not set"); } } + @Test public void Test4103271() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -594,7 +607,7 @@ public void Test4103271() { testCal.setMinimalDaysInFirstWeek(minDays); testCal.setFirstDayOfWeek(firstDay); testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays)); - logln(testDesc + " => 1st day of week=" + System.out.println(testDesc + " => 1st day of week=" + String.valueOf(firstDay) + ", minimum days in first week=" + String.valueOf(minDays)); @@ -609,7 +622,7 @@ public void Test4103271() { calWOY = String.valueOf(actWOY); output = testDesc + " - " + sdf.format(d) + "\t"; output = output + "\t" + calWOY; - logln(output); + System.out.println(output); fail = true; } } @@ -626,18 +639,18 @@ public void Test4103271() { 1, 1, 1, 1, 1, 1, 1}; testCal.setFirstDayOfWeek(SUNDAY); for (int j = 0; j < DATA.length; j += 22) { - logln("Minimal days in first week = " + DATA[j] + System.out.println("Minimal days in first week = " + DATA[j] + " Week starts on Sunday"); testCal.setMinimalDaysInFirstWeek(DATA[j]); testCal.set(1997, DECEMBER, 21); for (int i = 0; i < 21; ++i) { int woy = testCal.get(WEEK_OF_YEAR); - log("\t" + testCal.getTime() + " " + woy); + System.out.println("\t" + testCal.getTime() + " " + woy); if (woy != DATA[j + 1 + i]) { - log(" ERROR"); + System.out.println(" ERROR"); fail = true; } else { - logln(" OK"); + System.out.println(" OK"); } // Now compute the time from the fields, and make sure we @@ -648,10 +661,10 @@ public void Test4103271() { testCal.set(WEEK_OF_YEAR, DATA[j + 1 + i]); testCal.set(DAY_OF_WEEK, (i % 7) + SUNDAY); if (!testCal.getTime().equals(save)) { - logln(" Parse failed: " + testCal.getTime()); + System.out.println(" Parse failed: " + testCal.getTime()); fail = true; } else { - logln(" Passed"); + System.out.println(" Passed"); } testCal.setTime(save); @@ -682,12 +695,12 @@ public void Test4103271() { testCal.set(YEAR, y); testCal.set(WEEK_OF_YEAR, woy); testCal.set(DAY_OF_WEEK, dow); - log(y + "-W" + woy + "-DOW" + dow); + System.out.println(y + "-W" + woy + "-DOW" + dow); if (!testCal.getTime().equals(exp)) { - logln(" FAILED expect: " + exp + "\n got: " + testCal.getTime()); + System.out.println(" FAILED expect: " + exp + "\n got: " + testCal.getTime()); fail = true; } else { - logln(" OK"); + System.out.println(" OK"); } } @@ -714,14 +727,14 @@ public void Test4103271() { } else { testCal.roll(WEEK_OF_YEAR, amount); } - log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") + System.out.println((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") + amount + ")\t " + before + "\n\t\t => " + testCal.getTime()); if (!after.equals(testCal.getTime())) { - logln("\tFAIL\n\t\texp: " + after); + System.out.println("\tFAIL\n\t\texp: " + after); fail = true; } else { - logln(" OK"); + System.out.println(" OK"); } testCal.setTime(after); @@ -730,22 +743,23 @@ public void Test4103271() { } else { testCal.roll(WEEK_OF_YEAR, -amount); } - log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") + System.out.println((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") + (-amount) + ") " + after + "\n\t\t => " + testCal.getTime()); if (!before.equals(testCal.getTime())) { - logln("\tFAIL\n\t\texp: " + before); + System.out.println("\tFAIL\n\t\texp: " + before); fail = true; } else { - logln("\tOK"); + System.out.println("\tOK"); } } if (fail) { - errln("Fail: Week of year misbehaving"); + fail("Fail: Week of year misbehaving"); } } + @Test public void Test4106136() { Locale saveLocale = Locale.getDefault(); try { @@ -758,7 +772,7 @@ public void Test4106136() { NumberFormat.getAvailableLocales().length}; for (int j = 0; j < n.length; ++j) { if (n[j] == 0) { - errln("Fail: No locales for " + locales[i]); + fail("Fail: No locales for " + locales[i]); } } } @@ -768,6 +782,7 @@ public void Test4106136() { } @SuppressWarnings("deprecation") + @Test public void Test4108764() { Date d00 = new Date(97, MARCH, 15, 12, 00, 00); Date d01 = new Date(97, MARCH, 15, 12, 00, 56); @@ -779,42 +794,43 @@ public void Test4108764() { cal.setTime(d11); cal.clear(MINUTE); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(d01)) { - errln("Fail: clear(MINUTE) broken"); + fail("Fail: clear(MINUTE) broken"); } cal.set(SECOND, 0); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(d00)) { - errln("Fail: set(SECOND, 0) broken"); + fail("Fail: set(SECOND, 0) broken"); } cal.setTime(d11); cal.set(SECOND, 0); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(d10)) { - errln("Fail: set(SECOND, 0) broken #2"); + fail("Fail: set(SECOND, 0) broken #2"); } cal.clear(MINUTE); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(d00)) { - errln("Fail: clear(MINUTE) broken #2"); + fail("Fail: clear(MINUTE) broken #2"); } cal.clear(); - logln(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); if (!cal.getTime().equals(epoch)) { - errln("Fail: clear() broken Want " + epoch); + fail("Fail: clear() broken Want " + epoch); } } @SuppressWarnings("deprecation") + @Test public void Test4114578() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -849,28 +865,28 @@ public void Test4114578() { int amt = (int) DATA[i + 2]; long expectedChange = DATA[i + 3]; - log(date.toString()); + System.out.println(date.toString()); cal.setTime(date); switch ((int) DATA[i + 1]) { case ADD: - log(" add (HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); + System.out.println(" add (HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); cal.add(HOUR, amt); break; case ROLL: - log(" roll(HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); + System.out.println(" roll(HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); cal.roll(HOUR, amt); break; } - log(cal.getTime().toString()); + System.out.println(cal.getTime().toString()); long change = cal.getTime().getTime() - date.getTime(); if (change != expectedChange) { fail = true; - logln(" FAIL"); + System.out.println(" FAIL"); } else { - logln(" OK"); + System.out.println(" OK"); } } } finally { @@ -878,29 +894,31 @@ public void Test4114578() { } if (fail) { - errln("Fail: roll/add misbehaves around DST onset/cease"); + fail("Fail: roll/add misbehaves around DST onset/cease"); } } /** * Make sure maximum for HOUR field is 11, not 12. */ + @Test public void Test4118384() { Calendar cal = Calendar.getInstance(); if (cal.getMaximum(HOUR) != 11 || cal.getLeastMaximum(HOUR) != 11 || cal.getActualMaximum(HOUR) != 11) { - errln("Fail: maximum of HOUR field should be 11"); + fail("Fail: maximum of HOUR field should be 11"); } } /** * Check isLeapYear for BC years. */ + @Test public void Test4125881() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -910,10 +928,10 @@ public void Test4125881() { for (int y = -20; y <= 10; ++y) { cal.set(ERA, y < 1 ? GregorianCalendar.BC : GregorianCalendar.AD); cal.set(YEAR, y < 1 ? 1 - y : y); - logln(y + " = " + fmt.format(cal.getTime()) + " " + System.out.println(y + " = " + fmt.format(cal.getTime()) + " " + cal.isLeapYear(y)); if (cal.isLeapYear(y) != ((y + 40) % 4 == 0)) { - errln("Leap years broken"); + fail("Leap years broken"); } } } @@ -922,10 +940,11 @@ public void Test4125881() { * Prove that GregorianCalendar is proleptic (it used to cut off * at 45 BC, and not have leap years before then). */ + @Test public void Test4125892() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -939,7 +958,7 @@ public void Test4125892() { cal.add(DATE, 1); if (cal.get(DATE) != 29 || !cal.isLeapYear(-80)) { // -80 == 81 BC - errln("Calendar not proleptic"); + fail("Calendar not proleptic"); } } @@ -948,6 +967,7 @@ public void Test4125892() { * Calendar needs a good implementation that subclasses can override, * and GregorianCalendar should use that implementation. */ + @Test public void Test4136399() { /* Note: This test is actually more strict than it has to be. * Technically, there is no requirement that unequal objects have @@ -961,24 +981,24 @@ public void Test4136399() { Calendar a = Calendar.getInstance(); Calendar b = (Calendar) a.clone(); if (a.hashCode() != b.hashCode()) { - errln("Calendar hash code unequal for cloned objects"); + fail("Calendar hash code unequal for cloned objects"); } b.setMinimalDaysInFirstWeek(7 - a.getMinimalDaysInFirstWeek()); if (a.hashCode() == b.hashCode()) { - errln("Calendar hash code ignores minimal days in first week"); + fail("Calendar hash code ignores minimal days in first week"); } b.setMinimalDaysInFirstWeek(a.getMinimalDaysInFirstWeek()); b.setFirstDayOfWeek((a.getFirstDayOfWeek() % 7) + 1); // Next day if (a.hashCode() == b.hashCode()) { - errln("Calendar hash code ignores first day of week"); + fail("Calendar hash code ignores first day of week"); } b.setFirstDayOfWeek(a.getFirstDayOfWeek()); b.setLenient(!a.isLenient()); if (a.hashCode() == b.hashCode()) { - errln("Calendar hash code ignores lenient setting"); + fail("Calendar hash code ignores lenient setting"); } b.setLenient(a.isLenient()); @@ -986,36 +1006,37 @@ public void Test4136399() { // of a reference -- this is true as of this writing b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset() + 60 * 60 * 1000); if (a.hashCode() == b.hashCode()) { - errln("Calendar hash code ignores zone"); + fail("Calendar hash code ignores zone"); } b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset()); GregorianCalendar c = new GregorianCalendar(); GregorianCalendar d = (GregorianCalendar) c.clone(); if (c.hashCode() != d.hashCode()) { - errln("GregorianCalendar hash code unequal for clones objects"); + fail("GregorianCalendar hash code unequal for clones objects"); } Date cutover = c.getGregorianChange(); d.setGregorianChange(new Date(cutover.getTime() + 24 * 60 * 60 * 1000)); if (c.hashCode() == d.hashCode()) { - errln("GregorianCalendar hash code ignores cutover"); + fail("GregorianCalendar hash code ignores cutover"); } } /** * GregorianCalendar.equals() ignores cutover date */ + @Test public void Test4141665() { GregorianCalendar cal = new GregorianCalendar(); GregorianCalendar cal2 = (GregorianCalendar) cal.clone(); Date cut = cal.getGregorianChange(); Date cut2 = new Date(cut.getTime() + 100 * 24 * 60 * 60 * 1000L); // 100 days later if (!cal.equals(cal2)) { - errln("Cloned GregorianCalendars not equal"); + fail("Cloned GregorianCalendars not equal"); } cal2.setGregorianChange(cut2); if (cal.equals(cal2)) { - errln("GregorianCalendar.equals() ignores cutover"); + fail("GregorianCalendar.equals() ignores cutover"); } } @@ -1023,16 +1044,17 @@ public void Test4141665() { * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar.roll() * when IllegalArgumentException should be. */ + @Test public void Test4142933() { GregorianCalendar calendar = new GregorianCalendar(); try { calendar.roll(-1, true); - errln("Test failed, no exception trown"); + fail("Test failed, no exception trown"); } catch (IllegalArgumentException e) { // OK: Do nothing // logln("Test passed"); } catch (Exception e) { - errln("Test failed. Unexpected exception is thrown: " + e); + fail("Test failed. Unexpected exception is thrown: " + e); e.printStackTrace(); } } @@ -1044,6 +1066,7 @@ public void Test4142933() { * report to therefore only check the behavior of a calendar with a zero raw * offset zone. */ + @Test public void Test4145158() { GregorianCalendar calendar = new GregorianCalendar(); @@ -1058,13 +1081,14 @@ public void Test4145158() { int era2 = calendar.get(ERA); if (year1 == year2 && era1 == era2) { - errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around"); + fail("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around"); } } /** * Maximum value for YEAR field wrong. */ + @Test public void Test4145983() { GregorianCalendar calendar = new GregorianCalendar(); calendar.setTimeZone(TimeZone.getTimeZone("GMT")); @@ -1074,7 +1098,7 @@ public void Test4145983() { int year = calendar.get(YEAR); int maxYear = calendar.getMaximum(YEAR); if (year > maxYear) { - errln("Failed for " + DATES[i].getTime() + " ms: year=" + fail("Failed for " + DATES[i].getTime() + " ms: year=" + year + ", maxYear=" + maxYear); } } @@ -1086,6 +1110,7 @@ public void Test4145983() { * report test was written. In reality the bug is restricted to the DAY_OF_YEAR * field. - liu 6/29/98 */ + @Test public void Test4147269() { final String[] fieldName = { "ERA", @@ -1121,7 +1146,7 @@ public void Test4147269() { calendar.getTime(); // Force time computation // We expect an exception to be thrown. If we fall through // to the next line, then we have a bug. - errln("Test failed with field " + fieldName[field] + fail("Test failed with field " + fieldName[field] + ", date before: " + date + ", date after: " + calendar.getTime() + ", value: " + value + " (max = " + max + ")"); @@ -1135,6 +1160,7 @@ public void Test4147269() { * doesn't behave as a pure Julian calendar. * CANNOT REPRODUCE THIS BUG */ + @Test public void Test4149677() { TimeZone[] zones = {TimeZone.getTimeZone("GMT"), TimeZone.getTimeZone("PST"), @@ -1145,11 +1171,11 @@ public void Test4149677() { // Make sure extreme values don't wrap around calendar.setTime(new Date(Long.MIN_VALUE)); if (calendar.get(ERA) != GregorianCalendar.BC) { - errln("Fail: Date(Long.MIN_VALUE) has an AD year in " + zones[i]); + fail("Fail: Date(Long.MIN_VALUE) has an AD year in " + zones[i]); } calendar.setTime(new Date(Long.MAX_VALUE)); if (calendar.get(ERA) != GregorianCalendar.AD) { - errln("Fail: Date(Long.MAX_VALUE) has a BC year in " + zones[i]); + fail("Fail: Date(Long.MAX_VALUE) has a BC year in " + zones[i]); } calendar.setGregorianChange(new Date(Long.MAX_VALUE)); @@ -1157,9 +1183,9 @@ public void Test4149677() { boolean is100Leap = calendar.isLeapYear(100); if (!is100Leap) { - errln("test failed with zone " + zones[i].getID()); - errln(" cutover date is Date(Long.MAX_VALUE)"); - errln(" isLeapYear(100) returns: " + is100Leap); + fail("test failed with zone " + zones[i].getID() + + "\n cutover date is Date(Long.MAX_VALUE)" + + "\n isLeapYear(100) returns: " + is100Leap); } } } @@ -1168,6 +1194,7 @@ public void Test4149677() { * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar * and Date classes will misbehave. */ + @Test public void Test4162587() { TimeZone savedTz = TimeZone.getDefault(); TimeZone tz = TimeZone.getTimeZone("PST"); @@ -1178,29 +1205,29 @@ public void Test4162587() { try { for (int i = 0; i < 5; ++i) { if (i > 0) { - logln("---"); + System.out.println("---"); } cal.clear(); cal.set(1998, APRIL, 5, i, 0); d = cal.getTime(); String s0 = d.toString(); - logln("0 " + i + ": " + s0); + System.out.println("0 " + i + ": " + s0); cal.clear(); cal.set(1998, APRIL, 4, i + 24, 0); d = cal.getTime(); String sPlus = d.toString(); - logln("+ " + i + ": " + sPlus); + System.out.println("+ " + i + ": " + sPlus); cal.clear(); cal.set(1998, APRIL, 6, i - 24, 0); d = cal.getTime(); String sMinus = d.toString(); - logln("- " + i + ": " + sMinus); + System.out.println("- " + i + ": " + sMinus); if (!s0.equals(sPlus) || !s0.equals(sMinus)) { - errln("Fail: All three lines must match"); + fail("Fail: All three lines must match"); } } } finally { @@ -1211,27 +1238,29 @@ public void Test4162587() { /** * Adding 12 months behaves differently from adding 1 year */ + @Test public void Test4165343() { GregorianCalendar calendar = new GregorianCalendar(1996, FEBRUARY, 29); Date start = calendar.getTime(); - logln("init date: " + start); + System.out.println("init date: " + start); calendar.add(MONTH, 12); Date date1 = calendar.getTime(); - logln("after adding 12 months: " + date1); + System.out.println("after adding 12 months: " + date1); calendar.setTime(start); calendar.add(YEAR, 1); Date date2 = calendar.getTime(); - logln("after adding one year : " + date2); + System.out.println("after adding one year : " + date2); if (date1.equals(date2)) { - logln("Test passed"); + System.out.println("Test passed"); } else { - errln("Test failed"); + fail("Test failed"); } } /** * GregorianCalendar.getActualMaximum() does not account for first day of week. */ + @Test public void Test4166109() { /* Test month: * @@ -1249,7 +1278,7 @@ public void Test4166109() { GregorianCalendar calendar = new GregorianCalendar(Locale.US); calendar.set(1998, MARCH, 1); calendar.setMinimalDaysInFirstWeek(1); - logln("Date: " + calendar.getTime()); + System.out.println("Date: " + calendar.getTime()); int firstInMonth = calendar.get(DAY_OF_MONTH); @@ -1258,7 +1287,7 @@ public void Test4166109() { int returned = calendar.getActualMaximum(field); int expected = (31 + ((firstInMonth - firstInWeek + 7) % 7) + 6) / 7; - logln("First day of week = " + firstInWeek + System.out.println("First day of week = " + firstInWeek + " getActualMaximum(WEEK_OF_MONTH) = " + returned + " expected = " + expected + ((returned == expected) ? " ok" : " FAIL")); @@ -1268,7 +1297,7 @@ public void Test4166109() { } } if (!passed) { - errln("Test failed"); + fail("Test failed"); } } @@ -1279,6 +1308,7 @@ public void Test4166109() { * setGregorianChange didn't change object's date. But it was * changed. See 4928615. */ + @Test public void Test4167060() { int field = YEAR; DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G", @@ -1293,7 +1323,7 @@ public void Test4167060() { String[] id = {"Hybrid", "Gregorian", "Julian"}; for (int k = 0; k < 3; ++k) { - logln("--- " + id[k] + " ---"); + System.out.println("--- " + id[k] + " ---"); for (int j = 0; j < dates.length; ++j) { GregorianCalendar calendar = new GregorianCalendar(); @@ -1308,8 +1338,8 @@ public void Test4167060() { Date dateBefore = calendar.getTime(); int maxYear = calendar.getActualMaximum(field); - logln("maxYear: " + maxYear + " for " + format.format(calendar.getTime())); - logln("date before: " + format.format(dateBefore)); + System.out.println("maxYear: " + maxYear + " for " + format.format(calendar.getTime())); + System.out.println("date before: " + format.format(dateBefore)); int[] years = {2000, maxYear - 1, maxYear, maxYear + 1}; @@ -1320,12 +1350,12 @@ public void Test4167060() { int newYear = calendar.get(field); calendar.setTime(dateBefore); // restore calendar for next use - logln(" Year " + years[i] + (valid ? " ok " : " bad") + System.out.println(" Year " + years[i] + (valid ? " ok " : " bad") + " => " + format.format(dateAfter)); if (valid && newYear != years[i]) { - errln(" FAIL: " + newYear + " should be valid; date, month and time shouldn't change"); + fail(" FAIL: " + newYear + " should be valid; date, month and time shouldn't change"); } else if (!valid && newYear == years[i]) { - errln(" FAIL: " + newYear + " should be invalid"); + fail(" FAIL: " + newYear + " should be invalid"); } } } @@ -1336,10 +1366,11 @@ public void Test4167060() { * Calendar.roll broken * This bug relies on the TimeZone bug 4173604 to also be fixed. */ + @Test public void Test4173516() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -1365,11 +1396,11 @@ public void Test4173516() { cal.roll(HOUR, 0x7F000000); cal.roll(HOUR, -0x7F000000); if (cal.getTime().getTime() != 0) { - errln("Hour rolling broken. expected 0, got " + cal.getTime().getTime()); + fail("Hour rolling broken. expected 0, got " + cal.getTime().getTime()); } for (int op = 0; op < 2; ++op) { - logln("Testing GregorianCalendar " + (op == 0 ? "add" : "roll")); + System.out.println("Testing GregorianCalendar " + (op == 0 ? "add" : "roll")); for (int field = 0; field < FIELD_COUNT; ++field) { if (field != ZONE_OFFSET @@ -1395,7 +1426,7 @@ public void Test4173516() { || cal.get(MINUTE) != fields[4] || cal.get(SECOND) != fields[5] || cal.get(MILLISECOND) != fields[6]) { - errln("Field " + field + fail("Field " + field + " (" + fieldNames[field] + ") FAIL, expected " + fields[0] @@ -1417,7 +1448,7 @@ public void Test4173516() { cal.set(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5]); cal.set(MILLISECOND, fields[6]); - errln(cal.get(YEAR) + fail(cal.get(YEAR) + "/" + (cal.get(MONTH) + 1) + "/" + cal.get(DATE) + " " + cal.get(HOUR_OF_DAY) @@ -1435,7 +1466,7 @@ public void Test4173516() { long t = cal.getTime().getTime(); long delta = t - prev; prev = t; - errln((op == 0 ? "add(" : "roll(") + fail((op == 0 ? "add(" : "roll(") + fieldNames[field] + ", " + (i < limit ? "+" : "-") + "1) => " + cal.get(YEAR) @@ -1457,6 +1488,7 @@ public void Test4173516() { } } + @Test public void Test4174361() { GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29); @@ -1470,13 +1502,14 @@ public void Test4174361() { int d2 = calendar.get(DAY_OF_MONTH); if (d1 != d2) { - errln("adding months to Feb 29 broken"); + fail("adding months to Feb 29 broken"); } } /** * Calendar does not update field values when setTimeZone is called. */ + @Test public void Test4177484() { TimeZone PST = TimeZone.getTimeZone("PST"); TimeZone EST = TimeZone.getTimeZone("EST"); @@ -1488,7 +1521,7 @@ public void Test4177484() { cal.setTimeZone(EST); int h2 = cal.get(HOUR_OF_DAY); if (h1 == h2) { - errln("FAIL: Fields not updated after setTimeZone"); + fail("FAIL: Fields not updated after setTimeZone"); } // getTime() must NOT change when time zone is changed. @@ -1500,13 +1533,14 @@ public void Test4177484() { cal.setTimeZone(EST); Date est10 = cal.getTime(); if (!pst10.equals(est10)) { - errln("FAIL: setTimeZone changed time"); + fail("FAIL: setTimeZone changed time"); } } /** * Week of year is wrong at the start and end of the year. */ + @Test public void Test4197699() { GregorianCalendar cal = new GregorianCalendar(); cal.setFirstDayOfWeek(MONDAY); @@ -1523,14 +1557,14 @@ public void Test4197699() { int expWOY = DATA[i++]; int actWOY = cal.get(WEEK_OF_YEAR); if (expWOY == actWOY) { - logln("Ok: " + fmt.format(cal.getTime())); + System.out.println("Ok: " + fmt.format(cal.getTime())); } else { - errln("FAIL: " + fmt.format(cal.getTime()) + fail("FAIL: " + fmt.format(cal.getTime()) + ", expected WOY=" + expWOY); cal.add(DATE, -8); for (int j = 0; j < 14; ++j) { cal.add(DATE, 1); - logln(fmt.format(cal.getTime())); + System.out.println(fmt.format(cal.getTime())); } } } @@ -1549,6 +1583,7 @@ public void Test4197699() { * WEEK_OF_YEAR + DAY_OF_WEEK */ @SuppressWarnings("deprecation") + @Test public void Test4209071() { Calendar cal = Calendar.getInstance(Locale.US); @@ -1625,7 +1660,7 @@ public void Test4209071() { Date act = cal.getTime(); if (!act.equals(exp)) { - errln("FAIL: Test " + (i / 2) + " got " + act + fail("FAIL: Test " + (i / 2) + " got " + act + ", want " + exp + " (see test/java/util/Calendar/CalendarRegression.java"); } @@ -1649,13 +1684,14 @@ public void Test4209071() { cal.set(YEAR, 1997); Date actual = cal.getTime(); if (!actual.equals(DATA[i + 1])) { - errln("FAIL: Sunday " + DATA[i] + fail("FAIL: Sunday " + DATA[i] + " of Jan 1997 -> " + actual + ", want " + DATA[i + 1]); } } } + @Test public void Test4288792() throws Exception { TimeZone savedTZ = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("GMT")); @@ -1678,7 +1714,7 @@ public void Test4288792() throws Exception { cal.add(DATE, 1); int WOY = cal.get(WEEK_OF_YEAR); if (WOY != maxWeek) { - errln(cal.getTime() + ",got=" + WOY + fail(cal.getTime() + ",got=" + WOY + ",expected=" + maxWeek + ",min=" + j1 + ",first=" + j); } @@ -1687,7 +1723,7 @@ public void Test4288792() throws Exception { cal.add(DATE, 1); int WOY = cal.get(WEEK_OF_YEAR); if (WOY != 1) { - errln(cal.getTime() + ",got=" + WOY + fail(cal.getTime() + ",got=" + WOY + ",expected=1,min=" + j1 + ",first" + j); } } @@ -1698,6 +1734,7 @@ public void Test4288792() throws Exception { } } + @Test public void Test4328747() throws Exception { Calendar c = Calendar.getInstance(Locale.US); c.clear(); @@ -1718,7 +1755,7 @@ public void Test4328747() throws Exception { // Bug gives 1965 11 19 if ((result.get(YEAR) != 1966) || (result.get(MONTH) != 0) || (result.get(DATE) != 1)) { - errln("deserialized Calendar returned wrong date field(s): " + fail("deserialized Calendar returned wrong date field(s): " + result.get(YEAR) + "/" + result.get(MONTH) + "/" + result.get(DATE) + ", expected 1966/0/1"); } @@ -1728,6 +1765,7 @@ public void Test4328747() throws Exception { * Test whether Calendar can be serialized/deserialized correctly * even if invalid/customized TimeZone is used. */ + @Test public void Test4413980() { TimeZone savedTimeZone = TimeZone.getDefault(); try { @@ -1751,18 +1789,18 @@ public void Test4413980() { if (!c.equals(t.readObject())) { pass = false; - logln("Calendar instance which uses TimeZone <" + System.out.println("Calendar instance which uses TimeZone <" + IDs[i] + "> is incorrectly serialized/deserialized."); } else { - logln("Calendar instance which uses TimeZone <" + System.out.println("Calendar instance which uses TimeZone <" + IDs[i] + "> is correctly serialized/deserialized."); } } if (!pass) { - errln("Fail: Calendar serialization/equality bug"); + fail("Fail: Calendar serialization/equality bug"); } } catch (IOException | ClassNotFoundException e) { - errln("Fail: " + e); + fail("Fail: " + e); e.printStackTrace(); } finally { TimeZone.setDefault(savedTimeZone); @@ -1772,6 +1810,7 @@ public void Test4413980() { /** * 4546637: Incorrect WEEK_OF_MONTH after changing First Day Of Week */ + @Test public void Test4546637() { GregorianCalendar day = new GregorianCalendar(2001, NOVEMBER, 04); day.setMinimalDaysInFirstWeek(1); @@ -1779,13 +1818,14 @@ public void Test4546637() { day.setFirstDayOfWeek(MONDAY); if (day.get(WEEK_OF_MONTH) != 1) { - errln("Fail: 2001/11/4 must be the first week of the month."); + fail("Fail: 2001/11/4 must be the first week of the month."); } } /** * 4623997: GregorianCalendar returns bad WEEK_OF_YEAR */ + @Test public void Test4623997() { GregorianCalendar cal = new GregorianCalendar(2000, JANUARY, 1); @@ -1795,7 +1835,7 @@ public void Test4623997() { cal.setMinimalDaysInFirstWeek(4); if (cal.get(WEEK_OF_YEAR) != 52) { - errln("Fail: 2000/1/1 must be the 52nd week of the year."); + fail("Fail: 2000/1/1 must be the 52nd week of the year."); } } @@ -1805,11 +1845,12 @@ public void Test4623997() { *

    Need to use SimpleDateFormat to test because a call to * get(int) changes internal states of a Calendar. */ + @Test public void Test4685354() { Locale locale = Locale.getDefault(); if (!TestUtils.usesAsciiDigits(locale) || !TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -1831,7 +1872,7 @@ public void Test4685354() { calendar.set(DAY_OF_MONTH, 0); s = df.format(calendar.getTime()); if (!expected.equals(s)) { - errln("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s); + fail("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s); } // The same thing must work with ZONE_OFFSET set @@ -1847,7 +1888,7 @@ public void Test4685354() { calendar.set(DAY_OF_MONTH, 0); s = df.format(calendar.getTime()); if (!expected.equals(s)) { - errln("DAY_OF_MONTH: expected: " + expected + ", got: " + s); + fail("DAY_OF_MONTH: expected: " + expected + ", got: " + s); } expected = "1999/12/24"; // 0th week of 2000 @@ -1867,7 +1908,7 @@ public void Test4685354() { calendar.set(WEEK_OF_YEAR, 0); s = df.format(calendar.getTime()); if (!expected.equals(s)) { - errln("WEEK_OF_YEAR: expected: " + expected + ", got: " + s); + fail("WEEK_OF_YEAR: expected: " + expected + ", got: " + s); } // change the state back calendar.clear(); @@ -1879,7 +1920,7 @@ public void Test4685354() { calendar.set(WEEK_OF_MONTH, 0); s = df.format(calendar.getTime()); if (!expected.equals(s)) { - errln("WEEK_OF_MONTH: expected: " + expected + ", got: " + s); + fail("WEEK_OF_MONTH: expected: " + expected + ", got: " + s); } // Make sure the time fields work correctly. @@ -1903,7 +1944,7 @@ public void Test4685354() { // time should be back to 22:59:59. s = df.format(calendar.getTime()); if (!expected.equals(s)) { - errln("MINUTE: expected: " + expected + ", got: " + s); + fail("MINUTE: expected: " + expected + ", got: " + s); } } @@ -1913,10 +1954,11 @@ public void Test4685354() { *

    Need to use SimpleDateFormat to test because a call to * get(int) changes internal states of a Calendar. */ + @Test public void Test4655637() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -1935,7 +1977,7 @@ public void Test4655637() { String expected = "2001/01/08"; String s = df.format(cal.getTime()); if (!expected.equals(s)) { - errln("expected: " + expected + ", got: " + s); + fail("expected: " + expected + ", got: " + s); } } @@ -1947,6 +1989,7 @@ public void Test4655637() { * *

    This test case throws ArrayIndexOutOfBoundsException without the fix. */ + @Test public void Test4683492() { Calendar cal = new GregorianCalendar(2002, 3, 29, 10, 0, 0); cal.set(DAY_OF_WEEK, FRIDAY); @@ -1956,13 +1999,14 @@ public void Test4683492() { String expected = "2003/01/31"; String s = df.format(cal.getTime()); if (!expected.equals(s)) { - errln("expected: " + expected + ", got: " + s); + fail("expected: " + expected + ", got: " + s); } } /** * 4080631: Calendar.hashCode is amazingly bad */ + @Test public void Test4080631() { Calendar cal = Calendar.getInstance(); int h1 = cal.hashCode(); @@ -1971,16 +2015,16 @@ public void Test4080631() { Calendar cal2 = (Calendar) cal.clone(); cal.add(MILLISECOND, +1); int h3 = cal.hashCode(); - logln("hash code: h1=" + h1 + ", h2=" + h2 + ", h3=" + h3); + System.out.println("hash code: h1=" + h1 + ", h2=" + h2 + ", h3=" + h3); if (h1 == h2 || h1 == h3 || h2 == h3) { - errln("hash code is poor: hashCode=" + h1); + fail("hash code is poor: hashCode=" + h1); } h2 = cal2.hashCode(); cal.add(MILLISECOND, -1); int h4 = cal.hashCode(); - logln("hash code: h2=" + h2 + ", h4=" + h4); + System.out.println("hash code: h2=" + h2 + ", h4=" + h4); if (cal.equals(cal2) && h2 != h4) { - errln("broken hash code: h2=" + h2 + ", h4=" + h4); + fail("broken hash code: h2=" + h2 + ", h4=" + h4); } int x = cal.getFirstDayOfWeek() + 3; if (x > SATURDAY) { @@ -1988,9 +2032,9 @@ public void Test4080631() { } cal.setFirstDayOfWeek(x); int h5 = cal.hashCode(); - logln("hash code: h4=" + h4 + ", h5=" + h5); + System.out.println("hash code: h4=" + h4 + ", h5=" + h5); if (h4 == h5) { - errln("has code is poor with first day of week param: hashCode=" + h4); + fail("has code is poor with first day of week param: hashCode=" + h4); } } @@ -1998,6 +2042,7 @@ public void Test4080631() { * 4125161: RFE: GregorianCalendar needs more era names (BCE and CE) */ /* + @Test public void Test4125161() throws Exception { Class gc = GregorianCalendar.class; Field f; @@ -2005,86 +2050,89 @@ public void Test4125161() throws Exception { f = gc.getDeclaredField("BCE"); mod = f.getModifiers(); if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) { - errln("BCE: wrong modifiers: " + mod); + fail("BCE: wrong modifiers: " + mod); } f = gc.getDeclaredField("CE"); mod = f.getModifiers(); if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) { - errln("CE: wrong modifiers: " + mod); + fail("CE: wrong modifiers: " + mod); } if (GregorianCalendar.BCE != GregorianCalendar.BC || GregorianCalendar.CE != GregorianCalendar.AD) { - errln("Wrong BCE and/or CE values"); + fail("Wrong BCE and/or CE values"); } } */ /** * 4167995: GregorianCalendar.setGregorianChange() not to spec */ + @Test public void Test4167995() { Koyomi gc = new Koyomi(TimeZone.getTimeZone("GMT")); - logln("Hybrid: min date"); + System.out.println("Hybrid: min date"); gc.setTime(new Date(Long.MIN_VALUE)); if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } - logln("Hybrid: max date"); + System.out.println("Hybrid: max date"); gc.setTime(new Date(Long.MAX_VALUE)); if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } gc.setGregorianChange(new Date(Long.MIN_VALUE)); - logln("Gregorian: min date"); + System.out.println("Gregorian: min date"); gc.setTime(new Date(Long.MIN_VALUE)); if (!gc.checkDate(292275056, MAY, 16, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } - logln("Gregorian: max date"); + System.out.println("Gregorian: max date"); gc.setTime(new Date(Long.MAX_VALUE)); if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } gc.setGregorianChange(new Date(Long.MAX_VALUE)); - logln("Julian: min date"); + System.out.println("Julian: min date"); gc.setTime(new Date(Long.MIN_VALUE)); if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } - logln("Julian: max date"); + System.out.println("Julian: max date"); gc.setTime(new Date(Long.MAX_VALUE)); if (!gc.checkDate(292272993, JANUARY, 4, SUNDAY) || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { - errln(gc.getMessage()); + fail(gc.getMessage()); } } /** * 4340146: Calendar.equals modifies state */ + @Test public void Test4340146() { Koyomi cal = new Koyomi(); cal.clear(); cal.set(2003, OCTOBER, 32); cal.equals(new Koyomi()); if (!cal.checkInternalDate(2003, OCTOBER, 32)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } new Koyomi().equals(cal); if (!cal.checkInternalDate(2003, OCTOBER, 32)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } /** * 4639407: GregorianCalendar doesn't work in non-lenient due to timezone bounds checking */ + @Test public void Test4639407() { // The following operations in non-lenient mode shouldn't // throw IllegalArgumentException. @@ -2100,6 +2148,7 @@ public void Test4639407() { /** * 4652815: rolling week-of-year back hundreds of weeks changes year */ + @Test public void Test4652815() { Koyomi cal = new Koyomi(Locale.US); testRoll(cal, 2003, SEPTEMBER, 29); @@ -2112,18 +2161,18 @@ private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) { cal.clear(); cal.set(year, month, dayOfMonth); cal.getTime(); // normalize fields - logln("Roll backwards from " + cal.toDateString()); + System.out.println("Roll backwards from " + cal.toDateString()); for (int i = 0; i < 1000; i++) { cal.roll(WEEK_OF_YEAR, -i); if (!cal.checkFieldValue(YEAR, year)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } - logln("Roll forewards from " + cal.toDateString()); + System.out.println("Roll forewards from " + cal.toDateString()); for (int i = 0; i < 1000; i++) { cal.roll(WEEK_OF_YEAR, +i); if (!cal.checkFieldValue(YEAR, year)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } } @@ -2131,47 +2180,50 @@ private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) { /** * 4652830: GregorianCalendar roll behaves unexpectedly for dates in BC era */ + @Test public void Test4652830() { Koyomi cal = new Koyomi(Locale.US); cal.clear(); - logln("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice"); + System.out.println("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice"); cal.set(ERA, GregorianCalendar.BC); cal.set(9, FEBRUARY, 28); if (cal.getActualMaximum(DAY_OF_YEAR) != 366) { - errln(" wrong actual max of DAY_OF_YEAR: got " + fail(" wrong actual max of DAY_OF_YEAR: got " + cal.getActualMaximum(DAY_OF_YEAR) + " expected " + 366); } cal.roll(DAY_OF_MONTH, +1); if (!cal.checkFieldValue(ERA, GregorianCalendar.BC) || !cal.checkDate(9, FEBRUARY, 29)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } cal.roll(DAY_OF_MONTH, +1); if (!cal.checkFieldValue(ERA, GregorianCalendar.BC) || !cal.checkDate(9, FEBRUARY, 1)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } /** * 4740554: GregorianCalendar.getActualMaximum is inconsistent with normalization */ + @Test public void Test4740554() { - logln("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum"); + System.out.println("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum"); Koyomi cal = new Koyomi(Locale.US); cal.clear(); cal.set(1999, FEBRUARY + 12, 1); if (!cal.checkActualMaximum(DAY_OF_YEAR, 366)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkActualMaximum(DAY_OF_MONTH, 29)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } /** * 4936355: GregorianCalendar causes overflow/underflow with time of day calculation */ + @Test public void Test4936355() { Koyomi cal = new Koyomi(TimeZone.getTimeZone("GMT")); cal.clear(); @@ -2213,7 +2265,7 @@ private void checkTimeCalculation(Koyomi cal, int field, int value, long expecte long time2 = cal.getTimeInMillis(); if ((time + expectedDelta) != time2) { String s = value == Integer.MAX_VALUE ? "Integer.MAX_VALUE" : "Integer.MIN_VALUE"; - errln("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time2 + fail("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time2 + ", expected " + (time + expectedDelta)); } } @@ -2222,6 +2274,7 @@ private void checkTimeCalculation(Koyomi cal, int field, int value, long expecte * 4722650: Calendar.equals can throw an exception in non-lenient * (piggy-back tests for compareTo() which is new in 1.5) */ + @Test public void Test4722650() { Calendar cal1 = new GregorianCalendar(); cal1.clear(); @@ -2233,26 +2286,26 @@ public void Test4722650() { cal2.set(2003, OCTOBER, 31); try { if (cal1.equals(cal2)) { - errln("lenient and non-lenient shouldn't be equal. (2003/10/31)"); + fail("lenient and non-lenient shouldn't be equal. (2003/10/31)"); } if (cal1.compareTo(cal2) != 0) { - errln("cal1 and cal2 should represent the same time. (2003/10/31)"); + fail("cal1 and cal2 should represent the same time. (2003/10/31)"); } } catch (IllegalArgumentException e) { - errln("equals threw IllegalArugumentException with non-lenient"); + fail("equals threw IllegalArugumentException with non-lenient"); } cal1.set(2003, OCTOBER, 32); cal2.set(2003, OCTOBER, 32); try { if (cal1.equals(cal2)) { - errln("lenient and non-lenient shouldn't be equal. (2003/10/32)"); + fail("lenient and non-lenient shouldn't be equal. (2003/10/32)"); } if (cal1.compareTo(cal2) != 0) { - errln("cal1 and cal2 should represent the same time. (2003/10/32)"); + fail("cal1 and cal2 should represent the same time. (2003/10/32)"); } } catch (IllegalArgumentException e) { - errln("equals threw IllegalArugumentException with non-lenient"); + fail("equals threw IllegalArugumentException with non-lenient"); } cal1 = Calendar.getInstance(Locale.of("th", "TH")); @@ -2260,48 +2313,49 @@ public void Test4722650() { cal2 = Calendar.getInstance(Locale.US); cal2.setTimeInMillis(0L); if (cal1.equals(cal2)) { - errln("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)"); + fail("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)"); } if (cal1.compareTo(cal2) != 0) { - errln("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)"); + fail("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)"); } } /** * 4738710: API: Calendar comparison methods should be improved */ + @Test public void Test4738710() { Calendar cal0 = new GregorianCalendar(2003, SEPTEMBER, 30); Comparable cal1 = new GregorianCalendar(2003, OCTOBER, 1); Calendar cal2 = new GregorianCalendar(2003, OCTOBER, 2); if (!(cal1.compareTo(cal0) > 0)) { - errln("!(cal1 > cal0)"); + fail("!(cal1 > cal0)"); } if (!(cal1.compareTo(cal2) < 0)) { - errln("!(cal1 < cal2)"); + fail("!(cal1 < cal2)"); } if (cal1.compareTo(new GregorianCalendar(2003, OCTOBER, 1)) != 0) { - errln("cal1 != new GregorianCalendar(2003, OCTOBER, 1)"); + fail("cal1 != new GregorianCalendar(2003, OCTOBER, 1)"); } if (cal0.after(cal2)) { - errln("cal0 shouldn't be after cal2"); + fail("cal0 shouldn't be after cal2"); } if (cal2.before(cal0)) { - errln("cal2 shouldn't be before cal0"); + fail("cal2 shouldn't be before cal0"); } if (cal0.after(0)) { - errln("cal0.after() returned true with an Integer."); + fail("cal0.after() returned true with an Integer."); } if (cal0.before(0)) { - errln("cal0.before() returned true with an Integer."); + fail("cal0.before() returned true with an Integer."); } if (cal0.after(null)) { - errln("cal0.after() returned true with null."); + fail("cal0.after() returned true with null."); } if (cal0.before(null)) { - errln("cal0.before() returned true with null."); + fail("cal0.before() returned true with null."); } } @@ -2309,6 +2363,7 @@ public void Test4738710() { * 4633646: Setting WEEK_OF_MONTH to 1 results in incorrect date */ @SuppressWarnings("deprecation") + @Test public void Test4633646() { Koyomi cal = new Koyomi(Locale.US); cal.setTime(new Date(2002 - 1900, 1 - 1, 28)); @@ -2334,15 +2389,15 @@ void sub4633646(Koyomi cal) { cal.set(WEEK_OF_MONTH, 1); if (cal.isLenient()) { if (!cal.checkDate(2001, DECEMBER, 31)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(WEEK_OF_MONTH, 6)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } else { try { Date d = cal.getTime(); - errln("didn't throw IllegalArgumentException in non-lenient"); + fail("didn't throw IllegalArgumentException in non-lenient"); } catch (IllegalArgumentException e) { } } @@ -2352,6 +2407,7 @@ void sub4633646(Koyomi cal) { * 4846659: Calendar: Both set() and roll() don't work for AM_PM time field * (Partially fixed only roll as of 1.5) */ + @Test public void Test4846659() { Koyomi cal = new Koyomi(); cal.clear(); @@ -2360,7 +2416,7 @@ public void Test4846659() { // Test roll() cal.roll(AM_PM, +1); // should turn to PM if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) { - errln("roll: AM_PM didn't change to PM"); + fail("roll: AM_PM didn't change to PM"); } cal.clear(); @@ -2369,7 +2425,7 @@ public void Test4846659() { // Test set() cal.set(AM_PM, PM); // should turn to PM if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) { - errln("set: AM_PM didn't change to PM"); + fail("set: AM_PM didn't change to PM"); } cal.clear(); @@ -2378,13 +2434,14 @@ public void Test4846659() { cal.set(AM_PM, PM); cal.set(HOUR, 9); if (!cal.checkFieldValue(HOUR_OF_DAY, 9 + 12)) { - errln("set: both AM_PM and HOUT didn't change to PM"); + fail("set: both AM_PM and HOUT didn't change to PM"); } } /** * 4822110: GregorianCalendar.get() returns an incorrect date after setFirstDayOfWeek() */ + @Test public void Test4822110() { Koyomi cal = new Koyomi(Locale.US); // June 2003 @@ -2401,17 +2458,18 @@ public void Test4822110() { cal.setFirstDayOfWeek(MONDAY); // Now 6/2 to 6/8 should be the 2nd week of June. Sunday of // that week is 6/8. - logln("1: " + cal.get(WEEK_OF_MONTH) + ", " + cal.get(DAY_OF_MONTH)); + System.out.println("1: " + cal.get(WEEK_OF_MONTH) + ", " + cal.get(DAY_OF_MONTH)); cal.set(DAY_OF_WEEK, SUNDAY); - logln("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY"); + System.out.println("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY"); if (!cal.checkDate(2003, JUNE, 8)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } /** * 4973919: Inconsistent GregorianCalendar hashCode before and after serialization */ + @Test public void Test4966499() throws Exception { GregorianCalendar date1 = new GregorianCalendar(2004, JANUARY, 7); @@ -2428,10 +2486,10 @@ public void Test4966499() throws Exception { GregorianCalendar date2 = (GregorianCalendar) ois.readObject(); if (!date1.equals(date2)) { - errln("date1.equals(date2) != true"); + fail("date1.equals(date2) != true"); } if (date1.hashCode() != date2.hashCode()) { - errln("inconsistent hashCode() value (before=0x" + fail("inconsistent hashCode() value (before=0x" + Integer.toHexString(date1.hashCode()) + ", after=0x" + Integer.toHexString(date2.hashCode()) + ")"); } @@ -2440,54 +2498,56 @@ public void Test4966499() throws Exception { /** * 4980088: GregorianCalendar.getActualMaximum doesn't throw exception */ + @Test public void Test4980088() { GregorianCalendar cal = new GregorianCalendar(); try { int x = cal.getMaximum(100); - errln("getMaximum(100) didn't throw an exception."); + fail("getMaximum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getMaximum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getMaximum: " + e.getClass().getName() + ": " + e.getMessage()); } try { int x = cal.getLeastMaximum(100); - errln("getLeastMaximum(100) didn't throw an exception."); + fail("getLeastMaximum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage()); } try { int x = cal.getActualMaximum(100); - errln("getActualMaximum(100) didn't throw an exception."); + fail("getActualMaximum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage()); } try { int x = cal.getMinimum(100); - errln("getMinimum(100) didn't throw an exception."); + fail("getMinimum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getMinimum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getMinimum: " + e.getClass().getName() + ": " + e.getMessage()); } try { int x = cal.getGreatestMinimum(100); - errln("getGreatestMinimum(100) didn't throw an exception."); + fail("getGreatestMinimum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage()); } try { int x = cal.getActualMinimum(100); - errln("getActualMinimum(100) didn't throw an exception."); + fail("getActualMinimum(100) didn't throw an exception."); } catch (IndexOutOfBoundsException e) { - logln("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage()); + System.out.println("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage()); } } /** * 4965624: GregorianCalendar.isLeapYear(1000) returns incorrect value */ + @Test public void Test4965624() { // 5013094: This test case needs to use "GMT" to specify // Gregorian cutover dates. @@ -2509,7 +2569,7 @@ public void Test4965624() { GregorianCalendar cal = new GregorianCalendar(); cal.setGregorianChange(d); if (cal.isLeapYear(1000) != expected) { - errln("isLeapYear(1000) returned " + cal.isLeapYear(1000) + fail("isLeapYear(1000) returned " + cal.isLeapYear(1000) + " with cutover date (Julian) " + d); } }); @@ -2532,16 +2592,17 @@ static Date getGregorianDate(int year, int month, int dayOfMonth) { /** * 5006864: Define the minimum value of DAY_OF_WEEK_IN_MONTH as 1 */ + @Test public void Test5006864() { GregorianCalendar cal = new GregorianCalendar(); int min = cal.getMinimum(DAY_OF_WEEK_IN_MONTH); if (min != 1) { - errln("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned " + fail("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned " + min + ", expected 1."); } min = cal.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH); if (min != 1) { - errln("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned " + fail("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned " + min + ", expected 1."); } } diff --git a/test/jdk/java/util/Calendar/CalendarTest.java b/test/jdk/java/util/Calendar/CalendarTest.java index 7d4b0d71000..5092c6adec0 100644 --- a/test/jdk/java/util/Calendar/CalendarTest.java +++ b/test/jdk/java/util/Calendar/CalendarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -27,7 +27,7 @@ * @summary test for Calendar * @library /java/text/testlib * @modules java.base/java.util:+open - * @run main CalendarTest + * @run junit CalendarTest * @key randomness */ @@ -48,18 +48,19 @@ import static java.util.Calendar.*; -public class CalendarTest extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class CalendarTest { static final int ONE_DAY = 24 * 60 * 60 * 1000; static final int EPOCH_JULIAN = 2440588; - public static void main(String argv[]) throws Exception { - new CalendarTest().run(argv); - } - /** * Test the behavior of the GregorianCalendar around the changeover. */ + @Test public void TestGregorianChangeover() { TimeZone savedZone = TimeZone.getDefault(); /* @@ -97,10 +98,10 @@ public void TestGregorianChangeover() { int dom = cal.get(DATE); int dow = cal.get(DAY_OF_WEEK); - logln("Changeover " + (i >= 0 ? "+" : "") + i + System.out.println("Changeover " + (i >= 0 ? "+" : "") + i + " days: " + y + "/" + mon + "/" + dom + " dow=" + dow); if (y != 1582 || mon != MON[j] || dom != DOM[j] || dow != DOW[j]) { - errln(" Fail: Above line is wrong"); + fail(" Fail: Above line is wrong"); } } } finally { @@ -114,6 +115,7 @@ public void TestGregorianChangeover() { * (first day of week, minimal days in first week). */ @SuppressWarnings("deprecation") + @Test public void TestMapping() { TimeZone saveZone = TimeZone.getDefault(); int[] DATA = { @@ -160,9 +162,9 @@ public void TestMapping() { + year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2; if (delta != 0 || year != year2 || month != month2 || dom != dom2) { - errln(s + " FAIL"); + fail(s + " FAIL"); } else { - logln(s); + System.out.println(s); } // Test Julian computation @@ -184,9 +186,9 @@ public void TestMapping() { + year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2; if (delta != 0 || year != year2 || month != month2 || dom != dom2) { - errln(s + " FAIL"); + fail(s + " FAIL"); } else { - logln(s); + System.out.println(s); } } @@ -212,16 +214,17 @@ private void auxMapping(Calendar cal, int y, int m, int d) { int month2 = cal.get(MONTH); int dom2 = cal.get(DAY_OF_MONTH); if (y != year2 || m != month2 || dom2 != d) { - errln("Round-trip failure: " + y + "-" + (m + 1) + "-" + d + " =>ms=> " + fail("Round-trip failure: " + y + "-" + (m + 1) + "-" + d + " =>ms=> " + year2 + "-" + (month2 + 1) + "-" + dom2); } } @SuppressWarnings("deprecation") + @Test public void TestGenericAPI() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -235,7 +238,7 @@ public void TestGenericAPI() { Calendar cal = Calendar.getInstance((SimpleTimeZone) zone.clone()); if (!zone.equals(cal.getTimeZone())) { - errln("FAIL: Calendar.getTimeZone failed"); + fail("FAIL: Calendar.getTimeZone failed"); } Calendar cal2 = Calendar.getInstance(cal.getTimeZone()); @@ -244,27 +247,27 @@ public void TestGenericAPI() { cal2.setTime(when); if (!(cal.equals(cal2))) { - errln("FAIL: Calendar.operator== failed"); + fail("FAIL: Calendar.operator== failed"); } // if ((*cal != *cal2)) errln("FAIL: Calendar.operator!= failed"); if (!cal.equals(cal2) || cal.before(cal2) || cal.after(cal2)) { - errln("FAIL: equals/before/after failed"); + fail("FAIL: equals/before/after failed"); } cal2.setTime(new Date(when.getTime() + 1000)); if (cal.equals(cal2) || cal2.before(cal) || cal.after(cal2)) { - errln("FAIL: equals/before/after failed"); + fail("FAIL: equals/before/after failed"); } cal.roll(SECOND, true); if (!cal.equals(cal2) || cal.before(cal2) || cal.after(cal2)) { - errln("FAIL: equals/before/after failed"); + fail("FAIL: equals/before/after failed"); } // Roll back to January @@ -272,20 +275,20 @@ public void TestGenericAPI() { if (cal.equals(cal2) || cal2.before(cal) || cal.after(cal2)) { - errln("FAIL: equals/before/after failed"); + fail("FAIL: equals/before/after failed"); } // C++ only /* TimeZone z = cal.orphanTimeZone(); if (z.getID(str) != tzid || z.getRawOffset() != tzoffset) - errln("FAIL: orphanTimeZone failed"); + fail("FAIL: orphanTimeZone failed"); */ for (int i = 0; i < 2; ++i) { boolean lenient = (i > 0); cal.setLenient(lenient); if (lenient != cal.isLenient()) { - errln("FAIL: setLenient/isLenient failed"); + fail("FAIL: setLenient/isLenient failed"); } // Later: Check for lenient behavior } @@ -294,26 +297,26 @@ public void TestGenericAPI() { for (i = SUNDAY; i <= SATURDAY; ++i) { cal.setFirstDayOfWeek(i); if (cal.getFirstDayOfWeek() != i) { - errln("FAIL: set/getFirstDayOfWeek failed"); + fail("FAIL: set/getFirstDayOfWeek failed"); } } for (i = 0; i <= 7; ++i) { cal.setMinimalDaysInFirstWeek(i); if (cal.getMinimalDaysInFirstWeek() != i) { - errln("FAIL: set/getFirstDayOfWeek failed"); + fail("FAIL: set/getFirstDayOfWeek failed"); } } for (i = 0; i < FIELD_COUNT; ++i) { if (cal.getMinimum(i) != cal.getGreatestMinimum(i)) { - errln("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i); + fail("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i); } if (cal.getLeastMaximum(i) > cal.getMaximum(i)) { - errln("FAIL: getLeastMaximum larger than getMaximum for field " + i); + fail("FAIL: getLeastMaximum larger than getMaximum for field " + i); } if (cal.getMinimum(i) >= cal.getMaximum(i)) { - errln("FAIL: getMinimum not less than getMaximum for field " + i); + fail("FAIL: getMinimum not less than getMaximum for field " + i); } } @@ -321,22 +324,22 @@ public void TestGenericAPI() { cal.clear(); cal.set(1984, 5, 24); if (cal.getTime().getTime() != new Date(84, 5, 24).getTime()) { - errln("FAIL: Calendar.set(3 args) failed"); - logln(" Got: " + cal.getTime() + " Expected: " + new Date(84, 5, 24)); + fail("FAIL: Calendar.set(3 args) failed"); + System.out.println(" Got: " + cal.getTime() + " Expected: " + new Date(84, 5, 24)); } cal.clear(); cal.set(1985, 3, 2, 11, 49); if (cal.getTime().getTime() != new Date(85, 3, 2, 11, 49).getTime()) { - errln("FAIL: Calendar.set(5 args) failed"); - logln(" Got: " + cal.getTime() + " Expected: " + new Date(85, 3, 2, 11, 49)); + fail("FAIL: Calendar.set(5 args) failed"); + System.out.println(" Got: " + cal.getTime() + " Expected: " + new Date(85, 3, 2, 11, 49)); } cal.clear(); cal.set(1995, 9, 12, 1, 39, 55); if (cal.getTime().getTime() != new Date(95, 9, 12, 1, 39, 55).getTime()) { - errln("FAIL: Calendar.set(6 args) failed"); - logln(" Got: " + cal.getTime() + " Expected: " + new Date(95, 9, 12, 1, 39, 55)); + fail("FAIL: Calendar.set(6 args) failed"); + System.out.println(" Got: " + cal.getTime() + " Expected: " + new Date(95, 9, 12, 1, 39, 55)); } cal.getTime(); @@ -349,17 +352,17 @@ public void TestGenericAPI() { case MINUTE: case SECOND: if (!cal.isSet(i)) { - errln("FAIL: !Calendar.isSet test failed: " + calendarFieldNames[i]); + fail("FAIL: !Calendar.isSet test failed: " + calendarFieldNames[i]); } break; default: if (cal.isSet(i)) { - errln("FAIL: Calendar.isSet test failed: " + calendarFieldNames[i]); + fail("FAIL: Calendar.isSet test failed: " + calendarFieldNames[i]); } } cal.clear(i); if (cal.isSet(i)) { - errln("FAIL: Calendar.clear/isSet failed"); + fail("FAIL: Calendar.clear/isSet failed"); } } @@ -368,7 +371,7 @@ public void TestGenericAPI() { Locale[] loc = Calendar.getAvailableLocales(); long count = loc.length; if (count < 1 || loc == null) { - errln("FAIL: getAvailableLocales failed"); + fail("FAIL: getAvailableLocales failed"); } else { for (i = 0; i < count; ++i) { cal = Calendar.getInstance(loc[i]); @@ -399,13 +402,13 @@ public void TestGenericAPI() { gc = new GregorianCalendar(1998, 10, 14, 21, 43); if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43).getTime()) { - errln("FAIL: new GregorianCalendar(ymdhm) failed"); + fail("FAIL: new GregorianCalendar(ymdhm) failed"); } // delete gc; gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55); if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43, 55).getTime()) { - errln("FAIL: new GregorianCalendar(ymdhms) failed"); + fail("FAIL: new GregorianCalendar(ymdhms) failed"); } // C++ only: @@ -417,6 +420,7 @@ public void TestGenericAPI() { } // Verify Roger Webster's bug + @Test public void TestRog() { GregorianCalendar gc = new GregorianCalendar(); @@ -432,12 +436,13 @@ public void TestRog() { if (gc.get(YEAR) != year || gc.get(MONTH) != month || gc.get(DATE) != (date + i)) { - errln("FAIL: Date " + gc.getTime() + " wrong"); + fail("FAIL: Date " + gc.getTime() + " wrong"); } } } // Verify DAY_OF_WEEK + @Test public void TestDOW943() { dowTest(false); dowTest(true); @@ -453,18 +458,19 @@ void dowTest(boolean lenient) { int min = cal.getMinimum(DAY_OF_WEEK); int max = cal.getMaximum(DAY_OF_WEEK); if (dow < min || dow > max) { - errln("FAIL: Day of week " + dow + " out of range"); + fail("FAIL: Day of week " + dow + " out of range"); } if (dow != SUNDAY) { - errln("FAIL2: Day of week should be SUNDAY; is " + dow + ": " + cal.getTime()); + fail("FAIL2: Day of week should be SUNDAY; is " + dow + ": " + cal.getTime()); } if (min != SUNDAY || max != SATURDAY) { - errln("FAIL: Min/max bad"); + fail("FAIL: Min/max bad"); } } // Verify that the clone method produces distinct objects with no // unintentionally shared fields. + @Test public void TestClonesUnique908() { Calendar c = Calendar.getInstance(); Calendar d = (Calendar) c.clone(); @@ -472,31 +478,33 @@ public void TestClonesUnique908() { d.set(MILLISECOND, 456); if (c.get(MILLISECOND) != 123 || d.get(MILLISECOND) != 456) { - errln("FAIL: Clones share fields"); + fail("FAIL: Clones share fields"); } } // Verify effect of Gregorian cutoff value @SuppressWarnings("deprecation") + @Test public void TestGregorianChange768() { boolean b; GregorianCalendar c = new GregorianCalendar(); - logln("With cutoff " + c.getGregorianChange()); - logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800))); - logln(" (should be FALSE)"); + System.out.println("With cutoff " + c.getGregorianChange()); + System.out.println(" isLeapYear(1800) = " + (b = c.isLeapYear(1800))); + System.out.println(" (should be FALSE)"); if (b != false) { - errln("FAIL"); + fail("FAIL"); } c.setGregorianChange(new Date(0, 0, 1)); // Jan 1 1900 - logln("With cutoff " + c.getGregorianChange()); - logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800))); - logln(" (should be TRUE)"); + System.out.println("With cutoff " + c.getGregorianChange()); + System.out.println(" isLeapYear(1800) = " + (b = c.isLeapYear(1800))); + System.out.println(" (should be TRUE)"); if (b != true) { - errln("FAIL"); + fail("FAIL"); } } // Test the correct behavior of the disambiguation algorithm. + @Test public void TestDisambiguation765() throws Exception { Locale savedLocale = Locale.getDefault(); try { @@ -562,7 +570,7 @@ public void TestDisambiguation765() throws Exception { c.set(WEEK_OF_MONTH, 1); verify765("1997 Tuesday in week 0 of June = ", c, 1997, JUNE, 3); } catch (IllegalArgumentException ex) { - errln("FAIL: Exception seen: " + ex.getMessage()); + fail("FAIL: Exception seen: " + ex.getMessage()); // ex.printStackTrace(log); } @@ -596,9 +604,9 @@ void verify765(String msg, Calendar c, int year, int month, int day) { if (c.get(YEAR) == year && c.get(MONTH) == month && c.get(DATE) == day) { - logln("PASS: " + msg + c.getTime()); + System.out.println("PASS: " + msg + c.getTime()); } else { - errln("FAIL: " + msg + c.getTime() + fail("FAIL: " + msg + c.getTime() + "; expected " + year + "/" + (month + 1) + "/" + day); } @@ -607,17 +615,18 @@ void verify765(String msg, Calendar c, int year, int month, int day) { // Called when e expected to be non-null void verify765(String msg, IllegalArgumentException e) { if (e == null) { - errln("FAIL: No IllegalArgumentException for " + msg); + fail("FAIL: No IllegalArgumentException for " + msg); } else { - logln("PASS: " + msg + "IllegalArgument as expected"); + System.out.println("PASS: " + msg + "IllegalArgument as expected"); } } // Test the behavior of GMT vs. local time + @Test public void TestGMTvsLocal4064654() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -645,7 +654,7 @@ void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) { gmtcal.set(MILLISECOND, 0); date = gmtcal.getTime(); - logln("date = " + date); + System.out.println("date = " + date); Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); @@ -658,7 +667,7 @@ void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) { cal.get(DAY_OF_WEEK), cal.get(MILLISECOND)); - logln("offset for " + date + "= " + (offset / 1000 / 60 / 60.0) + "hr"); + System.out.println("offset for " + date + "= " + (offset / 1000 / 60 / 60.0) + "hr"); int utc = ((cal.get(HOUR_OF_DAY) * 60 + cal.get(MINUTE)) * 60 @@ -668,7 +677,7 @@ void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) { int expected = ((hr * 60 + mn) * 60 + sc) * 1000; if (utc != expected) { - errln("FAIL: Discrepancy of " + fail("FAIL: Discrepancy of " + (utc - expected) + " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr"); } @@ -676,6 +685,7 @@ void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) { // Verify that add and set work regardless of the order in which // they are called. + @Test public void TestAddSetOrder621() { @SuppressWarnings("deprecation") Date d = new Date(97, 4, 14, 13, 23, 45); @@ -699,13 +709,14 @@ public void TestAddSetOrder621() { String s2 = cal.getTime().toString(); if (s.equals(s2)) { - logln("Pass: " + s + " == " + s2); + System.out.println("Pass: " + s + " == " + s2); } else { - errln("FAIL: " + s + " != " + s2); + fail("FAIL: " + s + " != " + s2); } } // Verify that add works. + @Test public void TestAdd520() { int y = 1997, m = FEBRUARY, d = 1; GregorianCalendar temp = new GregorianCalendar(y, m, d); @@ -737,19 +748,20 @@ void check520(Calendar c, int y, int m, int d) { if (c.get(YEAR) != y || c.get(MONTH) != m || c.get(DATE) != d) { - errln("FAILURE: Expected YEAR/MONTH/DATE of " + fail("FAILURE: Expected YEAR/MONTH/DATE of " + y + "/" + (m + 1) + "/" + d + "; got " + c.get(YEAR) + "/" + (c.get(MONTH) + 1) + "/" + c.get(DATE)); } else { - logln("Confirmed: " + System.out.println("Confirmed: " + y + "/" + (m + 1) + "/" + d); } } // Verify that setting fields works. This test fails when an exception is thrown. + @Test public void TestFieldSet4781() { try { GregorianCalendar g = new GregorianCalendar(); @@ -763,16 +775,17 @@ public void TestFieldSet4781() { // The following line will result in IllegalArgumentException because // it thinks the YEAR is set and it is NOT. if (g2.equals(g)) { - logln("Same"); + System.out.println("Same"); } else { - logln("Different"); + System.out.println("Different"); } } catch (IllegalArgumentException e) { - errln("Unexpected exception seen: " + e); + fail("Unexpected exception seen: " + e); } } // Test serialization of a Calendar object + @Test public void TestSerialize337() { Calendar cal = Calendar.getInstance(); @@ -800,15 +813,15 @@ public void TestSerialize337() { File fl = new File(FILENAME); fl.delete(); } catch (IOException e) { - errln("FAIL: Exception received:"); + fail("FAIL: Exception received:"); // e.printStackTrace(log); } catch (ClassNotFoundException e) { - errln("FAIL: Exception received:"); + fail("FAIL: Exception received:"); // e.printStackTrace(log); } if (!ok) { - errln("Serialization of Calendar object failed."); + fail("Serialization of Calendar object failed."); } } static final String PREFIX = "abc"; @@ -816,6 +829,7 @@ public void TestSerialize337() { static final String FILENAME = "tmp337.bin"; // Try to zero out the seconds field + @Test public void TestSecondsZero121() { Calendar cal = new GregorianCalendar(); // Initialize with current date/time @@ -825,11 +839,12 @@ public void TestSecondsZero121() { Date d = cal.getTime(); String s = d.toString(); if (s.indexOf(":00 ") < 0) { - errln("Expected to see :00 in " + s); + fail("Expected to see :00 in " + s); } } // Try various sequences of add, set, and get method calls. + @Test public void TestAddSetGet0610() { // // Error case 1: @@ -840,13 +855,13 @@ public void TestAddSetGet0610() { { Calendar calendar = new GregorianCalendar(); calendar.set(1993, JANUARY, 4); - logln("1A) " + value(calendar)); + System.out.println("1A) " + value(calendar)); calendar.add(DATE, 1); String v = value(calendar); - logln("1B) " + v); - logln("--) 1993/0/5"); + System.out.println("1B) " + v); + System.out.println("--) 1993/0/5"); if (!v.equals(EXPECTED_0610)) { - errln("Expected " + EXPECTED_0610 + fail("Expected " + EXPECTED_0610 + "; saw " + v); } } @@ -858,13 +873,13 @@ public void TestAddSetGet0610() { // { Calendar calendar = new GregorianCalendar(1993, JANUARY, 4); - logln("2A) " + value(calendar)); + System.out.println("2A) " + value(calendar)); calendar.add(DATE, 1); String v = value(calendar); - logln("2B) " + v); - logln("--) 1993/0/5"); + System.out.println("2B) " + v); + System.out.println("--) 1993/0/5"); if (!v.equals(EXPECTED_0610)) { - errln("Expected " + EXPECTED_0610 + fail("Expected " + EXPECTED_0610 + "; saw " + v); } } @@ -877,14 +892,14 @@ public void TestAddSetGet0610() { // { Calendar calendar = new GregorianCalendar(1993, JANUARY, 4); - logln("3A) " + value(calendar)); + System.out.println("3A) " + value(calendar)); calendar.getTime(); calendar.add(DATE, 1); String v = value(calendar); - logln("3B) " + v); - logln("--) 1993/0/5"); + System.out.println("3B) " + v); + System.out.println("--) 1993/0/5"); if (!v.equals(EXPECTED_0610)) { - errln("Expected " + EXPECTED_0610 + fail("Expected " + EXPECTED_0610 + "; saw " + v); } } @@ -897,6 +912,7 @@ static String value(Calendar calendar) { static String EXPECTED_0610 = "1993/0/5"; // Test that certain fields on a certain date are as expected. + @Test public void TestFields060() { int year = 1997; int month = OCTOBER; //october @@ -908,7 +924,7 @@ public void TestFields060() { int field = EXPECTED_FIELDS[i++]; int expected = EXPECTED_FIELDS[i++]; if (calendar.get(field) != expected) { - errln("Expected field " + field + " to have value " + expected + fail("Expected field " + field + " to have value " + expected + "; received " + calendar.get(field) + " instead"); } } @@ -942,6 +958,7 @@ public void TestFields060() { // Verify that the fields are as expected (mostly zero) at the epoch start. // Note that we adjust for the default timezone to get most things to zero. + @Test public void TestEpochStartFields() { String[][] lt = { {"en", "US", "US/Pacific"}, /* First day = 1, Minimum day = 1 */ @@ -988,14 +1005,14 @@ public void TestEpochStartFields() { boolean err = false; for (int i = 0; i < calendarFieldNames.length; ++i) { if ((val = c.get(i)) != EPOCH_FIELDS[i]) { - errln("Wrong value: " + val + fail("Wrong value: " + val + " for field(" + calendarFieldNames[i] + "), expected: " + EPOCH_FIELDS[i]); err = true; } } if (err) { - errln("Failed: \n\tDate=" + d + "\n\tTimeZone=" + z + fail("Failed: \n\tDate=" + d + "\n\tTimeZone=" + z + "\n\tLocale=" + l + "\n\tCalendar=" + c); } } @@ -1007,6 +1024,7 @@ public void TestEpochStartFields() { // Verify that as you add days to the calendar (e.g., 24 day periods), // the day of the week shifts in the expected pattern. + @Test public void TestDOWProgression() { Calendar cal = new GregorianCalendar(1972, OCTOBER, 26); @@ -1020,66 +1038,68 @@ void marchByDelta(Calendar cal, int delta) { int DOW, newDOW = initialDOW; do { DOW = newDOW; - logln("DOW = " + DOW + " " + cur.getTime()); + System.out.println("DOW = " + DOW + " " + cur.getTime()); cur.add(DAY_OF_WEEK, delta); newDOW = cur.get(DAY_OF_WEEK); int expectedDOW = 1 + (DOW + delta - 1) % 7; if (newDOW != expectedDOW) { - errln("Day of week should be " + expectedDOW + fail("Day of week should be " + expectedDOW + " instead of " + newDOW + " on " + cur.getTime()); return; } } while (newDOW != initialDOW); } + @Test public void TestActualMinMax() { Calendar cal = new GregorianCalendar(1967, MARCH, 10); cal.setFirstDayOfWeek(SUNDAY); cal.setMinimalDaysInFirstWeek(3); if (cal.getActualMinimum(DAY_OF_MONTH) != 1) { - errln("Actual minimum date for 3/10/1967 should have been 1; got " + fail("Actual minimum date for 3/10/1967 should have been 1; got " + cal.getActualMinimum(DAY_OF_MONTH)); } if (cal.getActualMaximum(DAY_OF_MONTH) != 31) { - errln("Actual maximum date for 3/10/1967 should have been 31; got " + fail("Actual maximum date for 3/10/1967 should have been 31; got " + cal.getActualMaximum(DAY_OF_MONTH)); } cal.set(MONTH, FEBRUARY); if (cal.getActualMaximum(DAY_OF_MONTH) != 28) { - errln("Actual maximum date for 2/10/1967 should have been 28; got " + fail("Actual maximum date for 2/10/1967 should have been 28; got " + cal.getActualMaximum(DAY_OF_MONTH)); } if (cal.getActualMaximum(DAY_OF_YEAR) != 365) { - errln("Number of days in 1967 should have been 365; got " + fail("Number of days in 1967 should have been 365; got " + cal.getActualMaximum(DAY_OF_YEAR)); } cal.set(YEAR, 1968); if (cal.getActualMaximum(DAY_OF_MONTH) != 29) { - errln("Actual maximum date for 2/10/1968 should have been 29; got " + fail("Actual maximum date for 2/10/1968 should have been 29; got " + cal.getActualMaximum(DAY_OF_MONTH)); } if (cal.getActualMaximum(DAY_OF_YEAR) != 366) { - errln("Number of days in 1968 should have been 366; got " + fail("Number of days in 1968 should have been 366; got " + cal.getActualMaximum(DAY_OF_YEAR)); } // Using week settings of SUNDAY/3 (see above) if (cal.getActualMaximum(WEEK_OF_YEAR) != 52) { - errln("Number of weeks in 1968 should have been 52; got " + fail("Number of weeks in 1968 should have been 52; got " + cal.getActualMaximum(WEEK_OF_YEAR)); } cal.set(YEAR, 1976); // Using week settings of SUNDAY/3 (see above) if (cal.getActualMaximum(WEEK_OF_YEAR) != 53) { - errln("Number of weeks in 1976 should have been 53; got " + fail("Number of weeks in 1976 should have been 53; got " + cal.getActualMaximum(WEEK_OF_YEAR)); } } + @Test public void TestRoll() { Calendar cal = new GregorianCalendar(1997, JANUARY, 31); @@ -1089,7 +1109,7 @@ public void TestRoll() { Calendar cal2 = (Calendar) cal.clone(); cal2.roll(MONTH, i); if (cal2.get(DAY_OF_MONTH) != dayValues[i]) { - errln("Rolling the month in 1/31/1997 up by " + i + " should have yielded " + fail("Rolling the month in 1/31/1997 up by " + i + " should have yielded " + ((i + 1) % 12) + "/" + dayValues[i] + "/1997, but actually yielded " + ((i + 1) % 12) + "/" + cal2.get(DAY_OF_MONTH) + "/1997."); } @@ -1105,7 +1125,7 @@ public void TestRoll() { cal2.roll(YEAR, i); if (cal2.get(DAY_OF_MONTH) != dayValues2[i] || cal2.get(MONTH) != monthValues[i]) { - errln("Rolling the year in 2/29/1996 up by " + i + " should have yielded " + fail("Rolling the year in 2/29/1996 up by " + i + " should have yielded " + (monthValues[i] + 1) + "/" + dayValues2[i] + "/" + (1996 + i) + ", but actually yielded " + (cal2.get(MONTH) + 1) + "/" @@ -1118,17 +1138,17 @@ public void TestRoll() { cal.roll(HOUR_OF_DAY, -2); int f = cal.get(HOUR_OF_DAY); if (f != 22) { - errln("Rolling HOUR_OF_DAY=0 delta=-2 gave " + f + " Wanted 22"); + fail("Rolling HOUR_OF_DAY=0 delta=-2 gave " + f + " Wanted 22"); } cal.roll(HOUR_OF_DAY, 5); f = cal.get(HOUR_OF_DAY); if (f != 3) { - errln("Rolling HOUR_OF_DAY=22 delta=5 gave " + f + " Wanted 3"); + fail("Rolling HOUR_OF_DAY=22 delta=5 gave " + f + " Wanted 3"); } cal.roll(HOUR_OF_DAY, 21); f = cal.get(HOUR_OF_DAY); if (f != 0) { - errln("Rolling HOUR_OF_DAY=3 delta=21 gave " + f + " Wanted 0"); + fail("Rolling HOUR_OF_DAY=3 delta=21 gave " + f + " Wanted 0"); } // Test rolling hour @@ -1136,23 +1156,24 @@ public void TestRoll() { cal.roll(HOUR, -2); f = cal.get(HOUR); if (f != 10) { - errln("Rolling HOUR=0 delta=-2 gave " + f + " Wanted 10"); + fail("Rolling HOUR=0 delta=-2 gave " + f + " Wanted 10"); } cal.roll(HOUR, 5); f = cal.get(HOUR); if (f != 3) { - errln("Rolling HOUR=10 delta=5 gave " + f + " Wanted 3"); + fail("Rolling HOUR=10 delta=5 gave " + f + " Wanted 3"); } cal.roll(HOUR, 9); f = cal.get(HOUR); if (f != 0) { - errln("Rolling HOUR=3 delta=9 gave " + f + " Wanted 0"); + fail("Rolling HOUR=3 delta=9 gave " + f + " Wanted 0"); } } /* * Confirm that multiple calls to Calendar.set() works correctly. */ + @Test public void Test4374886() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); @@ -1171,7 +1192,7 @@ public void Test4374886() { || cal.get(MONTH) != JANUARY || cal.get(DATE) != 22 || cal.get(DAY_OF_WEEK) != MONDAY) { - errln("Failed : got " + cal.getTime() + ", expected Mon Jan 22, 2001"); + fail("Failed : got " + cal.getTime() + ", expected Mon Jan 22, 2001"); } } finally { Locale.setDefault(savedLocale); @@ -1179,6 +1200,7 @@ public void Test4374886() { } } + @Test public void TestClonedSharedZones() throws NoSuchFieldException, IllegalAccessException { Field zone = Calendar.class.getDeclaredField("zone"); zone.setAccessible(true); @@ -1191,13 +1213,13 @@ public void TestClonedSharedZones() throws NoSuchFieldException, IllegalAccessEx // c1 should have a shared zone if (!sharedZone.getBoolean(c1)) { - errln("Failed : c1.sharedZone == false"); + fail("Failed : c1.sharedZone == false"); } else { // c2 should have a shared zone too if (!sharedZone.getBoolean(c2)) { - errln("Failed : c2.sharedZone == false"); + fail("Failed : c2.sharedZone == false"); } else if (zone.get(c1) != zone.get(c2)) { - errln("Failed : c1.zone != c2.zone"); + fail("Failed : c1.zone != c2.zone"); } } } diff --git a/test/jdk/java/util/Calendar/FieldStateTest.java b/test/jdk/java/util/Calendar/FieldStateTest.java index 9fe5e7fc472..6b4632c13e1 100644 --- a/test/jdk/java/util/Calendar/FieldStateTest.java +++ b/test/jdk/java/util/Calendar/FieldStateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -24,9 +24,7 @@ /* * @test * @bug 4860664 4916815 4867075 - * @library /java/text/testlib - * @build Koyomi - * @run main FieldStateTest + * @run junit/othervm FieldStateTest * @summary Unit tests for internal fields states. */ @@ -36,31 +34,30 @@ import static java.util.Calendar.*; -public class FieldStateTest extends IntlTest { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - Locale reservedLocale = Locale.getDefault(); - TimeZone reservedTimeZone = TimeZone.getDefault(); - try { - TimeZone.setDefault(TimeZone.getTimeZone("GMT")); - Locale.setDefault(Locale.US); +import static org.junit.jupiter.api.Assertions.fail; - new FieldStateTest().run(args); - } finally { - // restore the reserved locale and time zone - Locale.setDefault(reservedLocale); - TimeZone.setDefault(reservedTimeZone); - } +public class FieldStateTest { + + // Change JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); } + + @Test public void TestFieldState() { Koyomi cal = new Koyomi(); - logln("Right after instantialtion:"); + System.out.println("Right after instantialtion:"); if (!cal.checkAllSet()) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Set date to 2003/10/31 after the instantiation:"); + System.out.println("Set date to 2003/10/31 after the instantiation:"); cal.set(2003, OCTOBER, 31); // let cal calculate the time cal.getTime(); @@ -70,18 +67,18 @@ public void TestFieldState() { // the fields have "computed". But we can't distinguish them // outside the package. if (!cal.checkAllSet()) { - errln(cal.getMessage()); + fail(cal.getMessage()); } // Make sure that the correct date was produced. if (!cal.checkInternalDate(2003, OCTOBER, 31, FRIDAY)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Change to Monday of the week, which is 2003/10/27:"); + System.out.println("Change to Monday of the week, which is 2003/10/27:"); cal.set(DAY_OF_WEEK, MONDAY); cal.getTime(); if (!cal.checkDate(2003, OCTOBER, 27)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } // The same operation didn't work after calling clear() before @@ -89,28 +86,28 @@ public void TestFieldState() { // operations. After the instantiation, all the fields are set // to "computed". But after calling clear(), the state becomes // "unset". - logln("Set to 2003/10/31 after clear():"); + System.out.println("Set to 2003/10/31 after clear():"); cal.clear(); cal.set(2003, OCTOBER, 31); cal.getTime(); cal.set(DAY_OF_WEEK, MONDAY); if (!cal.checkDate(2003, OCTOBER, 27, MONDAY)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Set to 2003/10/31 after clear(), then to the 51st week of year (12/19):"); + System.out.println("Set to 2003/10/31 after clear(), then to the 51st week of year (12/19):"); cal.clear(); cal.set(2003, OCTOBER, 31); cal.getTime(); cal.set(WEEK_OF_YEAR, 51); if (!cal.checkFieldValue(WEEK_OF_YEAR, 51)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkDate(2003, DECEMBER, 19, FRIDAY)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Set to 2003/10 Mon of 4th week (10/20: 43rd week of year, 293rd day):"); + System.out.println("Set to 2003/10 Mon of 4th week (10/20: 43rd week of year, 293rd day):"); cal.clear(); cal.set(YEAR, 2003); cal.set(MONTH, OCTOBER); @@ -118,32 +115,32 @@ public void TestFieldState() { cal.set(WEEK_OF_MONTH, 4); cal.getTime(); if (!cal.checkFieldValue(DAY_OF_MONTH, 20)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(WEEK_OF_YEAR, 43)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Set to 2003/10 Mon of 43rd week of year (10/20: 4th week of month, 293rd day):"); + System.out.println("Set to 2003/10 Mon of 43rd week of year (10/20: 4th week of month, 293rd day):"); cal.clear(); cal.set(YEAR, 2003); cal.set(DAY_OF_WEEK, MONDAY); cal.set(WEEK_OF_YEAR, 43); cal.getTime(); if (!cal.checkDate(2003, OCTOBER, 20, MONDAY)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(WEEK_OF_MONTH, 4)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln("Set day of week to SUNDAY and date to 2003/10/31. " + System.out.println("Set day of week to SUNDAY and date to 2003/10/31. " + "Then, getTime and set week of year to 43."); @SuppressWarnings("deprecation") @@ -161,15 +158,16 @@ public void TestFieldState() { cal.getTime(); cal.set(WEEK_OF_YEAR, 43); if (!cal.checkDate(2003, OCTOBER, 24, FRIDAY)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } /* * 4916815: REGRESSION: Problem with java.util.Calendar VM 1.4.2-b28 */ + @Test public void Test4916815() { - logln("Set date to 2003/9/26 (Fri). Roll to Aug and back to Sep. " + System.out.println("Set date to 2003/9/26 (Fri). Roll to Aug and back to Sep. " + "Set dayofweek to Sunday which should be 2003/9/21."); Koyomi cal = new Koyomi(); cal.clear(); @@ -183,13 +181,14 @@ public void Test4916815() { // Sunday of the week should be 2003/9/21. cal2.set(DAY_OF_WEEK, SUNDAY); if (!cal2.checkDate(2003, SEPTEMBER, 21, SUNDAY)) { - errln(cal2.getMessage()); + fail(cal2.getMessage()); } } /* * 4867075: GregorianCalendar get() calls complete() internally, should getTime() too? */ + @Test public void Test4867075() { Koyomi cal = new Koyomi(Locale.US); cal.clear(); @@ -209,7 +208,7 @@ private void checkDate(Koyomi cal, int dayOfWeek, cal.set(DAY_OF_WEEK, dayOfWeek); cal.getTime(); if (!cal.checkInternalDate(expectedYear, expectedMonth, expectedDayOfMonth, dayOfWeek)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } diff --git a/test/jdk/java/util/Calendar/GregorianCutoverTest.java b/test/jdk/java/util/Calendar/GregorianCutoverTest.java index a9b840a95b1..8b56c3ac62b 100644 --- a/test/jdk/java/util/Calendar/GregorianCutoverTest.java +++ b/test/jdk/java/util/Calendar/GregorianCutoverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -24,9 +24,7 @@ /* * @test * @bug 4359204 4928615 4743587 4956232 6459836 6549953 - * @library /java/text/testlib - * @build Koyomi - * @run main GregorianCutoverTest + * @run junit/othervm GregorianCutoverTest * @summary Unit tests related to the Gregorian cutover support. */ @@ -36,25 +34,25 @@ import static java.util.GregorianCalendar.*; -public class GregorianCutoverTest extends IntlTest { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - TimeZone tz = TimeZone.getDefault(); - Locale lc = Locale.getDefault(); - try { - TimeZone.setDefault(TimeZone.getTimeZone("GMT")); - Locale.setDefault(Locale.US); +import static org.junit.jupiter.api.Assertions.fail; - new GregorianCutoverTest().run(args); - } finally { - TimeZone.setDefault(tz); - Locale.setDefault(lc); - } +public class GregorianCutoverTest { + + // Change JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); } + /** * 4359204: GregorianCalendar.get(cal.DAY_OF_YEAR) is inconsistent for year 1582 */ + @Test public void Test4359204() { Koyomi cal = new Koyomi(); @@ -100,79 +98,79 @@ public void Test4359204() { checkContinuity(cal, DAY_OF_YEAR); checkContinuity(cal, WEEK_OF_YEAR); - logln("Default cutover"); + System.out.println("Default cutover"); cal = new Koyomi(); cal.set(1582, OCTOBER, 1); - logln(" roll --DAY_OF_MONTH from 1582/10/01"); + System.out.println(" roll --DAY_OF_MONTH from 1582/10/01"); cal.roll(DAY_OF_MONTH, -1); if (!cal.checkDate(1582, OCTOBER, 31)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" roll DAY_OF_MONTH+10 from 1582/10/31"); + System.out.println(" roll DAY_OF_MONTH+10 from 1582/10/31"); cal.roll(DAY_OF_MONTH, +10); if (!cal.checkDate(1582, OCTOBER, 20)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" roll DAY_OF_MONTH-10 from 1582/10/20"); + System.out.println(" roll DAY_OF_MONTH-10 from 1582/10/20"); cal.roll(DAY_OF_MONTH, -10); if (!cal.checkDate(1582, OCTOBER, 31)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" roll back one day further"); + System.out.println(" roll back one day further"); cal.roll(DAY_OF_MONTH, +1); if (!cal.checkDate(1582, OCTOBER, 1)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } // should handle the gap between 1969/12/22 (Julian) to 1970/1/5 (Gregorian) - logln("Cutover date is 1970/1/5"); + System.out.println("Cutover date is 1970/1/5"); @SuppressWarnings("deprecation") Date d1 = new Date(1970 - 1900, JANUARY, 5); cal.setGregorianChange(d1); cal.set(ERA, AD); cal.set(YEAR, 1970); - logln(" Set DAY_OF_YEAR to the 28th day of 1970"); + System.out.println(" Set DAY_OF_YEAR to the 28th day of 1970"); cal.set(DAY_OF_YEAR, 28); if (!cal.checkDate(1970, FEBRUARY, 1)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } if (!cal.checkFieldValue(WEEK_OF_YEAR, 5)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" 1969/12/22 should be the 356th day of the year."); + System.out.println(" 1969/12/22 should be the 356th day of the year."); cal.set(1969, DECEMBER, 22); if (!cal.checkFieldValue(DAY_OF_YEAR, 356)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" Set DAY_OF_YEAR to autual maximum."); + System.out.println(" Set DAY_OF_YEAR to autual maximum."); int actualMaxDayOfYear = cal.getActualMaximum(DAY_OF_YEAR); if (actualMaxDayOfYear != 356) { - errln("actual maximum of DAY_OF_YEAR: got " + actualMaxDayOfYear + ", expected 356"); + fail("actual maximum of DAY_OF_YEAR: got " + actualMaxDayOfYear + ", expected 356"); } cal.set(DAY_OF_YEAR, actualMaxDayOfYear); if (!cal.checkDate(1969, DECEMBER, 22)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } cal.set(1969, DECEMBER, 22); cal.roll(DAY_OF_YEAR, +1); - logln(" Set to 1969/12/22 and roll DAY_OF_YEAR++"); + System.out.println(" Set to 1969/12/22 and roll DAY_OF_YEAR++"); if (!cal.checkDate(1969, JANUARY, 1)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" 1970/1/5 should be the first day of the year."); + System.out.println(" 1970/1/5 should be the first day of the year."); cal.set(1970, JANUARY, 5); if (!cal.checkFieldValue(DAY_OF_YEAR, 1)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" roll --DAY_OF_MONTH from 1970/1/5"); + System.out.println(" roll --DAY_OF_MONTH from 1970/1/5"); cal.roll(DAY_OF_MONTH, -1); if (!cal.checkDate(1970, JANUARY, 31)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } - logln(" roll back one day of month"); + System.out.println(" roll back one day of month"); cal.roll(DAY_OF_MONTH, +1); if (!cal.checkDate(1970, JANUARY, 5)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } // Test "missing" dates in non-lenient. @@ -180,22 +178,22 @@ public void Test4359204() { cal.setLenient(false); try { // the next day of 1582/10/4 (Julian) is 1582/10/15 (Gregorian) - logln("1582/10/10 doesn't exit with the default cutover."); + System.out.println("1582/10/10 doesn't exit with the default cutover."); cal.set(1582, OCTOBER, 10); cal.getTime(); - errln(" Didn't throw IllegalArgumentException in non-lenient."); + fail(" Didn't throw IllegalArgumentException in non-lenient."); } catch (IllegalArgumentException e) { } } private void checkContinuity(Koyomi cal, int field) { cal.getTime(); - logln(Koyomi.getFieldName(field) + " starting on " + cal.toDateString()); + System.out.println(Koyomi.getFieldName(field) + " starting on " + cal.toDateString()); int max = cal.getActualMaximum(field); for (int i = 1; i <= max; i++) { - logln(i + " " + cal.toDateString()); + System.out.println(i + " " + cal.toDateString()); if (!cal.checkFieldValue(field, i)) { - errln(" " + cal.toDateString() + ":\t" + cal.getMessage()); + fail(" " + cal.toDateString() + ":\t" + cal.getMessage()); } cal.add(field, +1); } @@ -204,92 +202,95 @@ private void checkContinuity(Koyomi cal, int field) { /** * 4928615: GregorianCalendar returns wrong dates after setGregorianChange */ + @Test public void Test4928615() { Koyomi cal = new Koyomi(); - logln("Today is 2003/10/1 Gregorian."); + System.out.println("Today is 2003/10/1 Gregorian."); @SuppressWarnings("deprecation") Date x = new Date(2003 - 1900, 10 - 1, 1); cal.setTime(x); - logln(" Changing the cutover date to yesterday..."); + System.out.println(" Changing the cutover date to yesterday..."); cal.setGregorianChange(new Date(x.getTime() - (24 * 3600 * 1000))); if (!cal.checkDate(2003, OCTOBER, 1)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } - logln(" Changing the cutover date to tomorrow..."); + System.out.println(" Changing the cutover date to tomorrow..."); cal.setGregorianChange(new Date(x.getTime() + (24 * 3600 * 1000))); if (!cal.checkDate(2003, SEPTEMBER, 18)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } } /** * 4743587: GregorianCalendar.getLeastMaximum() returns wrong values */ + @Test public void Test4743587() { Koyomi cal = new Koyomi(); Koyomi cal2 = (Koyomi) cal.clone(); - logln("getLeastMaximum should handle cutover year.\n" + System.out.println("getLeastMaximum should handle cutover year.\n" + " default cutover date"); if (!cal.checkLeastMaximum(DAY_OF_YEAR, 365 - 10)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkLeastMaximum(WEEK_OF_YEAR, 52 - ((10 + 6) / 7))) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } // Corrected for 4956232 if (!cal.checkLeastMaximum(DAY_OF_MONTH, 28)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkLeastMaximum(WEEK_OF_MONTH, 3)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkLeastMaximum(DAY_OF_WEEK_IN_MONTH, 3)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } // make sure that getLeastMaximum calls didn't affect the date if (!cal.equals(cal2)) { - errln(" getLeastMaximum calls modified the object."); + fail(" getLeastMaximum calls modified the object."); } if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 1)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } - logln(" changing the date to 1582/10/20 for actual min/max tests"); + System.out.println(" changing the date to 1582/10/20 for actual min/max tests"); cal.set(1582, OCTOBER, 20); if (!cal.checkActualMinimum(DAY_OF_MONTH, 1)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } cal = new Koyomi(); - logln("Change the cutover date to 1970/1/5."); + System.out.println("Change the cutover date to 1970/1/5."); @SuppressWarnings("deprecation") Date d = new Date(1970 - 1900, 0, 5); cal.setGregorianChange(d); if (!cal.checkLeastMaximum(DAY_OF_YEAR, 356)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkLeastMaximum(DAY_OF_MONTH, 22)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 5)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } cal.set(1970, JANUARY, 10); if (!cal.checkActualMinimum(DAY_OF_MONTH, 5)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { - errln(" " + cal.getMessage()); + fail(" " + cal.getMessage()); } } /** * 6459836: (cal) GregorianCalendar set method provides wrong result */ + @Test public void Test6459836() { int hour = 13865672; Koyomi gc1 = new Koyomi(); @@ -297,19 +298,20 @@ public void Test6459836() { gc1.set(1, JANUARY, 1, 0, 0, 0); gc1.set(HOUR_OF_DAY, hour); if (!gc1.checkDate(1582, OCTOBER, 4)) { - errln("test case 1: " + gc1.getMessage()); + fail("test case 1: " + gc1.getMessage()); } gc1.clear(); gc1.set(1, JANUARY, 1, 0, 0, 0); gc1.set(HOUR_OF_DAY, hour + 24); if (!gc1.checkDate(1582, OCTOBER, 15)) { - errln("test case 2: " + gc1.getMessage()); + fail("test case 2: " + gc1.getMessage()); } } /** * 6549953 (cal) WEEK_OF_YEAR and DAY_OF_YEAR calculation problems around Gregorian cutover */ + @Test public void Test6549953() { Koyomi cal = new Koyomi(); @@ -319,13 +321,13 @@ public void Test6549953() { cal.checkFieldValue(WEEK_OF_YEAR, 42); cal.checkFieldValue(DAY_OF_WEEK, FRIDAY); if (!cal.checkDate(1582, OCTOBER, 29)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } cal.clear(); cal.set(1582, OCTOBER, 1); cal.set(DAY_OF_YEAR, 292); if (!cal.checkDate(1582, OCTOBER, 29)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } } diff --git a/test/jdk/java/util/Calendar/JulianTest.java b/test/jdk/java/util/Calendar/JulianTest.java index bd7105bce89..4311dab1e3b 100644 --- a/test/jdk/java/util/Calendar/JulianTest.java +++ b/test/jdk/java/util/Calendar/JulianTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2023, 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,20 +25,21 @@ * @test * @bug 5029449 * @summary Tests for the Julian calendar system (before the Gregorian cutover) - * @library /java/text/testlib + * @run junit JulianTest */ import static java.util.GregorianCalendar.*; -public class JulianTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new JulianTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class JulianTest { /* * 5029449: Regression: GregorianCalendar produces wrong Julian calendar dates in BC 1 */ + @Test public void Test5029449() { Koyomi cal = new Koyomi(); cal.clear(); @@ -46,7 +47,7 @@ public void Test5029449() { // Date should be BC 1/12/31 if (!cal.checkFieldValue(ERA, BC) || !cal.checkDate(1, DECEMBER, 31)) { - errln(cal.getMessage()); + fail(cal.getMessage()); } } } diff --git a/test/jdk/java/util/Calendar/NonLenientTest.java b/test/jdk/java/util/Calendar/NonLenientTest.java index 357cf0e95c0..58b22215bf2 100644 --- a/test/jdk/java/util/Calendar/NonLenientTest.java +++ b/test/jdk/java/util/Calendar/NonLenientTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,7 +25,7 @@ * @test * @bug 4147269 4266783 4726030 * @summary Make sure that validation is adequate in non-lenient mode. - * @library /java/text/testlib + * @run junit/othervm NonLenientTest */ import java.util.Date; @@ -35,22 +35,22 @@ import static java.util.Calendar.*; -public class NonLenientTest extends IntlTest { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; - public static void main(String[] args) throws Exception { - Locale reservedLocale = Locale.getDefault(); - TimeZone reservedTimeZone = TimeZone.getDefault(); - try { - Locale.setDefault(Locale.US); - TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); - new NonLenientTest().run(args); - } finally { - // restore the reserved locale and time zone - Locale.setDefault(reservedLocale); - TimeZone.setDefault(reservedTimeZone); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class NonLenientTest { + + // Change JVM default Locale and TimeZone + @BeforeAll + static void initAll() { + Locale.setDefault(Locale.US); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); } + + @Test public void TestValidationInNonLenient() { Koyomi cal = getNonLenient(); @@ -122,6 +122,7 @@ public void TestValidationInNonLenient() { /** * 4266783: java.util.GregorianCalendar: incorrect validation in non-lenient */ + @Test public void Test4266783() { Koyomi cal = getNonLenient(); // 2003/1 has up to 5 weeks. @@ -135,6 +136,7 @@ public void Test4266783() { /** * 4726030: GregorianCalendar doesn't check invalid dates in non-lenient */ + @Test public void Test4726030() { Koyomi cal = getNonLenient(); // Default year is 1970 in GregorianCalendar which isn't a leap year. @@ -146,6 +148,7 @@ public void Test4726030() { /** * 4147269: java.util.GregorianCalendar.computeTime() works wrong when lenient is false */ + @Test public void Test4147269() { Koyomi calendar = getNonLenient(); Date date = (new GregorianCalendar(1996, 0, 3)).getTime(); @@ -157,7 +160,7 @@ public void Test4147269() { calendar.set(field, value); try { calendar.computeTime(); // call method under test - errln("Test failed with field " + Koyomi.getFieldName(field) + fail("Test failed with field " + Koyomi.getFieldName(field) + "\n\tdate before: " + date + "\n\tdate after: " + calendar.getTime() + "\n\tvalue: " + value + " (max = " + max + ")"); @@ -172,7 +175,7 @@ public void Test4147269() { calendar.set(field, value); try { calendar.computeTime(); // call method under test - errln("Test failed with field " + Koyomi.getFieldName(field) + fail("Test failed with field " + Koyomi.getFieldName(field) + "\n\tdate before: " + date + "\n\tdate after: " + calendar.getTime() + "\n\tvalue: " + value + " (min = " + min + ")"); @@ -187,7 +190,7 @@ void validate(Koyomi cal, String desc) { try { cal.complete(); - errln(desc + " should throw IllegalArgumentException in non-lenient."); + fail(desc + " should throw IllegalArgumentException in non-lenient."); } catch (IllegalArgumentException e) { } @@ -198,14 +201,14 @@ void validate(Koyomi cal, String desc) { int[] afterFields = cal.getFields(); for (int i = 0; i < FIELD_COUNT; i++) { if (cal.isSet(i) && originalFields[i] != afterFields[i]) { - errln(" complete() modified fields[" + Koyomi.getFieldName(i) + "] got " + fail(" complete() modified fields[" + Koyomi.getFieldName(i) + "] got " + afterFields[i] + ", expected " + originalFields[i]); } } // In non-lenient, set state of fields shouldn't be modified. int afterSetFields = cal.getSetStateFields(); if (setFields != afterSetFields) { - errln(" complate() modified set states: before 0x" + toHex(setFields) + fail(" complate() modified set states: before 0x" + toHex(setFields) + ", after 0x" + toHex(afterSetFields)); } } diff --git a/test/jdk/java/util/Calendar/bug4243802.java b/test/jdk/java/util/Calendar/bug4243802.java index a2361317abb..499b7e45772 100644 --- a/test/jdk/java/util/Calendar/bug4243802.java +++ b/test/jdk/java/util/Calendar/bug4243802.java @@ -24,8 +24,9 @@ /* * @test * @bug 4243802 - * @summary confirm that Calendar.setTimeInMillis() and getTimeInMillis() - * can be called from a user program. They used to be protected methods. + * @summary confirm that Calendar.setTimeInMillis() and + * getTimeInMillis() can be called from a user program. (They used to + * be protected methods.) * @run junit bug4243802 */ @@ -35,17 +36,17 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; - import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class bug4243802 { + // Save JVM default Locale and TimeZone private static final TimeZone savedTz = TimeZone.getDefault(); private static final Locale savedLocale = Locale.getDefault(); - // Save JVM default Locale and TimeZone + // Set custom JVM default Locale and TimeZone @BeforeAll static void initAll() { Locale.setDefault(Locale.US); @@ -68,10 +69,8 @@ static void tearDownAll() { public void setCalendarWithoutDateTest() { Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); - cal1.clear(); cal2.clear(); - cal1.set(2001, Calendar.JANUARY, 25, 1, 23, 45); // Build the second calendar using the getTimeInMillis of the first cal2.setTimeInMillis(cal1.getTimeInMillis()); diff --git a/test/jdk/java/util/Calendar/bug4316678.java b/test/jdk/java/util/Calendar/bug4316678.java index b455f51e067..f6bd4b87cae 100644 --- a/test/jdk/java/util/Calendar/bug4316678.java +++ b/test/jdk/java/util/Calendar/bug4316678.java @@ -46,9 +46,11 @@ public class bug4316678 { private static final String serializedData = "bug4316678.ser"; + + // Save JVM default TimeZone private static final TimeZone savedTz = TimeZone.getDefault(); - // Save JVM default Locale and TimeZone + // Set custom JVM default TimeZone @BeforeAll static void initAll() { TimeZone.setDefault(TimeZone.getTimeZone("PST")); diff --git a/test/jdk/java/util/Calendar/bug4372743.java b/test/jdk/java/util/Calendar/bug4372743.java index da7d20e5cd0..193ad53d813 100644 --- a/test/jdk/java/util/Calendar/bug4372743.java +++ b/test/jdk/java/util/Calendar/bug4372743.java @@ -61,15 +61,16 @@ public class bug4372743 { + // Save JVM default timezone private static final TimeZone savedTz = TimeZone.getDefault(); - // Save JVM default Locale and TimeZone + // Set custom JVM default timezone @BeforeAll static void initAll() { TimeZone.setDefault(TimeZone.getTimeZone("PST")); } - // Restore JVM default Locale and TimeZone + // Restore JVM default timezone @AfterAll static void tearDownAll() { TimeZone.setDefault(savedTz); diff --git a/test/jdk/java/util/Calendar/bug4409072.java b/test/jdk/java/util/Calendar/bug4409072.java index af5ef02c349..617550fe1aa 100644 --- a/test/jdk/java/util/Calendar/bug4409072.java +++ b/test/jdk/java/util/Calendar/bug4409072.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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,25 +26,26 @@ * @bug 4409072 * @summary tests for set(), add(), and roll() with various week parameters. * @library /java/text/testlib - * @run main bug4409072 + * @run junit bug4409072 */ import java.util.*; import static java.util.Calendar.*; -public class bug4409072 extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new bug4409072().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class bug4409072 { /* Confirm some public methods' behavior in Calendar. * (e.g. add(), roll(), set()) */ + @Test public void Test4409072() { Locale locale = Locale.getDefault(); if (!TestUtils.usesGregorianCalendar(locale)) { - logln("Skipping this test because locale is " + locale); + System.out.println("Skipping this test because locale is " + locale); return; } @@ -411,7 +412,7 @@ void testSet() { if (cal.get(WEEK_OF_YEAR) != 22) { noerror = false; - errln("Failed : set(WEEK_OF_YEAR=22)" + + fail("Failed : set(WEEK_OF_YEAR=22)" + " *** get(WEEK_OF_YEAR=" + cal.get(WEEK_OF_YEAR) + ")" + ", got " + (month+1)+"/"+date+"/"+year + @@ -420,7 +421,7 @@ void testSet() { ", FirstDOW=" + dow); } else if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : set(WEEK_OF_YEAR=22)" + + fail("Failed : set(WEEK_OF_YEAR=22)" + " got " + (month+1)+"/"+date+"/"+year + ", expected " + (m+1)+"/"+d+"/"+y + ", MinFirstDOW=" + minDow + @@ -446,7 +447,7 @@ void testSet() { if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : set(WEEK_OF_MONTH=1)" + + fail("Failed : set(WEEK_OF_MONTH=1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected " + (m+1)+"/"+d+"/"+y + ", MinFirstDOW=" + minDow + @@ -470,7 +471,7 @@ void testSet() { if (cal.get(WEEK_OF_YEAR) != 1) { noerror = false; - errln("Failed : set(WEEK_OF_YEAR=1)" + + fail("Failed : set(WEEK_OF_YEAR=1)" + " *** get(WEEK_OF_YEAR=" + cal.get(WEEK_OF_YEAR) + ")" + ", got " + (month+1)+"/"+date+"/"+year + @@ -479,7 +480,7 @@ void testSet() { ", FirstDOW=" + dow); } else if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : set(WEEK_OF_YEAR=1)" + + fail("Failed : set(WEEK_OF_YEAR=1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected " + (m+1)+"/"+d+"/"+y + ", MinFirstDOW=" + minDow + @@ -490,7 +491,7 @@ void testSet() { } if (noerror) { - logln("Passed : set() test"); + System.out.println("Passed : set() test"); } } @@ -525,7 +526,7 @@ void testAdd() { if ((year != 2006) || (month != 0) || (date != 25)) { noerror = false; - errln("Failed : add(WEEK_OF_YEAR+1)" + + fail("Failed : add(WEEK_OF_YEAR+1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected 1/25/2006" + ", MinFirstDOW=" + minDow + @@ -542,7 +543,7 @@ void testAdd() { date = cal.get(DATE); if ((oldWOY - newWOY) != 3) { - errln("Failed : add(WEEK_OF_YEAR-1)" + + fail("Failed : add(WEEK_OF_YEAR-1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected 11/16/2005" + ", MinFirstDOW=" + minDow + @@ -550,7 +551,7 @@ void testAdd() { ", WEEK_OF_YEAR=" + newWOY + " should be " + (oldWOY-3)); } else if ((year != 2005) || (month != 10) || (date != 16)) { - errln("Failed : add(-1)" + + fail("Failed : add(-1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected 11/16/2005" + ", MinFirstDOW=" + minDow + @@ -560,7 +561,7 @@ void testAdd() { } if (noerror) { - logln("Passed : add() test"); + System.out.println("Passed : add() test"); } } @@ -622,7 +623,7 @@ void testRoll() { if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : roll(WEEK_OF_MONTH-1)" + + fail("Failed : roll(WEEK_OF_MONTH-1)" + " got " + (month+1) + "/" + date + "/" + year + ", expected " + (m+1) + "/" + d + "/" + y + ", MinFirstDOW=" + minDow + @@ -649,7 +650,7 @@ void testRoll() { if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : roll(WEEK_OF_YEAR+1)" + + fail("Failed : roll(WEEK_OF_YEAR+1)" + " got " + (month+1) + "/" + date + "/" + year + ", expected " + (m+1) + "/" + d + "/" + y + ", MinFirstDOW=" + minDow + @@ -670,7 +671,7 @@ void testRoll() { if ((year != y) || (month != m) || (date != d)) { noerror = false; - errln("Failed : roll(WEEK_OF_YEAR-1)" + + fail("Failed : roll(WEEK_OF_YEAR-1)" + " got " + (month+1)+"/"+date+"/"+year + ", expected " + (m+1)+"/"+d+"/"+y + ", MinFirstDOW=" + minDow + @@ -680,7 +681,7 @@ void testRoll() { } if (noerror) { - logln("Passed : roll() test"); + System.out.println("Passed : roll() test"); } } } diff --git a/test/jdk/java/util/Date/DateRegression.java b/test/jdk/java/util/Date/DateRegression.java index 70d8a5bf706..8fe89d9d59b 100644 --- a/test/jdk/java/util/Date/DateRegression.java +++ b/test/jdk/java/util/Date/DateRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -24,21 +24,22 @@ /* * @test * @bug 4023247 4027685 4032037 4072029 4073003 4118010 4120606 4133833 4136916 6274757 6314387 - * @library /java/text/testlib + * @run junit DateRegression */ import java.util.*; -@SuppressWarnings("deprecation") -public class DateRegression extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new DateRegression().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +@SuppressWarnings("deprecation") +public class DateRegression { /** * @bug 4023247 */ + @Test public void Test4023247() { Date d1 = new Date(0); Date d2 = new Date(0); @@ -58,46 +59,49 @@ public void Test4023247() { d2.setSeconds(0); if (d1.hashCode() != d2.hashCode()) - errln("Fail: Date hashCode misbehaves"); + fail("Fail: Date hashCode misbehaves"); } /** * @bug 4027685 */ + @Test public void Test4027685() { // Should be 01/16/97 00:00:00 Date nite = new Date("16-JAN-97 12:00 AM"); // Should be 01/16/97 12:00:00 Date noon = new Date("16-JAN-97 12:00 PM"); - logln("Midnight = " + nite + ", Noon = " + noon); + System.out.println("Midnight = " + nite + ", Noon = " + noon); if (!nite.equals(new Date(97, Calendar.JANUARY, 16, 0, 0)) || !noon.equals(new Date(97, Calendar.JANUARY, 16, 12, 0))) - errln("Fail: Nite/Noon confused"); + fail("Fail: Nite/Noon confused"); } /** * @bug 4032037 */ + @Test public void Test4032037() { Date ref = new Date(97, 1, 10); Date d = new Date(Date.parse("2/10/97")); - logln("Date.parse(2/10/97) => " + d); - if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d); + System.out.println("Date.parse(2/10/97) => " + d); + if (!d.equals(ref)) fail("Fail: Want " + ref + " Got " + d); d = new Date(Date.parse("10 feb 1997")); - logln("Date.parse(10 feb 1997) => " + d); - if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d); + System.out.println("Date.parse(10 feb 1997) => " + d); + if (!d.equals(ref)) fail("Fail: Want " + ref + " Got " + d); d = new Date("2/10/97"); - logln("Date(2/10/97) => " + d); - if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d); + System.out.println("Date(2/10/97) => " + d); + if (!d.equals(ref)) fail("Fail: Want " + ref + " Got " + d); d = new Date("10 feb 1997"); - logln("Date(10 feb 1997) => " + d); - if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d); + System.out.println("Date(10 feb 1997) => " + d); + if (!d.equals(ref)) fail("Fail: Want " + ref + " Got " + d); } /** * @bug 4072029 */ + @Test public void Test4072029() { TimeZone saveZone = TimeZone.getDefault(); @@ -110,7 +114,7 @@ public void Test4072029() { if (!s.equals(s2) || Math.abs(now.getTime() - now2.getTime()) > 60000 /*one min*/) { - errln("Fail: Roundtrip toString/parse"); + fail("Fail: Roundtrip toString/parse"); } } finally { @@ -121,16 +125,17 @@ public void Test4072029() { /** * @bug 4073003 */ + @Test public void Test4073003() { Date d = new Date(Date.parse("01/02/1984")); if (!d.equals(new Date(84, 0, 2))) - errln("Fail: Want 1/2/1984 Got " + d); + fail("Fail: Want 1/2/1984 Got " + d); d = new Date(Date.parse("02/03/2012")); if (!d.equals(new Date(112, 1, 3))) - errln("Fail: Want 2/3/2012 Got " + d); + fail("Fail: Want 2/3/2012 Got " + d); d = new Date(Date.parse("03/04/15")); if (!d.equals(new Date(115, 2, 4))) - errln("Fail: Want 3/4/2015 Got " + d); + fail("Fail: Want 3/4/2015 Got " + d); } /** @@ -140,26 +145,28 @@ public void Test4073003() { * NOTE: This turned out to be a user error (passing in 2000 instead * of 2000-1900 to the Date constructor). */ + @Test public void Test4118010() { Date d=new java.util.Date(2000-1900, Calendar.FEBRUARY, 29); int m=d.getMonth(); int date=d.getDate(); if (m != Calendar.FEBRUARY || date != 29) - errln("Fail: Want Feb 29, got " + d); + fail("Fail: Want Feb 29, got " + d); } /** * @bug 4120606 * Date objects share state after cloning. */ + @Test public void Test4120606() { Date d = new Date(98, Calendar.JUNE, 24); d.setMonth(Calendar.MAY); Date e = (Date)d.clone(); d.setMonth(Calendar.FEBRUARY); if (e.getMonth() != Calendar.MAY) { - errln("Cloned Date objects share state"); + fail("Cloned Date objects share state"); } } @@ -168,11 +175,12 @@ public void Test4120606() { * Date constructor crashes with parameters out of range, when it should * normalize. */ + @Test public void Test4133833() { Date date = new java.util.Date(12,15,19); Date exp = new Date(1913-1900, Calendar.APRIL, 19); if (!date.equals(exp)) - errln("Fail: Want " + exp + + fail("Fail: Want " + exp + "; got " + date); } @@ -181,15 +189,17 @@ public void Test4133833() { * Date.toString() throws exception in 1.2b4-E * CANNOT REPRODUCE this bug */ + @Test public void Test4136916() { Date time = new Date(); - logln(time.toString()); + System.out.println(time.toString()); } /** * @bug 6274757 * Date getTime and toString interaction for some time values */ + @Test public void Test6274757() { TimeZone savedTz = TimeZone.getDefault(); try { @@ -199,11 +209,11 @@ public void Test6274757() { Calendar jdkCal = Calendar.getInstance(jdkGMT); jdkCal.clear(); jdkCal.set(1582, Calendar.OCTOBER, 15); - logln("JDK time: " + jdkCal.getTime().getTime() ); - logln("JDK time (str): " + jdkCal.getTime() ); - logln("Day of month: " + jdkCal.get(Calendar.DAY_OF_MONTH)); + System.out.println("JDK time: " + jdkCal.getTime().getTime() ); + System.out.println("JDK time (str): " + jdkCal.getTime() ); + System.out.println("Day of month: " + jdkCal.get(Calendar.DAY_OF_MONTH)); Date co = jdkCal.getTime(); - logln("Change over (Oct 15 1582) = " + co + " (" + + System.out.println("Change over (Oct 15 1582) = " + co + " (" + co.getTime() + ")"); long a = jdkCal.getTime().getTime(); Date c = jdkCal.getTime(); @@ -211,9 +221,9 @@ public void Test6274757() { long b = c.getTime(); if (a != b) { - errln("ERROR: " + a + " != " + b); + fail("ERROR: " + a + " != " + b); } else { - logln(a + " = " + b); + System.out.println(a + " = " + b); } } finally { TimeZone.setDefault(savedTz); @@ -224,16 +234,17 @@ public void Test6274757() { * @bug 6314387 * JCK6.0: api/java_util/Date/index.html#misc fails, mustang */ + @Test public void Test6314387() { Date d = new Date(Long.MAX_VALUE); int y = d.getYear(); if (y != 292277094) { - errln("yesr: got " + y + ", expected 292277094"); + fail("yesr: got " + y + ", expected 292277094"); } d = new Date(Long.MIN_VALUE); y = d.getYear(); if (y != 292267155) { - errln("yesr: got " + y + ", expected 292267155"); + fail("yesr: got " + y + ", expected 292267155"); } } } diff --git a/test/jdk/java/util/Date/DateTest.java b/test/jdk/java/util/Date/DateTest.java index 98392760ba3..6740cb16faa 100644 --- a/test/jdk/java/util/Date/DateTest.java +++ b/test/jdk/java/util/Date/DateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,23 +25,24 @@ * @test * @bug 4143459 * @summary test Date - * @library /java/text/testlib + * @run junit DateTest */ import java.text.*; import java.util.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + @SuppressWarnings("deprecation") -public class DateTest extends IntlTest +public class DateTest { - public static void main(String[] args) throws Exception { - new DateTest().run(args); - } - /** * @bug 4143459 * Warning: Use TestDefaultZone() for complete testing of this bug. */ + @Test public void TestDefaultZoneLite() { // Note: This test is redundant with TestDefaultZone(). It was added by // request to provide a short&sweet test for this bug. It does not test @@ -57,7 +58,7 @@ public void TestDefaultZoneLite() { d.setHours(6); TimeZone.setDefault(TimeZone.getTimeZone("PST")); if (d.getHours() != 22) { - errln("Fail: Date.setHours()/getHours() ignoring default zone"); + fail("Fail: Date.setHours()/getHours() ignoring default zone"); } } finally { TimeZone.setDefault(save); } @@ -66,6 +67,7 @@ public void TestDefaultZoneLite() { /** * @bug 4143459 */ + @Test public void TestDefaultZone() { // Various problems can creep up, with the current implementation of Date, // when the default zone is changed. @@ -87,7 +89,7 @@ public void TestDefaultZone() { // sub-object (most Date objects), and a Date object with a Calendar // sub-object. We make two passes to cover the two cases. for (int pass=0; pass<2; ++pass) { - logln(pass == 0 ? "Normal Date object" : "Date with Calendar sub-object"); + System.out.println(pass == 0 ? "Normal Date object" : "Date with Calendar sub-object"); TimeZone.setDefault(GMT); d = new Date(refstr); @@ -96,7 +98,7 @@ public void TestDefaultZone() { d.setYear(d.getYear()); } if (d.getTime() != ref.getTime()) { - errln("FAIL: new Date(\"" + refstr + "\") x GMT -> " + d + + fail("FAIL: new Date(\"" + refstr + "\") x GMT -> " + d + " " + d.getTime() + " ms"); } @@ -104,7 +106,7 @@ public void TestDefaultZone() { d.getDay(), d.getHours(), d.getTimezoneOffset() }; for (int i=0; i PER_LOOP_LIMIT) - logln("WARNING: Date constructor/getYear slower than " + + System.out.println("WARNING: Date constructor/getYear slower than " + PER_LOOP_LIMIT + " ms"); } static double PER_LOOP_LIMIT = 3.0; @@ -150,6 +153,7 @@ public void TestPerformance592() /** * Verify that the Date(String) constructor works. */ + @Test public void TestParseOfGMT() { Date OUT = null; @@ -164,7 +168,7 @@ public void TestParseOfGMT() // logln("PASS"); } else { - errln( "Expected: " + + fail( "Expected: " + new Date( expectedVal ) + ": " + expectedVal + @@ -178,56 +182,58 @@ public void TestParseOfGMT() // Check out Date's behavior with large negative year values; bug 664 // As of the fix to bug 4056585, Date should work correctly with // large negative years. + @Test public void TestDateNegativeYears() { Date d1= new Date(80,-1,2); - logln(d1.toString()); + System.out.println(d1.toString()); d1= new Date(-80,-1,2); - logln(d1.toString()); + System.out.println(d1.toString()); boolean e = false; try { d1= new Date(-800000,-1,2); - logln(d1.toString()); + System.out.println(d1.toString()); } catch (IllegalArgumentException ex) { e = true; } - if (e) errln("FAIL: Saw exception for year -800000"); - else logln("Pass: No exception for year -800000"); + if (e) fail("FAIL: Saw exception for year -800000"); + else System.out.println("Pass: No exception for year -800000"); } // Verify the behavior of Date + @Test public void TestDate480() { TimeZone save = TimeZone.getDefault(); try { TimeZone.setDefault(TimeZone.getTimeZone("PST")); Date d1=new java.util.Date(97,8,13,10,8,13); - logln("d = "+d1); + System.out.println("d = "+d1); Date d2=new java.util.Date(97,8,13,30,8,13); // 20 hours later - logln("d+20h = "+d2); + System.out.println("d+20h = "+d2); double delta = (d2.getTime() - d1.getTime()) / 3600000; - logln("delta = " + delta + "h"); + System.out.println("delta = " + delta + "h"); - if (delta != 20.0) errln("Expected delta of 20; got " + delta); + if (delta != 20.0) fail("Expected delta of 20; got " + delta); Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(1997,8,13,10,8,13); Date t1 = cal.getTime(); - logln("d = "+t1); + System.out.println("d = "+t1); cal.clear(); cal.set(1997,8,13,30,8,13); // 20 hours later Date t2 = cal.getTime(); - logln("d+20h = "+t2); + System.out.println("d+20h = "+t2); double delta2 = (t2.getTime() - t1.getTime()) / 3600000; - logln("delta = " + delta2 + "h"); + System.out.println("delta = " + delta2 + "h"); - if (delta != 20.0) errln("Expected delta of 20; got " + delta2); + if (delta != 20.0) fail("Expected delta of 20; got " + delta2); } finally { TimeZone.setDefault(save); diff --git a/test/jdk/java/util/Date/TimestampTest.java b/test/jdk/java/util/Date/TimestampTest.java index 950f0a5fb91..06bcab22dad 100644 --- a/test/jdk/java/util/Date/TimestampTest.java +++ b/test/jdk/java/util/Date/TimestampTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2023, 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,23 +26,24 @@ * @bug 5008227 * @summary Make sure that changes to the Date class don't break java.sql.Timestamp. * @modules java.sql - * @library /java/text/testlib + * @run junit TimestampTest */ import java.util.*; import java.sql.Timestamp; -public class TimestampTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new TimestampTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class TimestampTest { /** * 5008227: java.sql.Timestamp.after() is not returning correct result * * Test before(), after(), equals(), compareTo() and getTime(). */ + @Test public void Test5008227() { long t = System.currentTimeMillis(); Timestamp ts1 = new Timestamp(t), ts2 = new Timestamp(t); @@ -88,28 +89,28 @@ private void compareTimestamps(Timestamp ts1, Timestamp ts2, int expected) { boolean expectedResult = expected > 0; boolean result = ts1.after(ts2); if (result != expectedResult) { - errln("ts1.after(ts2) returned " + result + fail("ts1.after(ts2) returned " + result + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")"); } expectedResult = expected < 0; result = ts1.before(ts2); if (result != expectedResult) { - errln("ts1.before(ts2) returned " + result + fail("ts1.before(ts2) returned " + result + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")"); } expectedResult = expected == 0; result = ts1.equals(ts2); if (result != expectedResult) { - errln("ts1.equals(ts2) returned " + result + fail("ts1.equals(ts2) returned " + result + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")"); } int x = ts1.compareTo(ts2); int y = (x > 0) ? 1 : (x < 0) ? -1 : 0; if (y != expected) { - errln("ts1.compareTo(ts2) returned " + x + ", expected " + fail("ts1.compareTo(ts2) returned " + x + ", expected " + relation(expected, "") + "0" + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")"); } @@ -122,7 +123,7 @@ private void compareTimestamps(Timestamp ts1, Timestamp ts2, int expected) { z = (n1 > n2) ? 1 : (n1 < n2) ? -1 : 0; } if (z != expected) { - errln("ts1.getTime() " + relation(z, "==") + " ts2.getTime(), expected " + fail("ts1.getTime() " + relation(z, "==") + " ts2.getTime(), expected " + relation(expected, "==") + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")"); } diff --git a/test/jdk/java/util/Locale/LegacyCodesClassInvariant.java b/test/jdk/java/util/Locale/LegacyCodesClassInvariant.java index c19a74516a0..bf4d659c8ee 100644 --- a/test/jdk/java/util/Locale/LegacyCodesClassInvariant.java +++ b/test/jdk/java/util/Locale/LegacyCodesClassInvariant.java @@ -20,13 +20,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + /* - @test - @bug 4184873 - @summary test that locale invariants are preserved across serialization - @library /java/text/testlib - @run main LegacyCodesClassInvariant -*/ + * @test + * @bug 4184873 + * @summary test that locale invariants are preserved across serialization. + * @run junit LegacyCodesClassInvariant + */ + /* * This file is available under and governed by the GNU General Public * License version 2 only, as published by the Free Software Foundation. @@ -63,23 +64,19 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.util.Locale; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + /** * A Locale can never contain the following language codes: he, yi or id. */ -public class LegacyCodesClassInvariant extends IntlTest { - public static void main(String[] args) throws Exception { - if (args.length == 1 && args[0].equals("prepTest")) { - prepTest(); - } else { - new LegacyCodesClassInvariant().run(args); - } - } - +public class LegacyCodesClassInvariant { + @Test public void testIt() throws Exception { verify("he"); verify("yi"); @@ -92,17 +89,12 @@ private void verify(String lang) { if (in != null) { final Locale loc = (Locale)in.readObject(); final Locale expected = Locale.of(lang, "XX"); - if (!(expected.equals(loc))) { - errln("Locale didn't maintain invariants for: "+lang); - errln(" got: "+loc); - errln(" excpeted: "+expected); - } else { - logln("Locale "+lang+" worked"); - } + assertEquals(expected, loc, + "Locale didn't maintain invariants for: "+lang); in.close(); } } catch (Exception e) { - errln(e.toString()); + fail(e.toString()); } } @@ -111,30 +103,8 @@ private ObjectInputStream getStream(String lang) { final File f = new File(System.getProperty("test.src", "."), "LegacyCodesClassInvariant_"+lang); return new ObjectInputStream(new FileInputStream(f)); } catch (Exception e) { - errln(e.toString()); + fail(e.toString()); return null; } } - - /** - * Create serialized output files of the test locales. After they are created, these test - * files should be corrupted (by hand) to contain invalid locale name values. - */ - private static void prepTest() { - outputLocale("he"); - outputLocale("yi"); - outputLocale("id"); - } - - private static void outputLocale(String lang) { - try { - ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("LegacyCodesClassInvariant_"+lang)); - out.writeObject(Locale.of(lang, "XX")); - out.close(); - } catch (Exception e) { - System.out.println(e); - } - } - } diff --git a/test/jdk/java/util/Locale/LocaleEnhanceTest.java b/test/jdk/java/util/Locale/LocaleEnhanceTest.java index f3cfc5941f0..ae796300231 100644 --- a/test/jdk/java/util/Locale/LocaleEnhanceTest.java +++ b/test/jdk/java/util/Locale/LocaleEnhanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, 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,24 +41,20 @@ import java.util.Locale.Builder; import java.util.Set; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + /** * @test * @bug 6875847 6992272 7002320 7015500 7023613 7032820 7033504 7004603 * 7044019 8008577 8176853 8255086 8263202 8287868 * @summary test API changes to Locale - * @library /java/text/testlib * @modules jdk.localedata * @compile LocaleEnhanceTest.java - * @run main/othervm -Djava.locale.providers=JRE,SPI -esa LocaleEnhanceTest + * @run junit/othervm -Djava.locale.providers=JRE,SPI -esa LocaleEnhanceTest */ -public class LocaleEnhanceTest extends IntlTest { - - public static void main(String[] args) throws Exception { - List argList = new ArrayList(); - argList.addAll(Arrays.asList(args)); - argList.add("-nothrow"); - new LocaleEnhanceTest().run(argList.toArray(new String[argList.size()])); - } +public class LocaleEnhanceTest { public LocaleEnhanceTest() { } @@ -83,6 +79,7 @@ public LocaleEnhanceTest() { * Ensure that Builder builds locales that have the expected * tag and java6 ID. Note the odd cases for the ID. */ + @Test public void testCreateLocaleCanonicalValid() { String[] valids = { "en-Latn-US-NewYork", "en_US_NewYork_#Latn", @@ -131,7 +128,7 @@ public void testCreateLocaleCanonicalValid() { assertEquals(msg + "id", id, l.toString()); } catch (IllegalArgumentException e) { - errln(msg + e.getMessage()); + fail(msg + e.getMessage()); } } } @@ -146,6 +143,7 @@ public void testCreateLocaleCanonicalValid() { * Note that 'New' and 'York' are invalid BCP47 variant subtags * because they are too short. */ + @Test public void testCreateLocaleMultipleVariants() { String[] valids = { @@ -188,7 +186,7 @@ public void testCreateLocaleMultipleVariants() { assertEquals(msg + "id", id, l.toString()); } catch (IllegalArgumentException e) { - errln(msg + e.getMessage()); + fail(msg + e.getMessage()); } } } @@ -197,6 +195,7 @@ public void testCreateLocaleMultipleVariants() { * Ensure that all these invalid formats are not recognized by * forLanguageTag. */ + @Test public void testCreateLocaleCanonicalInvalidSeparator() { String[] invalids = { // trailing separator @@ -240,6 +239,7 @@ public void testCreateLocaleCanonicalInvalidSeparator() { * Ensure that all current locale ids parse. Use DateFormat as a proxy * for all current locale ids. */ + @Test public void testCurrentLocales() { Locale[] locales = java.text.DateFormat.getAvailableLocales(); Builder builder = new Builder(); @@ -266,6 +266,7 @@ public void testCurrentLocales() { /** * Ensure that all icu locale ids parse. */ + @Test public void testIcuLocales() throws Exception { BufferedReader br = new BufferedReader( new InputStreamReader( @@ -282,6 +283,7 @@ public void testIcuLocales() throws Exception { /// Compatibility tests /// + @Test public void testConstructor() { // all the old weirdness still holds, no new weirdness String[][] tests = { @@ -320,6 +322,7 @@ public void testConstructor() { /// Locale API tests. /// + @Test public void testGetScript() { // forLanguageTag normalizes case Locale locale = Locale.forLanguageTag("und-latn"); @@ -334,6 +337,7 @@ public void testGetScript() { assertEquals("script is empty string", "", locale.getScript()); } + @Test public void testGetExtension() { // forLanguageTag does NOT normalize to hyphen Locale locale = Locale.forLanguageTag("und-a-some_ex-tension"); @@ -354,6 +358,7 @@ public void testGetExtension() { assertEquals("x", "y-z-blork", locale.getExtension('x')); } + @Test public void testGetExtensionKeys() { Locale locale = Locale.forLanguageTag("und-a-xx-yy-b-zz-ww"); Set result = locale.getExtensionKeys(); @@ -363,7 +368,7 @@ public void testGetExtensionKeys() { // result is not mutable try { result.add('x'); - errln("expected exception on add to extension key set"); + fail("expected exception on add to extension key set"); } catch (UnsupportedOperationException e) { // ok @@ -374,6 +379,7 @@ public void testGetExtensionKeys() { assertTrue("empty result", locale.getExtensionKeys().isEmpty()); } + @Test public void testGetUnicodeLocaleAttributes() { Locale locale = Locale.forLanguageTag("en-US-u-abc-def"); Set attributes = locale.getUnicodeLocaleAttributes(); @@ -386,6 +392,7 @@ public void testGetUnicodeLocaleAttributes() { assertTrue("empty attributes", attributes.isEmpty()); } + @Test public void testGetUnicodeLocaleType() { Locale locale = Locale.forLanguageTag("und-u-co-japanese-nu-thai"); assertEquals("collation", "japanese", locale.getUnicodeLocaleType("co")); @@ -413,6 +420,7 @@ public void testGetUnicodeLocaleType() { new ExpectNPE() { public void call() { Locale.forLanguageTag("").getUnicodeLocaleType(null); }}; } + @Test public void testGetUnicodeLocaleKeys() { Locale locale = Locale.forLanguageTag("und-u-co-japanese-nu-thai"); Set result = locale.getUnicodeLocaleKeys(); @@ -422,13 +430,14 @@ public void testGetUnicodeLocaleKeys() { // result is not modifiable try { result.add("frobozz"); - errln("expected exception when add to locale key set"); + fail("expected exception when add to locale key set"); } catch (UnsupportedOperationException e) { // ok } } + @Test public void testPrivateUseExtension() { Locale locale = Locale.forLanguageTag("x-y-x-blork-"); assertEquals("blork", "y-x-blork", locale.getExtension(Locale.PRIVATE_USE_EXTENSION)); @@ -437,6 +446,7 @@ public void testPrivateUseExtension() { assertEquals("no privateuse", null, locale.getExtension(Locale.PRIVATE_USE_EXTENSION)); } + @Test public void testToLanguageTag() { // lots of normalization to test here // test locales created using the constructor @@ -502,6 +512,7 @@ public void testToLanguageTag() { } + @Test public void testForLanguageTag() { // forLanguageTag implements the 'Language-Tag' production of // BCP47, so it handles private use and legacy language tags, @@ -589,7 +600,7 @@ public void testForLanguageTag() { assertEquals(msg, test[2], locale.toLanguageTag()); } catch (IllegalArgumentException e) { - errln(msg + " caught exception: " + e); + fail(msg + " caught exception: " + e); } } @@ -607,6 +618,7 @@ public void testForLanguageTag() { assertEquals("Duplicated Unicode locake key followed by an extension", "1234", locale.getExtension('c')); } + @Test public void testGetDisplayScript() { Locale latnLocale = Locale.forLanguageTag("und-latn"); Locale hansLocale = Locale.forLanguageTag("und-hans"); @@ -624,6 +636,7 @@ public void testGetDisplayScript() { Locale.setDefault(oldLocale); } + @Test public void testGetDisplayScriptWithLocale() { Locale latnLocale = Locale.forLanguageTag("und-latn"); Locale hansLocale = Locale.forLanguageTag("und-hans"); @@ -635,6 +648,7 @@ public void testGetDisplayScriptWithLocale() { assertEquals("hans DE", "Vereinfacht", hansLocale.getDisplayScript(Locale.GERMANY)); } + @Test public void testGetDisplayName() { final Locale[] testLocales = { Locale.ROOT, @@ -688,6 +702,7 @@ public void testGetDisplayName() { /// Builder tests /// + @Test public void testBuilderSetLocale() { Builder builder = new Builder(); Builder lenientBuilder = new Builder(); @@ -730,6 +745,7 @@ public void call() { }; } + @Test public void testBuilderSetLanguageTag() { String source = "eN-LaTn-Us-NewYork-A-Xx-B-Yy-X-1-2-3"; String target = "en-Latn-US-NewYork-a-xx-b-yy-x-1-2-3"; @@ -747,6 +763,7 @@ public void testBuilderSetLanguageTag() { new BuilderILE() { public void call() { b.setLanguageTag("und-u-nu-thai-NU-chinese-xx-1234"); }}; } + @Test public void testBuilderSetLanguage() { // language is normalized to lower case String source = "eN"; @@ -792,6 +809,7 @@ public void testBuilderSetLanguage() { assertEquals("eng", "eng", result); } + @Test public void testBuilderSetScript() { // script is normalized to title case String source = "lAtN"; @@ -828,6 +846,7 @@ public void testBuilderSetScript() { assertEquals("4alpha", "Wxyz", builder.setScript("wxyz").build().getScript()); } + @Test public void testBuilderSetRegion() { // region is normalized to upper case String source = "uS"; @@ -865,6 +884,7 @@ public void testBuilderSetRegion() { assertEquals("3digit", "000", builder.setRegion("000").build().getCountry()); } + @Test public void testBuilderSetVariant() { // Variant case is not normalized in lenient variant mode String source = "NewYork"; @@ -917,6 +937,7 @@ public void testBuilderSetVariant() { new BuilderILE("abcde-fg") { public void call() { b.setVariant(arg); }}; } + @Test public void testBuilderSetExtension() { // upper case characters are normalized to lower case final char sourceKey = 'a'; @@ -1007,6 +1028,7 @@ public void testBuilderSetExtension() { assertEquals("duplicate keys", "und-u-nu-thai-xx-1234", result); } + @Test public void testBuilderAddUnicodeLocaleAttribute() { Builder builder = new Builder(); Locale locale = builder @@ -1038,6 +1060,7 @@ public void testBuilderAddUnicodeLocaleAttribute() { new BuilderILE("invalid attribute") { public void call() { b.addUnicodeLocaleAttribute("ca"); }}; } + @Test public void testBuildersetUnicodeLocaleKeyword() { // Note: most behavior is tested in testBuilderSetExtension Builder builder = new Builder(); @@ -1081,6 +1104,7 @@ public void testBuildersetUnicodeLocaleKeyword() { new BuilderILE("ab", "abcdefghi") { public void call() { b.setUnicodeLocaleKeyword("ab", arg); }}; } + @Test public void testBuilderPrivateUseExtension() { // normalizes hyphens to underscore, case to lower String source = "c-B-a"; @@ -1096,6 +1120,7 @@ public void testBuilderPrivateUseExtension() { new BuilderILE("a--b") { public void call() { b.setExtension(Locale.PRIVATE_USE_EXTENSION, arg); }}; } + @Test public void testBuilderClear() { String monster = "en-latn-US-NewYork-a-bb-cc-u-co-japanese-x-z-y-x-x"; Builder builder = new Builder(); @@ -1108,14 +1133,17 @@ public void testBuilderClear() { assertEquals("clear", "und", result); } + @Test public void testBuilderRemoveUnicodeAttribute() { // tested in testBuilderAddUnicodeAttribute } + @Test public void testBuilderBuild() { // tested in other test methods } + @Test public void testSerialize() { final Locale[] testLocales = { Locale.ROOT, @@ -1161,11 +1189,12 @@ public void testSerialize() { assertEquals("roundtrip " + locale, locale, o); } catch (Exception e) { - errln(locale + " encountered exception:" + e.getLocalizedMessage()); + fail(locale + " encountered exception:" + e.getLocalizedMessage()); } } } + @Test public void testDeserialize6() { final String TESTFILEPREFIX = "java6locale_"; @@ -1184,10 +1213,10 @@ public void testDeserialize6() { } if (dataDir == null) { - errln("'dataDir' is null. serialized.data.dir Property value is "+dataDirName); + fail("'dataDir' is null. serialized.data.dir Property value is "+dataDirName); return; } else if (!dataDir.isDirectory()) { - errln("'dataDir' is not a directory. dataDir: "+dataDir.toString()); + fail("'dataDir' is not a directory. dataDir: "+dataDir.toString()); return; } @@ -1219,11 +1248,12 @@ public void testDeserialize6() { Object o = ois.readObject(); assertEquals("Deserialize Java 6 Locale " + locale, o, locale); } catch (Exception e) { - errln("Exception while reading " + testfile.getAbsolutePath() + " - " + e.getMessage()); + fail("Exception while reading " + testfile.getAbsolutePath() + " - " + e.getMessage()); } } } + @Test public void testBug7002320() { // forLanguageTag() and Builder.setLanguageTag(String) // should add a location extension for following two cases. @@ -1267,6 +1297,7 @@ public void testBug7002320() { } } + @Test public void testBug7023613() { String[][] testdata = { {"en-Latn", "en__#Latn"}, @@ -1286,6 +1317,7 @@ public void testBug7023613() { /* * 7033504: (lc) incompatible behavior change for ja_JP_JP and th_TH_TH locales */ + @Test public void testBug7033504() { checkCalendar(Locale.of("ja", "JP", "jp"), "java.util.GregorianCalendar"); checkCalendar(Locale.of("ja", "jp", "jp"), "java.util.GregorianCalendar"); @@ -1318,13 +1350,13 @@ private void checkDigit(Locale loc, Character expected) { private void assertTrue(String msg, boolean v) { if (!v) { - errln(msg + ": expected true"); + fail(msg + ": expected true"); } } private void assertFalse(String msg, boolean v) { if (v) { - errln(msg + ": expected false"); + fail(msg + ": expected false"); } } @@ -1336,7 +1368,7 @@ private void assertEquals(String msg, Object e, Object v) { if (v != null) { v = "'" + v + "'"; } - errln(msg + ": expected " + e + " but got " + v); + fail(msg + ": expected " + e + " but got " + v); } } @@ -1345,19 +1377,19 @@ private void assertNotEquals(String msg, Object e, Object v) { if (e != null) { e = "'" + e + "'"; } - errln(msg + ": expected not equal " + e); + fail(msg + ": expected not equal " + e); } } private void assertNull(String msg, Object o) { if (o != null) { - errln(msg + ": expected null but got '" + o + "'"); + fail(msg + ": expected null but got '" + o + "'"); } } private void assertNotNull(String msg, Object o) { if (o == null) { - errln(msg + ": expected non null"); + fail(msg + ": expected non null"); } } @@ -1383,7 +1415,7 @@ public void run() { if (failMsg != null) { String msg = message(); msg = msg == null ? "" : msg + " "; - errln(msg + failMsg); + fail(msg + failMsg); } } diff --git a/test/jdk/java/util/Locale/LocaleTest.java b/test/jdk/java/util/Locale/LocaleTest.java index 1258115ecca..7cbda6dc70d 100644 --- a/test/jdk/java/util/Locale/LocaleTest.java +++ b/test/jdk/java/util/Locale/LocaleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, 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 @@ -27,10 +27,9 @@ * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549 * 6786276 7066203 7085757 8008577 8030696 8170840 8255086 8263202 8287868 * @summary test Locales - * @library /java/text/testlib * @modules jdk.localedata - * @run main/othervm -Djava.locale.providers=COMPAT,SPI LocaleTest - * @run main/othervm -Djava.locale.providers=COMPAT,SPI -Djava.locale.useOldISOCodes=true LocaleTest + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI LocaleTest + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI -Djava.locale.useOldISOCodes=true LocaleTest */ /* * This file is available under and governed by the GNU General Public @@ -86,7 +85,11 @@ import java.util.Locale; import java.util.MissingResourceException; -public class LocaleTest extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class LocaleTest { public LocaleTest() { } @@ -191,52 +194,50 @@ public LocaleTest() { { "English (United States)", "French (France)", "Croatian (Croatia)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" }, }; - public static void main(String[] args) throws Exception { - new LocaleTest().run(args); - } - + @Test public void TestBasicGetters() { for (int i = 0; i <= MAX_LOCALES; i++) { Locale testLocale = Locale.of(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); - logln("Testing " + testLocale + "..."); + System.out.println("Testing " + testLocale + "..."); if (!testLocale.getLanguage().equals(dataTable[LANG][i])) { - errln(" Language code mismatch: " + testLocale.getLanguage() + " versus " + fail(" Language code mismatch: " + testLocale.getLanguage() + " versus " + dataTable[LANG][i]); } if (!testLocale.getCountry().equals(dataTable[CTRY][i])) { - errln(" Country code mismatch: " + testLocale.getCountry() + " versus " + fail(" Country code mismatch: " + testLocale.getCountry() + " versus " + dataTable[CTRY][i]); } if (!testLocale.getVariant().equals(dataTable[VAR][i])) { - errln(" Variant code mismatch: " + testLocale.getVariant() + " versus " + fail(" Variant code mismatch: " + testLocale.getVariant() + " versus " + dataTable[VAR][i]); } if (!testLocale.toString().equals(dataTable[NAME][i])) { - errln(" Locale name mismatch: " + testLocale.toString() + " versus " + fail(" Locale name mismatch: " + testLocale.toString() + " versus " + dataTable[NAME][i]); } } - logln("Same thing without variant codes..."); + System.out.println("Same thing without variant codes..."); for (int i = 0; i <= MAX_LOCALES; i++) { Locale testLocale = Locale.of(dataTable[LANG][i], dataTable[CTRY][i]); - logln("Testing " + testLocale + "..."); + System.out.println("Testing " + testLocale + "..."); if (!testLocale.getLanguage().equals(dataTable[LANG][i])) { - errln(" Language code mismatch: " + testLocale.getLanguage() + " versus " + fail(" Language code mismatch: " + testLocale.getLanguage() + " versus " + dataTable[LANG][i]); } if (!testLocale.getCountry().equals(dataTable[CTRY][i])) { - errln(" Country code mismatch: " + testLocale.getCountry() + " versus " + fail(" Country code mismatch: " + testLocale.getCountry() + " versus " + dataTable[CTRY][i]); } if (!testLocale.getVariant().equals("")) { - errln(" Variant code mismatch: " + testLocale.getVariant() + " versus \"\""); + fail(" Variant code mismatch: " + testLocale.getVariant() + " versus \"\""); } } } + @Test public void TestSimpleResourceInfo() { for (int i = 0; i <= MAX_LOCALES; i++) { if (dataTable[LANG][i].equals("xx")) { @@ -244,20 +245,20 @@ public void TestSimpleResourceInfo() { } Locale testLocale = Locale.of(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); - logln("Testing " + testLocale + "..."); + System.out.println("Testing " + testLocale + "..."); if (!testLocale.getISO3Language().equals(dataTable[LANG3][i])) { - errln(" ISO-3 language code mismatch: " + testLocale.getISO3Language() + fail(" ISO-3 language code mismatch: " + testLocale.getISO3Language() + " versus " + dataTable[LANG3][i]); } if (!testLocale.getISO3Country().equals(dataTable[CTRY3][i])) { - errln(" ISO-3 country code mismatch: " + testLocale.getISO3Country() + fail(" ISO-3 country code mismatch: " + testLocale.getISO3Country() + " versus " + dataTable[CTRY3][i]); } /* // getLCID() is currently private if (!String.valueOf(testLocale.getLCID()).equals(dataTable[LCID][i])) - errln(" LCID mismatch: " + testLocale.getLCID() + " versus " + fail(" LCID mismatch: " + testLocale.getLCID() + " versus " + dataTable[LCID][i]); */ } @@ -269,6 +270,7 @@ public void TestSimpleResourceInfo() { * between 1.1.5 and 1.1.6, but I included a new test for it anyway) * @bug 4052440 Stop falling back to the default locale. */ + @Test public void TestDisplayNames() { Locale saveDefault = Locale.getDefault(); Locale english = Locale.US; @@ -277,29 +279,29 @@ public void TestDisplayNames() { Locale greek = Locale.of("el", "GR"); Locale.setDefault(english); - logln("With default = en_US..."); - logln(" In default locale..."); + System.out.println("With default = en_US..."); + System.out.println(" In default locale..."); doTestDisplayNames(null, DLANG_EN, false); - logln(" In locale = en_US..."); + System.out.println(" In locale = en_US..."); doTestDisplayNames(english, DLANG_EN, false); - logln(" In locale = fr_FR..."); + System.out.println(" In locale = fr_FR..."); doTestDisplayNames(french, DLANG_FR, false); - logln(" In locale = hr_HR..."); + System.out.println(" In locale = hr_HR..."); doTestDisplayNames(croatian, DLANG_HR, false); - logln(" In locale = el_GR..."); + System.out.println(" In locale = el_GR..."); doTestDisplayNames(greek, DLANG_EL, false); Locale.setDefault(french); - logln("With default = fr_FR..."); - logln(" In default locale..."); + System.out.println("With default = fr_FR..."); + System.out.println(" In default locale..."); doTestDisplayNames(null, DLANG_FR, true); - logln(" In locale = en_US..."); + System.out.println(" In locale = en_US..."); doTestDisplayNames(english, DLANG_EN, true); - logln(" In locale = fr_FR..."); + System.out.println(" In locale = fr_FR..."); doTestDisplayNames(french, DLANG_FR, true); - logln(" In locale = hr_HR..."); + System.out.println(" In locale = hr_HR..."); doTestDisplayNames(croatian, DLANG_HR, true); - logln(" In locale = el_GR..."); + System.out.println(" In locale = el_GR..."); doTestDisplayNames(greek, DLANG_EL, true); Locale.setDefault(saveDefault); @@ -309,14 +311,14 @@ private void doTestDisplayNames(Locale inLocale, int compareIndex, boolean defau String language = Locale.getDefault().getLanguage(); if (defaultIsFrench && !language.equals("fr")) { - errln("Default locale should be French, but it's really " + language); + fail("Default locale should be French, but it's really " + language); } else if (!defaultIsFrench && !language.equals("en")) { - errln("Default locale should be English, but it's really " + language); + fail("Default locale should be English, but it's really " + language); } for (int i = 0; i <= MAX_LOCALES; i++) { Locale testLocale = Locale.of(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); - logln(" Testing " + testLocale + "..."); + System.out.println(" Testing " + testLocale + "..."); String testLang; String testCtry; @@ -373,21 +375,22 @@ private void doTestDisplayNames(Locale inLocale, int compareIndex, boolean defau } if (!testLang.equals(expectedLang)) { - errln("Display language mismatch: " + testLang + " versus " + expectedLang); + fail("Display language mismatch: " + testLang + " versus " + expectedLang); } if (!testCtry.equals(expectedCtry)) { - errln("Display country mismatch: " + testCtry + " versus " + expectedCtry); + fail("Display country mismatch: " + testCtry + " versus " + expectedCtry); } if (!testVar.equals(expectedVar)) { - errln("Display variant mismatch: " + testVar + " versus " + expectedVar); + fail("Display variant mismatch: " + testVar + " versus " + expectedVar); } if (!testName.equals(expectedName)) { - errln("Display name mismatch: " + testName + " versus " + expectedName); + fail("Display name mismatch: " + testName + " versus " + expectedName); } } } @SuppressWarnings("deprecation") + @Test public void TestSimpleObjectStuff() { Locale test1 = new Locale("aa", "AA"); Locale test2 = new Locale("aa", "AA"); @@ -395,19 +398,19 @@ public void TestSimpleObjectStuff() { Locale test4 = Locale.of("zz", "ZZ"); if (test1 == test2 || test1 == test3 || test1 == test4 || test2 == test3) { - errln("Some of the test variables point to the same locale!"); + fail("Some of the test variables point to the same locale!"); } if (test3 == null) { - errln("clone() failed to produce a valid object!"); + fail("clone() failed to produce a valid object!"); } if (!test1.equals(test2) || !test1.equals(test3) || !test2.equals(test3)) { - errln("clone() or equals() failed: objects that should compare equal don't"); + fail("clone() or equals() failed: objects that should compare equal don't"); } if (test1.equals(test4) || test2.equals(test4) || test3.equals(test4)) { - errln("equals() failed: objects that shouldn't compare equal do"); + fail("equals() failed: objects that shouldn't compare equal do"); } int hash1 = test1.hashCode(); @@ -415,13 +418,14 @@ public void TestSimpleObjectStuff() { int hash3 = test3.hashCode(); if (hash1 != hash2 || hash1 != hash3 || hash2 != hash3) { - errln("hashCode() failed: objects that should have the same hash code don't"); + fail("hashCode() failed: objects that should have the same hash code don't"); } } /** * @bug 4011756 4011380 */ + @Test public void TestISO3Fallback() { Locale test = Locale.of("xx", "YY"); boolean gotException = false; @@ -433,7 +437,7 @@ public void TestISO3Fallback() { gotException = true; } if (!gotException) { - errln("getISO3Language() on xx_YY returned " + result + " instead of throwing an exception"); + fail("getISO3Language() on xx_YY returned " + result + " instead of throwing an exception"); } gotException = false; @@ -443,13 +447,14 @@ public void TestISO3Fallback() { gotException = true; } if (!gotException) { - errln("getISO3Country() on xx_YY returned " + result + " instead of throwing an exception"); + fail("getISO3Country() on xx_YY returned " + result + " instead of throwing an exception"); } } /** * @bug 4106155 4118587 7066203 7085757 */ + @Test public void TestGetLangsAndCountries() { // It didn't seem right to just do an exhaustive test of everything here, so I check // for the following things: @@ -464,7 +469,7 @@ public void TestGetLangsAndCountries() { "he", "id", "iu", "ug", "yi", "za"}; if (test.length != 188) { - errln("Expected getISOLanguages() to return 188 languages; it returned " + test.length); + fail("Expected getISOLanguages() to return 188 languages; it returned " + test.length); } else { for (int i = 0; i < spotCheck1.length; i++) { int j; @@ -474,19 +479,19 @@ public void TestGetLangsAndCountries() { } } if (j == test.length || !test[j].equals(spotCheck1[i])) { - errln("Couldn't find " + spotCheck1[i] + " in language list."); + fail("Couldn't find " + spotCheck1[i] + " in language list."); } } } for (int i = 0; i < test.length; i++) { if (!test[i].equals(test[i].toLowerCase())) { - errln(test[i] + " is not all lower case."); + fail(test[i] + " is not all lower case."); } if (test[i].length() != 2) { - errln(test[i] + " is not two characters long."); + fail(test[i] + " is not two characters long."); } if (i > 0 && test[i].compareTo(test[i - 1]) <= 0) { - errln(test[i] + " appears in an out-of-order position in the list."); + fail(test[i] + " appears in an out-of-order position in the list."); } } @@ -495,7 +500,7 @@ public void TestGetLangsAndCountries() { if (test.length != 249) { - errln("Expected getISOCountries to return 249 countries; it returned " + test.length); + fail("Expected getISOCountries to return 249 countries; it returned " + test.length); } else { for (int i = 0; i < spotCheck2.length; i++) { int j; @@ -505,19 +510,19 @@ public void TestGetLangsAndCountries() { } } if (j == test.length || !test[j].equals(spotCheck2[i])) { - errln("Couldn't find " + spotCheck2[i] + " in country list."); + fail("Couldn't find " + spotCheck2[i] + " in country list."); } } } for (int i = 0; i < test.length; i++) { if (!test[i].equals(test[i].toUpperCase())) { - errln(test[i] + " is not all upper case."); + fail(test[i] + " is not all upper case."); } if (test[i].length() != 2) { - errln(test[i] + " is not two characters long."); + fail(test[i] + " is not two characters long."); } if (i > 0 && test[i].compareTo(test[i - 1]) <= 0) { - errln(test[i] + " appears in an out-of-order position in the list."); + fail(test[i] + " appears in an out-of-order position in the list."); } } } @@ -532,28 +537,29 @@ void Test4126880() { test[0] = "SUCKER!!!"; test = Locale.getISOCountries(); if (test[0].equals("SUCKER!!!")) { - errln("Changed internal country code list!"); + fail("Changed internal country code list!"); } test = Locale.getISOLanguages(); test[0] = "HAHAHAHA!!!"; test = Locale.getISOLanguages(); if (test[0].equals("HAHAHAHA!!!")) { // Fixed typo - errln("Changes internal language code list!"); + fail("Changes internal language code list!"); } } /** * @bug 4107014 */ + @Test public void TestGetAvailableLocales() { Locale[] locales = Locale.getAvailableLocales(); if (locales == null || locales.length == 0) { - errln("Locale.getAvailableLocales() returned no installed locales!"); + fail("Locale.getAvailableLocales() returned no installed locales!"); } else { - logln("Locale.getAvailableLocales() returned a list of " + locales.length + " locales."); + System.out.println("Locale.getAvailableLocales() returned a list of " + locales.length + " locales."); for (int i = 0; i < locales.length; i++) { - logln(locales[i].toString()); + System.out.println(locales[i].toString()); } } } @@ -561,11 +567,12 @@ public void TestGetAvailableLocales() { /** * @bug 4135316 */ + @Test public void TestBug4135316() { Locale[] locales1 = Locale.getAvailableLocales(); Locale[] locales2 = Locale.getAvailableLocales(); if (locales1 == locales2) { - errln("Locale.getAvailableLocales() doesn't clone its internal storage!"); + fail("Locale.getAvailableLocales() doesn't clone its internal storage!"); } } @@ -574,27 +581,28 @@ public void TestBug4135316() { */ /* test commented out pending API-change approval + @Test public void TestGetLanguagesForCountry() { String[] languages = Locale.getLanguagesForCountry("US"); if (!searchStringArrayFor("en", languages)) - errln("Didn't get en as a language for US"); + fail("Didn't get en as a language for US"); languages = Locale.getLanguagesForCountry("FR"); if (!searchStringArrayFor("fr", languages)) - errln("Didn't get fr as a language for FR"); + fail("Didn't get fr as a language for FR"); languages = Locale.getLanguagesForCountry("CH"); if (!searchStringArrayFor("fr", languages)) - errln("Didn't get fr as a language for CH"); + fail("Didn't get fr as a language for CH"); if (!searchStringArrayFor("it", languages)) - errln("Didn't get it as a language for CH"); + fail("Didn't get it as a language for CH"); if (!searchStringArrayFor("de", languages)) - errln("Didn't get de as a language for CH"); + fail("Didn't get de as a language for CH"); languages = Locale.getLanguagesForCountry("JP"); if (!searchStringArrayFor("ja", languages)) - errln("Didn't get ja as a language for JP"); + fail("Didn't get ja as a language for JP"); } */ @@ -607,6 +615,7 @@ private boolean searchStringArrayFor(String s, String[] array) { /** * @bug 4110613 */ + @Test public void TestSerialization() throws ClassNotFoundException, OptionalDataException, IOException, StreamCorruptedException { ObjectOutputStream ostream; @@ -627,13 +636,14 @@ public void TestSerialization() throws ClassNotFoundException, OptionalDataExcep Locale test2 = (Locale) (istream.readObject()); if (!test1.equals(test2) || test1.hashCode() != test2.hashCode()) { - errln("Locale failed to deserialize correctly."); + fail("Locale failed to deserialize correctly."); } } /** * @bug 4118587 */ + @Test public void TestSimpleDisplayNames() { // This test is different from TestDisplayNames because TestDisplayNames checks // fallback behavior, combination of language and country names to form locale @@ -646,7 +656,7 @@ public void TestSimpleDisplayNames() { for (int i = 0; i < languageCodes.length; i++) { String test = (Locale.of(languageCodes[i])).getDisplayLanguage(Locale.US); if (!test.equals(languageNames[i])) { - errln("Got wrong display name for " + languageCodes[i] + ": Expected \"" + fail("Got wrong display name for " + languageCodes[i] + ": Expected \"" + languageNames[i] + "\", got \"" + test + "\"."); } } @@ -655,6 +665,7 @@ public void TestSimpleDisplayNames() { /** * @bug 4118595 */ + @Test public void TestUninstalledISO3Names() { // This test checks to make sure getISO3Language and getISO3Country work right // even for locales that are not installed. @@ -664,7 +675,7 @@ public void TestUninstalledISO3Names() { for (int i = 0; i < iso2Languages.length; i++) { String test = (Locale.of(iso2Languages[i])).getISO3Language(); if (!test.equals(iso3Languages[i])) { - errln("Got wrong ISO3 code for " + iso2Languages[i] + ": Expected \"" + fail("Got wrong ISO3 code for " + iso2Languages[i] + ": Expected \"" + iso3Languages[i] + "\", got \"" + test + "\"."); } } @@ -675,7 +686,7 @@ public void TestUninstalledISO3Names() { for (int i = 0; i < iso2Countries.length; i++) { String test = (Locale.of("", iso2Countries[i])).getISO3Country(); if (!test.equals(iso3Countries[i])) { - errln("Got wrong ISO3 code for " + iso2Countries[i] + ": Expected \"" + fail("Got wrong ISO3 code for " + iso2Countries[i] + ": Expected \"" + iso3Countries[i] + "\", got \"" + test + "\"."); } } @@ -684,6 +695,7 @@ public void TestUninstalledISO3Names() { /** * @bug 4052404 4778440 8263202 */ + @Test public void TestChangedISO639Codes() { Locale hebrewOld = Locale.of("iw", "IL"); Locale hebrewNew = Locale.of("he", "IL"); @@ -694,28 +706,28 @@ public void TestChangedISO639Codes() { if ("true".equalsIgnoreCase(System.getProperty("java.locale.useOldISOCodes"))) { if (!hebrewNew.getLanguage().equals("iw")) { - errln("Got back wrong language code for new Hebrew: expected \"iw\", got \"" + fail("Got back wrong language code for new Hebrew: expected \"iw\", got \"" + hebrewNew.getLanguage() + "\""); } if (!yiddishNew.getLanguage().equals("ji")) { - errln("Got back wrong language code for new Yiddish: expected \"ji\", got \"" + fail("Got back wrong language code for new Yiddish: expected \"ji\", got \"" + yiddishNew.getLanguage() + "\""); } if (!indonesianNew.getLanguage().equals("in")) { - errln("Got back wrong language code for new Indonesian: expected \"in\", got \"" + fail("Got back wrong language code for new Indonesian: expected \"in\", got \"" + indonesianNew.getLanguage() + "\""); } } else { if (!hebrewOld.getLanguage().equals("he")) { - errln("Got back wrong language code for old Hebrew: expected \"he\", got \"" + fail("Got back wrong language code for old Hebrew: expected \"he\", got \"" + hebrewNew.getLanguage() + "\""); } if (!yiddishOld.getLanguage().equals("yi")) { - errln("Got back wrong language code for old Yiddish: expected \"yi\", got \"" + fail("Got back wrong language code for old Yiddish: expected \"yi\", got \"" + yiddishNew.getLanguage() + "\""); } if (!indonesianOld.getLanguage().equals("id")) { - errln("Got back wrong language code for old Indonesian: expected \"id\", got \"" + fail("Got back wrong language code for old Indonesian: expected \"id\", got \"" + indonesianNew.getLanguage() + "\""); } } @@ -739,6 +751,7 @@ public void TestChangedISO639Codes() { * 1999-11-19 joconner * */ + @Test public void TestAtypicalLocales() { Locale[] localesToTest = { Locale.of("de", "CA"), Locale.of("ja", "ZA"), @@ -784,27 +797,27 @@ public void TestAtypicalLocales() { for (int i = 0; i < localesToTest.length; i++) { String name = localesToTest[i].getDisplayName(Locale.US); - logln(name); + System.out.println(name); if (!name.equals(englishDisplayNames[i])) { - errln("Lookup in English failed: expected \"" + englishDisplayNames[i] + fail("Lookup in English failed: expected \"" + englishDisplayNames[i] + "\", got \"" + name + "\""); } } for (int i = 0; i < localesToTest.length; i++) { String name = localesToTest[i].getDisplayName(Locale.of("es", "ES")); - logln(name); + System.out.println(name); if (!name.equals(spanishDisplayNames[i])) { - errln("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i] + fail("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i] + "\", got \"" + name + "\""); } } for (int i = 0; i < localesToTest.length; i++) { String name = localesToTest[i].getDisplayName(Locale.FRANCE); - logln(name); + System.out.println(name); if (!name.equals(frenchDisplayNames[i])) { - errln("Lookup in French failed: expected \"" + frenchDisplayNames[i] + fail("Lookup in French failed: expected \"" + frenchDisplayNames[i] + "\", got \"" + name + "\""); } } @@ -816,6 +829,7 @@ public void TestAtypicalLocales() { /** * @bug 4126371 */ + @Test public void TestNullDefault() { // why on earth anyone would ever try to do this is beyond me, but we should // definitely make sure we don't let them @@ -827,10 +841,10 @@ public void TestNullDefault() { gotException = true; } if (Locale.getDefault() == null) { - errln("Locale.getDefault() allowed us to set default to NULL!"); + fail("Locale.getDefault() allowed us to set default to NULL!"); } if (!gotException) { - errln("Trying to set default locale to NULL didn't throw exception!"); + fail("Trying to set default locale to NULL didn't throw exception!"); } } @@ -839,15 +853,16 @@ public void TestNullDefault() { * This would be better tested by the LocaleDataTest. Will move it when I * get the LocaleDataTest working again. */ + @Test public void TestThaiCurrencyFormat() { DecimalFormat thaiCurrency = (DecimalFormat) NumberFormat.getCurrencyInstance( Locale.of("th", "TH")); if (!thaiCurrency.getPositivePrefix().equals("\u0e3f")) { - errln("Thai currency prefix wrong: expected \"\u0e3f\", got \"" + fail("Thai currency prefix wrong: expected \"\u0e3f\", got \"" + thaiCurrency.getPositivePrefix() + "\""); } if (!thaiCurrency.getPositiveSuffix().equals("")) { - errln("Thai currency suffix wrong: expected \"\", got \"" + fail("Thai currency suffix wrong: expected \"\", got \"" + thaiCurrency.getPositiveSuffix() + "\""); } } @@ -865,6 +880,7 @@ public void TestThaiCurrencyFormat() { * DON'T ASSUME: Any specific countries support the Euro. Instead, * iterate through all locales. */ + @Test public void TestEuroSupport() { final String EURO_VARIANT = "EURO"; final String EURO_CURRENCY = "\u20AC"; // Look for this string in formatted Euro currency @@ -878,10 +894,10 @@ public void TestEuroSupport() { String neg = nf.format(-271828.182845); if (pos.indexOf(EURO_CURRENCY) >= 0 && neg.indexOf(EURO_CURRENCY) >= 0) { - logln("Ok: " + loc.toString() + System.out.println("Ok: " + loc.toString() + ": " + pos + " / " + neg); } else { - errln("Fail: " + loc.toString() + fail("Fail: " + loc.toString() + " formats without " + EURO_CURRENCY + ": " + pos + " / " + neg + "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***"); @@ -894,6 +910,7 @@ public void TestEuroSupport() { * @bug 4139504 * toString() doesn't work with language_VARIANT. */ + @Test public void TestToString() { Object[] DATA = { Locale.of("xx", "", ""), "xx", @@ -908,7 +925,7 @@ public void TestToString() { Locale loc = (Locale) DATA[i]; String fmt = (String) DATA[i + 1]; if (!loc.toString().equals(fmt)) { - errln("Fail: Locale.toString(" + fmt + ")=>" + loc); + fail("Fail: Locale.toString(" + fmt + ")=>" + loc); } } } @@ -918,6 +935,7 @@ public void TestToString() { * Currency symbol in zh is wrong. We will test this at the NumberFormat * end to test the whole pipe. */ + @Test public void Test4105828() { Locale[] LOC = {Locale.CHINESE, Locale.of("zh", "CN"), Locale.of("zh", "TW"), Locale.of("zh", "HK")}; @@ -925,7 +943,7 @@ public void Test4105828() { NumberFormat fmt = NumberFormat.getPercentInstance(LOC[i]); String result = fmt.format(1); if (!result.equals("100%")) { - errln("Percent for " + LOC[i] + " should be 100%, got " + result); + fail("Percent for " + LOC[i] + " should be 100%, got " + result); } } } @@ -946,6 +964,7 @@ public void Test4105828() { * is that something is wrong with the font mapping subsystem, but we can't * test that here. */ + @Test public void Test4139940() { Locale mylocale = Locale.of("hu"); @SuppressWarnings("deprecation") @@ -955,7 +974,7 @@ public void Test4139940() { // Make sure that o circumflex (\u00F4) is NOT there, and // o double acute (\u0151) IS. if (str.indexOf('\u0151') < 0 || str.indexOf('\u00F4') >= 0) { - errln("Fail: Monday in Hungarian is wrong"); + fail("Fail: Monday in Hungarian is wrong"); } } @@ -963,10 +982,11 @@ public void Test4139940() { * @bug 4143951 * Russian first day of week should be Monday. Confirmed. */ + @Test public void Test4143951() { Calendar cal = Calendar.getInstance(Locale.of("ru")); if (cal.getFirstDayOfWeek() != Calendar.MONDAY) { - errln("Fail: First day of week in Russia should be Monday"); + fail("Fail: First day of week in Russia should be Monday"); } } @@ -975,6 +995,7 @@ public void Test4143951() { * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes. * Should throw an exception for unknown locales */ + @Test public void Test4147315() { // Try with codes that are the wrong length but happen to match text // at a valid offset in the mapping table @@ -983,7 +1004,7 @@ public void Test4147315() { try { String result = locale.getISO3Country(); - errln("ERROR: getISO3Country() returns: " + result + fail("ERROR: getISO3Country() returns: " + result + " for locale '" + locale + "' rather than exception"); } catch (MissingResourceException e) { } @@ -995,6 +1016,7 @@ public void Test4147315() { * Should throw an exception for unknown locales, except they have three * letter language codes. */ + @Test public void Test4147317() { // Try a three letter language code, and check whether it is // returned as is. @@ -1002,7 +1024,7 @@ public void Test4147317() { String result = locale.getISO3Language(); if (!result.equals("aaa")) { - errln("ERROR: getISO3Language() returns: " + result + fail("ERROR: getISO3Language() returns: " + result + " for locale '" + locale + "' rather than returning it as is"); } @@ -1013,7 +1035,7 @@ public void Test4147317() { try { result = locale.getISO3Language(); - errln("ERROR: getISO3Language() returns: " + result + fail("ERROR: getISO3Language() returns: " + result + " for locale '" + locale + "' rather than exception"); } catch (MissingResourceException e) { } @@ -1022,6 +1044,7 @@ public void Test4147317() { /* * @bug 4147552 4778440 8030696 */ + @Test public void Test4147552() { Locale[] locales = {Locale.of("no", "NO"), Locale.of("no", "NO", "B"), Locale.of("no", "NO", "NY"), Locale.of("nb", "NO"), @@ -1038,11 +1061,11 @@ public void Test4147552() { for (int i = 0; i < locales.length; i++) { Locale loc = locales[i]; if (!loc.getDisplayName(Locale.US).equals(englishDisplayNames[i])) { - errln("English display-name mismatch: expected " + fail("English display-name mismatch: expected " + englishDisplayNames[i] + ", got " + loc.getDisplayName()); } if (!loc.getDisplayName(loc).equals(norwegianDisplayNames[i])) { - errln("Norwegian display-name mismatch: expected " + fail("Norwegian display-name mismatch: expected " + norwegianDisplayNames[i] + ", got " + loc.getDisplayName(loc)); } @@ -1052,11 +1075,12 @@ public void Test4147552() { /* * @bug 8030696 */ + @Test public void Test8030696() { List av = Arrays.asList(Locale.getAvailableLocales()); if (!av.contains(Locale.of("nb", "NO")) || !av.contains(Locale.of("nn", "NO"))) { - errln("\"nb-NO\" and/or \"nn-NO\" locale(s) not returned from getAvailableLocales()."); + fail("\"nb-NO\" and/or \"nn-NO\" locale(s) not returned from getAvailableLocales()."); } } diff --git a/test/jdk/java/util/TimeZone/Bug4322313.java b/test/jdk/java/util/TimeZone/Bug4322313.java index a65a87149b9..d3c87b50595 100644 --- a/test/jdk/java/util/TimeZone/Bug4322313.java +++ b/test/jdk/java/util/TimeZone/Bug4322313.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -27,14 +27,18 @@ * @summary Make sure that new implementation of custom time zone * support for TimeZone.getTimeZone() works correctly and the * getDisplayName() methods are locale independent. - * @library /java/text/testlib + * @run junit Bug4322313 */ import java.io.*; import java.text.*; import java.util.*; -public class Bug4322313 extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class Bug4322313 { private static final int MPM = 60 * 1000; /* Milliseconds per minute */ private static final Object[][] VALIDS = { /* given ID rawOffset normalized ID */ @@ -106,7 +110,7 @@ void Test4322313() { "\"] Invalid TimeZone ID, expected:" + VALIDS[k][2] + ", got:" + tz.getID() + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + VALIDS[k][0] + "\"] Valid TimeZone ID, got:" + VALIDS[k][2]); } @@ -119,7 +123,7 @@ void Test4322313() { "\"] Invalid RawOffset, expected:" + VALIDS[k][1] + ", got:" + offset + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + VALIDS[k][0] + "\"] Vaild RawOffset, got:" + offset); } @@ -132,7 +136,7 @@ void Test4322313() { "\"] DSTSavings should be zero, got:" + offset + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + VALIDS[k][0] + "\"] DSTSavings is zero."); } @@ -150,7 +154,7 @@ void Test4322313() { "\"] Invalid TimeZone ID, expected:GMT, got:" + tz.getID() + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + INVALIDS[k] + "\"] Valid TimeZone ID, got:" + tz.getID()); } @@ -163,7 +167,7 @@ void Test4322313() { "\"] RawOffset should be zero, got:" + offset + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + INVALIDS[k] + "\"] RawOffset is zero."); } @@ -176,7 +180,7 @@ void Test4322313() { "\"] DSTSavings should be zero, got:" + offset + ", " + tz); } else { - logln("\tPassed [Locale=" + + System.out.println("\tPassed [Locale=" + locale + ", \"" + INVALIDS[k] + "\"] DSTSavings is zero."); } @@ -218,13 +222,10 @@ void Test4322313() { TimeZone.setDefault(savedTimeZone); } if (err) { - errln("TimeZone.getTimeZone() test failed"); + fail("TimeZone.getTimeZone() test failed"); } else { - logln("TimeZone.getTimeZone() test passed"); + System.out.println("TimeZone.getTimeZone() test passed"); } } - public static void main (String[] args) throws Exception { - new Bug4322313().run(args); - } } diff --git a/test/jdk/java/util/TimeZone/Bug6329116.java b/test/jdk/java/util/TimeZone/Bug6329116.java index 32105881194..6e85fe8cb5b 100644 --- a/test/jdk/java/util/TimeZone/Bug6329116.java +++ b/test/jdk/java/util/TimeZone/Bug6329116.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -27,27 +27,24 @@ * 7039469 7090843 7103108 7103405 7158483 8008577 8059206 8064560 8072042 * 8077685 8151876 8166875 8169191 8170316 8176044 * @summary Make sure that timezone short display names are idenical to Olson's data. - * @library /java/text/testlib - * @build Bug6329116 TextFileReader - * @run main/othervm -Djava.locale.providers=COMPAT,SPI Bug6329116 + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI Bug6329116 */ import java.io.*; import java.text.*; import java.util.*; -public class Bug6329116 extends IntlTest { +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class Bug6329116 { static Locale[] locales = Locale.getAvailableLocales(); static String[] timezones = TimeZone.getAvailableIDs(); - public static void main(String[] args) throws IOException { - if (bug6329116()) { - throw new RuntimeException("At least one timezone display name is incorrect."); - } - } - - static boolean bug6329116() throws IOException { + @Test + public void bug6329116() throws IOException { boolean err = false; HashMap aliasTable = new HashMap<>(); @@ -200,7 +197,9 @@ static boolean bug6329116() throws IOException { } } - return err; + if (err) { + fail("At least one timezone display name is incorrect."); + } } static boolean useLocalzedShortDisplayName(TimeZone tz, diff --git a/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java b/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java index a1d44ea080d..c70ccc204de 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java +++ b/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,18 +23,26 @@ /* * @test - * @library /java/text/testlib * @summary test Time Zone Boundary + * @run junit TimeZoneBoundaryTest */ -import java.text.*; -import java.util.*; +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.SimpleTimeZone; +import java.util.TimeZone; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; /** * A test which discovers the boundaries of DST programmatically and verifies * that they are correct. */ -public class TimeZoneBoundaryTest extends IntlTest +public class TimeZoneBoundaryTest { static final int ONE_SECOND = 1000; static final int ONE_MINUTE = 60*ONE_SECOND; @@ -57,10 +65,6 @@ public class TimeZoneBoundaryTest extends IntlTest static final long AUSTRALIA_1997_BEG = 877797000000L; static final long AUSTRALIA_1997_END = 859653000000L; - public static void main(String[] args) throws Exception { - new TimeZoneBoundaryTest().run(args); - } - /** * Date.toString().substring() Boundary Test * Look for a DST changeover to occur within 6 months of the given Date. @@ -75,7 +79,7 @@ void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBounda if (d.toString().indexOf(startMode) == -1) { - logln("Error: " + startMode + " not present in " + d); + System.out.println("Error: " + startMode + " not present in " + d); } // Use a binary search, assuming that we have a Standard @@ -98,15 +102,15 @@ void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBounda } } - logln("Date Before: " + showDate(min)); - logln("Date After: " + showDate(max)); + System.out.println("Date Before: " + showDate(min)); + System.out.println("Date After: " + showDate(max)); long mindelta = expectedBoundary - min; long maxdelta = max - expectedBoundary; if (mindelta >= 0 && mindelta <= INTERVAL && mindelta >= 0 && mindelta <= INTERVAL) - logln("PASS: Expected boundary at " + expectedBoundary); + System.out.println("PASS: Expected boundary at " + expectedBoundary); else - errln("FAIL: Expected boundary at " + expectedBoundary); + fail("FAIL: Expected boundary at " + expectedBoundary); } void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary) @@ -128,14 +132,14 @@ void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, if (tz.inDaylightTime(d) != startsInDST) { - errln("FAIL: " + tz.getID() + " inDaylightTime(" + + fail("FAIL: " + tz.getID() + " inDaylightTime(" + d + ") != " + startsInDST); startsInDST = !startsInDST; // Flip over; find the apparent value } if (tz.inDaylightTime(new Date(max)) == startsInDST) { - errln("FAIL: " + tz.getID() + " inDaylightTime(" + + fail("FAIL: " + tz.getID() + " inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST)); return; } @@ -154,16 +158,16 @@ void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, } } - logln(tz.getID() + " Before: " + showDate(min, tz)); - logln(tz.getID() + " After: " + showDate(max, tz)); + System.out.println(tz.getID() + " Before: " + showDate(min, tz)); + System.out.println(tz.getID() + " After: " + showDate(max, tz)); long mindelta = expectedBoundary - min; long maxdelta = max - expectedBoundary; if (mindelta >= 0 && mindelta <= INTERVAL && mindelta >= 0 && mindelta <= INTERVAL) - logln("PASS: Expected boundary at " + expectedBoundary); + System.out.println("PASS: Expected boundary at " + expectedBoundary); else - errln("FAIL: Expected boundary at " + expectedBoundary); + fail("FAIL: Expected boundary at " + expectedBoundary); } private static String showDate(long l) @@ -209,23 +213,23 @@ void verifyDST(Date d, TimeZone time_zone, boolean expUseDaylightTime, boolean expInDaylightTime, int expZoneOffset, int expDSTOffset) { - logln("-- Verifying time " + d + + System.out.println("-- Verifying time " + d + " in zone " + time_zone.getID()); if (time_zone.inDaylightTime(d) == expInDaylightTime) - logln("PASS: inDaylightTime = " + time_zone.inDaylightTime(d)); + System.out.println("PASS: inDaylightTime = " + time_zone.inDaylightTime(d)); else - errln("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d)); + fail("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d)); if (time_zone.useDaylightTime() == expUseDaylightTime) - logln("PASS: useDaylightTime = " + time_zone.useDaylightTime()); + System.out.println("PASS: useDaylightTime = " + time_zone.useDaylightTime()); else - errln("FAIL: useDaylightTime = " + time_zone.useDaylightTime()); + fail("FAIL: useDaylightTime = " + time_zone.useDaylightTime()); if (time_zone.getRawOffset() == expZoneOffset) - logln("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR); + System.out.println("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR); else - errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR + + fail("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR + "; expected " + expZoneOffset/(double)ONE_HOUR); GregorianCalendar gc = new GregorianCalendar(time_zone); @@ -237,13 +241,14 @@ void verifyDST(Date d, TimeZone time_zone, gc.get(gc.SECOND)) * 1000 + gc.get(gc.MILLISECOND)); if (offset == expDSTOffset) - logln("PASS: getOffset() = " + offset/(double)ONE_HOUR); + System.out.println("PASS: getOffset() = " + offset/(double)ONE_HOUR); else - errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR + + fail("FAIL: getOffset() = " + offset/(double)ONE_HOUR + "; expected " + expDSTOffset/(double)ONE_HOUR); } @SuppressWarnings("deprecation") + @Test public void TestBoundaries() { TimeZone pst = TimeZone.getTimeZone("PST"); @@ -263,19 +268,19 @@ public void TestBoundaries() inDST ? -7*ONE_HOUR : -8*ONE_HOUR); } - logln("========================================"); + System.out.println("========================================"); findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG); - logln("========================================"); + System.out.println("========================================"); findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END); // Southern hemisphere test - logln("========================================"); + System.out.println("========================================"); TimeZone z = TimeZone.getTimeZone(AUSTRALIA); findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z); - logln("========================================"); + System.out.println("========================================"); findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG); - logln("========================================"); + System.out.println("========================================"); findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END); } finally { TimeZone.setDefault(save); @@ -297,7 +302,7 @@ void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary) if (tz.inDaylightTime(new Date(max)) == startsInDST) { - logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST)); + System.out.println("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST)); } while ((max - min) > INTERVAL) @@ -313,121 +318,50 @@ void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary) } } - logln("Binary Search Before: " + showDate(min)); - logln("Binary Search After: " + showDate(max)); + System.out.println("Binary Search Before: " + showDate(min)); + System.out.println("Binary Search After: " + showDate(max)); long mindelta = expectedBoundary - min; long maxdelta = max - expectedBoundary; if (mindelta >= 0 && mindelta <= INTERVAL && mindelta >= 0 && mindelta <= INTERVAL) - logln("PASS: Expected boundary at " + expectedBoundary); + System.out.println("PASS: Expected boundary at " + expectedBoundary); else - errln("FAIL: Expected boundary at " + expectedBoundary); + fail("FAIL: Expected boundary at " + expectedBoundary); } - /* - static void testUsingMillis(Date d, boolean startsInDST) - { - long millis = d.getTime(); - long max = millis + (long)(370 * ONE_DAY); // A year plus extra - - boolean lastDST = startsInDST; - while (millis < max) - { - cal.setTime(new Date(millis)); - boolean inDaylight = cal.inDaylightTime(); - - if (inDaylight != lastDST) - { - logln("Switch " + (inDaylight ? "into" : "out of") - + " DST at " + (new Date(millis))); - lastDST = inDaylight; - } - - millis += 15*ONE_MINUTE; - } - } - */ - /** * Test new rule formats. */ @SuppressWarnings("deprecation") - public void TestNewRules() - { - //logln(Locale.getDefault().getDisplayName()); - //logln(TimeZone.getDefault().getID()); - //logln(new Date(0)); - - if (true) - { - // Doesn't matter what the default TimeZone is here, since we - // are creating our own TimeZone objects. - - SimpleTimeZone tz; - - logln("-----------------------------------------------------------------"); - logln("Aug 2ndTues .. Mar 15"); - tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1", - Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR, - Calendar.MARCH, 15, 0, 2*ONE_HOUR); - //logln(tz.toString()); - logln("========================================"); - testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L); - logln("========================================"); - testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L); - - logln("-----------------------------------------------------------------"); - logln("Apr Wed>=14 .. Sep Sun<=20"); - tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2", - Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR, - Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR); - //logln(tz.toString()); - logln("========================================"); - testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L); - logln("========================================"); - testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L); - } - - /* - if (true) - { - logln("========================================"); - logln("Stepping using millis"); - testUsingMillis(new Date(97,0,1), false); - } - - if (true) - { - logln("========================================"); - logln("Stepping using fields"); - testUsingFields(1997, false); - } - - if (false) - { - cal.clear(); - cal.set(1997, 3, 5, 10, 0); - // cal.inDaylightTime(); - logln("Date = " + cal.getTime()); - logln("Millis = " + cal.getTime().getTime()/3600000); - } - */ + @Test + public void TestNewRules() { + // Doesn't matter what the default TimeZone is here, since we + // are creating our own TimeZone objects. + + SimpleTimeZone tz; + + System.out.println("-----------------------------------------------------------------"); + System.out.println("Aug 2ndTues .. Mar 15"); + tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1", + Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR, + Calendar.MARCH, 15, 0, 2*ONE_HOUR); + System.out.println("========================================"); + testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L); + System.out.println("========================================"); + testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L); + + System.out.println("-----------------------------------------------------------------"); + System.out.println("Apr Wed>=14 .. Sep Sun<=20"); + tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2", + Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR, + Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR); + System.out.println("========================================"); + testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L); + System.out.println("========================================"); + testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L); } - //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - // Long Bug - //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - //---------------------------------------------------------------------- - - //public void Test3() - //{ - // findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true); - //} - /** * Find boundaries by stepping. */ @@ -439,15 +373,15 @@ void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedCha long limit = time + ONE_YEAR + ONE_DAY; boolean lastState = z.inDaylightTime(d); int changes = 0; - logln("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState); - logln("useDaylightTime = " + z.useDaylightTime()); + System.out.println("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState); + System.out.println("useDaylightTime = " + z.useDaylightTime()); while (time < limit) { d.setTime(time); boolean state = z.inDaylightTime(d); if (state != lastState) { - logln((state ? "Entry " : "Exit ") + + System.out.println((state ? "Entry " : "Exit ") + "at " + d); lastState = state; ++changes; @@ -456,23 +390,24 @@ void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedCha } if (changes == 0) { - if (!lastState && !z.useDaylightTime()) logln("No DST"); - else errln("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime"); + if (!lastState && !z.useDaylightTime()) System.out.println("No DST"); + else fail("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime"); } else if (changes != 2) { - errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2"); + fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2"); } else if (!z.useDaylightTime()) { - errln("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen"); + fail("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen"); } if (changes != expectedChanges) { - errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges); + fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges); } } + @Test public void TestStepwise() { findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0); diff --git a/test/jdk/java/util/TimeZone/TimeZoneRegression.java b/test/jdk/java/util/TimeZone/TimeZoneRegression.java index 3dabbe49119..6343279689f 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneRegression.java +++ b/test/jdk/java/util/TimeZone/TimeZoneRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -27,42 +27,44 @@ * 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960 * 4966229 6433179 6851214 8007520 8008577 * @library /java/text/testlib - * @run main/othervm -Djava.locale.providers=COMPAT,SPI TimeZoneRegression + * @run junit/othervm -Djava.locale.providers=COMPAT,SPI TimeZoneRegression */ import java.util.*; import java.io.*; import java.text.*; -public class TimeZoneRegression extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new TimeZoneRegression().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class TimeZoneRegression { + @Test public void Test4073209() { TimeZone z1 = TimeZone.getTimeZone("PST"); TimeZone z2 = TimeZone.getTimeZone("PST"); if (z1 == z2) { - errln("Fail: TimeZone should return clones"); + fail("Fail: TimeZone should return clones"); } } @SuppressWarnings("deprecation") + @Test public void Test4073215() { SimpleTimeZone z = new SimpleTimeZone(0, "GMT"); if (z.useDaylightTime()) { - errln("Fail: Fix test to start with non-DST zone"); + fail("Fail: Fix test to start with non-DST zone"); } z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0); z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0); if (!z.useDaylightTime()) { - errln("Fail: DST not active"); + fail("Fail: DST not active"); } if (z.inDaylightTime(new Date(97, Calendar.JANUARY, 31)) || !z.inDaylightTime(new Date(97, Calendar.MARCH, 1)) || z.inDaylightTime(new Date(97, Calendar.MARCH, 31))) { - errln("Fail: DST not working as expected"); + fail("Fail: DST not working as expected"); } } @@ -74,6 +76,7 @@ public void Test4073215() { * day of end 0:59 AM STD = display name 1:59 AM DT * 1:00 AM STD = display name 1:00 AM ST */ + @Test public void Test4084933() { // test both SimpleTimeZone and ZoneInfo objects. // @since 1.4 @@ -113,10 +116,11 @@ private void sub4084933(TimeZone tz) { offset3 != SToffset || offset4 != DToffset || offset5 != DToffset || offset6 != SToffset || offset7 != SToffset || offset8 != SToffset) - errln("Fail: TimeZone misbehaving"); { + fail("Fail: TimeZone misbehaving"); { } } + @Test public void Test4096952() { String[] ZONES = { "GMT", "MET", "IST" }; boolean pass = true; @@ -124,7 +128,7 @@ public void Test4096952() { for (int i=0; i max) max = ids.length; - logln(hname + ' ' + ids.length + + System.out.println(hname + ' ' + ids.length + ((ids.length > 0) ? (" e.g. " + ids[0]) : "")); } catch (Exception e) { - errln(hname + ' ' + "Fail: " + e); + fail(hname + ' ' + "Fail: " + e); } } - logln("Maximum zones per offset = " + max); + System.out.println("Maximum zones per offset = " + max); } + @Test public void Test4151429() { try { TimeZone tz = TimeZone.getTimeZone("GMT"); String name = tz.getDisplayName(true, Integer.MAX_VALUE, Locale.getDefault()); - errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()"); + fail("IllegalArgumentException not thrown by TimeZone.getDisplayName()"); } catch(IllegalArgumentException e) {} } @@ -373,6 +381,7 @@ public void Test4151429() { * SimpleTimeZone accepts illegal DST savings values. These values * must be non-zero. There is no upper limit at this time. */ + @Test public void Test4154525() { final int GOOD = 1, BAD = 0; int[] DATA = { @@ -404,15 +413,15 @@ public void Test4154525() { break; } if (valid) { - logln("Pass: DST savings of " + savings + " accepted by " + method); + System.out.println("Pass: DST savings of " + savings + " accepted by " + method); } else { - errln("Fail: DST savings of " + savings + " accepted by " + method); + fail("Fail: DST savings of " + savings + " accepted by " + method); } } catch (IllegalArgumentException e) { if (valid) { - errln("Fail: DST savings of " + savings + " to " + method + " gave " + e); + fail("Fail: DST savings of " + savings + " to " + method + " gave " + e); } else { - logln("Pass: DST savings of " + savings + " to " + method + " gave " + e); + System.out.println("Pass: DST savings of " + savings + " to " + method + " gave " + e); } } } @@ -423,6 +432,7 @@ public void Test4154525() { * SimpleTimeZone.hasSameRules() doesn't work for zones with no DST * and different DST parameters. */ + @Test public void Test4154537() { // tz1 and tz2 have no DST and different rule parameters SimpleTimeZone tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0); @@ -435,15 +445,15 @@ public void Test4154537() { if (tz1.useDaylightTime() || tz2.useDaylightTime() || !tza.useDaylightTime() || !tzA.useDaylightTime() || !tzb.useDaylightTime()) { - errln("Test is broken -- rewrite it"); + fail("Test is broken -- rewrite it"); } if (!tza.hasSameRules(tzA) || tza.hasSameRules(tzb)) { - errln("Fail: hasSameRules() broken for zones with rules"); + fail("Fail: hasSameRules() broken for zones with rules"); } if (!tz1.hasSameRules(tz2)) { - errln("Fail: hasSameRules() returns false for zones without rules"); - errln("zone 1 = " + tz1); - errln("zone 2 = " + tz2); + fail("Fail: hasSameRules() returns false for zones without rules"); + fail("zone 1 = " + tz1); + fail("zone 2 = " + tz2); } } @@ -451,6 +461,7 @@ public void Test4154537() { * SimpleTimeZone constructors, setStartRule(), and setEndRule() don't * check for out-of-range arguments. */ + @Test public void Test4154542() { final int GOOD = 1; final int BAD = 0; @@ -496,7 +507,7 @@ public void Test4154542() { ex = e; } if ((ex == null) != shouldBeGood) { - errln("setStartRule(month=" + month + ", day=" + day + + fail("setStartRule(month=" + month + ", day=" + day + ", dayOfWeek=" + dayOfWeek + ", time=" + time + (shouldBeGood ? (") should work but throws " + ex) : ") should fail but doesn't")); @@ -509,7 +520,7 @@ public void Test4154542() { ex = e; } if ((ex == null) != shouldBeGood) { - errln("setEndRule(month=" + month + ", day=" + day + + fail("setEndRule(month=" + month + ", day=" + day + ", dayOfWeek=" + dayOfWeek + ", time=" + time + (shouldBeGood ? (") should work but throws " + ex) : ") should fail but doesn't")); @@ -524,7 +535,7 @@ public void Test4154542() { ex = e; } if ((ex == null) != shouldBeGood) { - errln("SimpleTimeZone(month=" + month + ", day=" + day + + fail("SimpleTimeZone(month=" + month + ", day=" + day + ", dayOfWeek=" + dayOfWeek + ", time=" + time + (shouldBeGood ? (", ) should work but throws " + ex) : ", ) should fail but doesn't")); @@ -539,7 +550,7 @@ public void Test4154542() { ex = e; } if ((ex == null) != shouldBeGood) { - errln("SimpleTimeZone(, month=" + month + ", day=" + day + + fail("SimpleTimeZone(, month=" + month + ", day=" + day + ", dayOfWeek=" + dayOfWeek + ", time=" + time + (shouldBeGood ? (") should work but throws " + ex) : ") should fail but doesn't")); @@ -550,6 +561,7 @@ public void Test4154542() { /** * SimpleTimeZone.getOffset accepts illegal arguments. */ + @Test public void Test4154650() { final int GOOD=1, BAD=0; final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST; @@ -594,7 +606,7 @@ public void Test4154650() { e = ex; } if (good != (e == null)) { - errln("Fail: getOffset(" + + fail("Fail: getOffset(" + DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " + DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] + (good ? (") threw " + e) : ") accepts invalid args")); @@ -605,6 +617,7 @@ public void Test4154650() { /** * TimeZone constructors allow null IDs. */ + @Test public void Test4159922() { TimeZone z = null; @@ -612,38 +625,38 @@ public void Test4159922() { // allow null. try { z = TimeZone.getTimeZone((String)null); - errln("FAIL: Null allowed in getTimeZone"); + fail("FAIL: Null allowed in getTimeZone"); } catch (NullPointerException e) {} z = TimeZone.getTimeZone("GMT"); try { z.getDisplayName(false, TimeZone.SHORT, null); - errln("FAIL: Null allowed in getDisplayName(3)"); + fail("FAIL: Null allowed in getDisplayName(3)"); } catch (NullPointerException e) {} try { z.getDisplayName(null); - errln("FAIL: Null allowed in getDisplayName(1)"); + fail("FAIL: Null allowed in getDisplayName(1)"); } catch (NullPointerException e) {} try { if (z.hasSameRules(null)) { - errln("FAIL: hasSameRules returned true"); + fail("FAIL: hasSameRules returned true"); } } catch (NullPointerException e) { - errln("FAIL: Null NOT allowed in hasSameRules"); + fail("FAIL: Null NOT allowed in hasSameRules"); } try { z.inDaylightTime(null); - errln("FAIL: Null allowed in inDaylightTime"); + fail("FAIL: Null allowed in inDaylightTime"); } catch (NullPointerException e) {} try { z.setID(null); - errln("FAIL: Null allowed in setID"); + fail("FAIL: Null allowed in setID"); } catch (NullPointerException e) {} TimeZone save = TimeZone.getDefault(); try { TimeZone.setDefault(null); } catch (NullPointerException e) { - errln("FAIL: Null NOT allowed in setDefault"); + fail("FAIL: Null NOT allowed in setDefault"); } finally { TimeZone.setDefault(save); } @@ -652,15 +665,15 @@ public void Test4159922() { SimpleTimeZone s = null; try { s = new SimpleTimeZone(0, null); - errln("FAIL: Null allowed in SimpleTimeZone(2)"); + fail("FAIL: Null allowed in SimpleTimeZone(2)"); } catch (NullPointerException e) {} try { s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0); - errln("FAIL: Null allowed in SimpleTimeZone(10)"); + fail("FAIL: Null allowed in SimpleTimeZone(10)"); } catch (NullPointerException e) {} try { s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0, 1000); - errln("FAIL: Null allowed in SimpleTimeZone(11)"); + fail("FAIL: Null allowed in SimpleTimeZone(11)"); } catch (NullPointerException e) {} } @@ -669,6 +682,7 @@ public void Test4159922() { * transitions at midnight correctly. */ @SuppressWarnings("deprecation") + @Test public void Test4162593() { SimpleDateFormat fmt = new SimpleDateFormat("z", Locale.US); final int ONE_HOUR = 60*60*1000; @@ -711,18 +725,18 @@ public void Test4162593() { Date d = new Date(p[0], p[1], p[2], p[3], p[4]); boolean transitionExpected = ((Boolean)DATA[j+2]).booleanValue(); - logln(tz.getID() + ":"); + System.out.println(tz.getID() + ":"); for (int i=0; i<4; ++i) { zone[i] = fmt.format(d); - logln("" + i + ": " + d); + System.out.println("" + i + ": " + d); d = new Date(d.getTime() + ONE_HOUR); } if (zone[0].equals(zone[1]) && (zone[1].equals(zone[2]) != transitionExpected) && zone[2].equals(zone[3])) { - logln("Ok: transition " + transitionExpected); + System.out.println("Ok: transition " + transitionExpected); } else { - errln("Fail: boundary transition incorrect"); + fail("Fail: boundary transition incorrect"); } } } @@ -736,6 +750,7 @@ public void Test4162593() { /** * TimeZone broken in last hour of year */ + @Test public void Test4173604() { // test both SimpleTimeZone and ZoneInfo objects. // @since 1.4 @@ -748,7 +763,7 @@ private void sub4173604(TimeZone pst) { int o23 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 23*60*60*1000); int o00 = pst.getOffset(1, 1999, 0, 1, Calendar.FRIDAY, 0); if (o22 != o23 || o22 != o00) { - errln("Offsets should be the same (for PST), but got: " + + fail("Offsets should be the same (for PST), but got: " + "12/31 22:00 " + o22 + ", 12/31 23:00 " + o23 + ", 01/01 00:00 " + o00); @@ -767,12 +782,12 @@ private void sub4173604(TimeZone pst) { ++transitions; Calendar t = (Calendar)cal.clone(); t.add(Calendar.MINUTE, -delta); - logln(t.getTime() + " " + t.get(Calendar.DST_OFFSET)); - logln(cal.getTime() + " " + (lastDST=cal.get(Calendar.DST_OFFSET))); + System.out.println(t.getTime() + " " + t.get(Calendar.DST_OFFSET)); + System.out.println(cal.getTime() + " " + (lastDST=cal.get(Calendar.DST_OFFSET))); } } if (transitions != 4) { - errln("Saw " + transitions + " transitions; should have seen 4"); + fail("Saw " + transitions + " transitions; should have seen 4"); } } @@ -780,6 +795,7 @@ private void sub4173604(TimeZone pst) { * getDisplayName doesn't work with unusual savings/offsets. */ @SuppressWarnings("deprecation") + @Test public void Test4176686() { // Construct a zone that does not observe DST but // that does have a DST savings (which should be ignored). @@ -827,7 +843,7 @@ public void Test4176686() { for (int i=0; i " + DATA[i+1] + ", exp " + DATA[i+2]); + fail("FAIL: " + DATA[i] + " -> " + DATA[i+1] + ", exp " + DATA[i+2]); } } } @@ -835,57 +851,58 @@ public void Test4176686() { /** * SimpleTimeZone allows invalid DOM values. */ + @Test public void Test4184229() { SimpleTimeZone zone = null; try { zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0); - errln("Failed. No exception has been thrown for DOM -1 startDay"); + fail("Failed. No exception has been thrown for DOM -1 startDay"); } catch(IllegalArgumentException e) { - logln("(a) " + e.getMessage()); + System.out.println("(a) " + e.getMessage()); } try { zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0); - errln("Failed. No exception has been thrown for DOM -1 endDay"); + fail("Failed. No exception has been thrown for DOM -1 endDay"); } catch(IllegalArgumentException e) { - logln("(b) " + e.getMessage()); + System.out.println("(b) " + e.getMessage()); } try { zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000); - errln("Failed. No exception has been thrown for DOM -1 startDay +savings"); + fail("Failed. No exception has been thrown for DOM -1 startDay +savings"); } catch(IllegalArgumentException e) { - logln("(c) " + e.getMessage()); + System.out.println("(c) " + e.getMessage()); } try { zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000); - errln("Failed. No exception has been thrown for DOM -1 endDay +savings"); + fail("Failed. No exception has been thrown for DOM -1 endDay +savings"); } catch(IllegalArgumentException e) { - logln("(d) " + e.getMessage()); + System.out.println("(d) " + e.getMessage()); } // Make a valid constructor call for subsequent tests. zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0); try { zone.setStartRule(0, -1, 0, 0); - errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings"); + fail("Failed. No exception has been thrown for DOM -1 setStartRule +savings"); } catch(IllegalArgumentException e) { - logln("(e) " + e.getMessage()); + System.out.println("(e) " + e.getMessage()); } try { zone.setStartRule(0, -1, 0); - errln("Failed. No exception has been thrown for DOM -1 setStartRule"); + fail("Failed. No exception has been thrown for DOM -1 setStartRule"); } catch(IllegalArgumentException e) { - logln("(f) " + e.getMessage()); + System.out.println("(f) " + e.getMessage()); } try { zone.setEndRule(0, -1, 0, 0); - errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings"); + fail("Failed. No exception has been thrown for DOM -1 setEndRule +savings"); } catch(IllegalArgumentException e) { - logln("(g) " + e.getMessage()); + System.out.println("(g) " + e.getMessage()); } try { zone.setEndRule(0, -1, 0); - errln("Failed. No exception has been thrown for DOM -1 setEndRule"); + fail("Failed. No exception has been thrown for DOM -1 setEndRule"); } catch(IllegalArgumentException e) { - logln("(h) " + e.getMessage()); + System.out.println("(h) " + e.getMessage()); } } @@ -893,6 +910,7 @@ public void Test4184229() { * SimpleTimeZone.getOffset() throws IllegalArgumentException when to get * of 2/29/1996 (leap day). */ + @Test public void Test4208960 () { // test both SimpleTimeZone and ZoneInfo objects. // @since 1.4 @@ -905,14 +923,14 @@ private void sub4208960(TimeZone tz) { int offset = tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29, Calendar.THURSDAY, 0); } catch (IllegalArgumentException e) { - errln("FAILED: to get TimeZone.getOffset(2/29/96)"); + fail("FAILED: to get TimeZone.getOffset(2/29/96)"); } try { int offset = tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29, Calendar.THURSDAY, 0); - errln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception."); + fail("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception."); } catch (IllegalArgumentException e) { - logln("got IllegalArgumentException"); + System.out.println("got IllegalArgumentException"); } } @@ -921,6 +939,7 @@ private void sub4208960(TimeZone tz) { * sun.util.calendar.ZoneInfo doesn't clone properly. */ @SuppressWarnings("deprecation") + @Test public void Test4966229() { TimeZone savedTZ = TimeZone.getDefault(); try { @@ -945,7 +964,7 @@ public void Test4966229() { cal2.setTime(d); int hourOfDay = cal2.get(cal.HOUR_OF_DAY); if (hourOfDay != expectedHourOfDay) { - errln("wrong hour of day: got: " + hourOfDay + fail("wrong hour of day: got: " + hourOfDay + ", expected: " + expectedHourOfDay); } } finally { @@ -956,6 +975,7 @@ public void Test4966229() { /** * 6433179: (tz) Incorrect DST end for America/Winnipeg and Canada/Central in 2038+ */ + @Test public void Test6433179() { // Use the old America/Winnipeg rule for testing. Note that // startMode is WALL_TIME for testing. It's actually @@ -974,7 +994,7 @@ public void Test6433179() { cal.set(cal.DAY_OF_WEEK_IN_MONTH, -1); cal.add(Calendar.HOUR_OF_DAY, 2); if (cal.get(cal.DST_OFFSET) == 0) { - errln("Should still be in DST."); + fail("Should still be in DST."); } } diff --git a/test/jdk/java/util/TimeZone/TimeZoneTest.java b/test/jdk/java/util/TimeZone/TimeZoneTest.java index 8f1c6e892d5..1973a782e0e 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneTest.java +++ b/test/jdk/java/util/TimeZone/TimeZoneTest.java @@ -27,9 +27,8 @@ * 8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684 8166875 8181157 * 8228469 8274407 8285844 8305113 * @modules java.base/sun.util.resources - * @library /java/text/testlib * @summary test TimeZone - * @run main TimeZoneTest -verbose + * @run junit TimeZoneTest */ import java.io.*; @@ -37,14 +36,14 @@ import java.util.*; import sun.util.resources.LocaleData; -public class TimeZoneTest extends IntlTest +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.fail; + +public class TimeZoneTest { static final int millisPerHour = 3600000; - public static void main(String[] args) throws Exception { - new TimeZoneTest().run(args); - } - /** * Bug 4130885 * Certain short zone IDs, used since 1.1.x, are incorrect. @@ -100,6 +99,7 @@ public static void main(String[] args) throws Exception { * else. E.g., EST usually indicates the US Eastern zone, so it cannot be * used for Brazil (BET). */ + @Test public void TestShortZoneIDs() throws Exception { ZoneDescriptor[] JDK_116_REFERENCE_LIST = { @@ -154,10 +154,10 @@ public void TestShortZoneIDs() throws Exception { ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i]; ZoneDescriptor currentZone = hash.get(referenceZone.getID()); if (referenceZone.equals(currentZone)) { - logln("ok " + referenceZone); + System.out.println("ok " + referenceZone); } else { - errln("Fail: Expected " + referenceZone + + fail("Fail: Expected " + referenceZone + "; got " + currentZone); } } @@ -241,6 +241,7 @@ static final String formatSeconds(int sec) { * ID "Custom" is no longer used for TimeZone objects created with * a custom time zone ID, such as "GMT-8". See 4322313. */ + @Test public void TestCustomParse() throws Exception { Object[] DATA = { // ID Expected offset in seconds @@ -271,7 +272,7 @@ public void TestCustomParse() throws Exception { Integer exp = (Integer)DATA[i+1]; TimeZone zone = TimeZone.getTimeZone(id); if (zone.getID().equals("GMT")) { - logln(id + " -> generic GMT"); + System.out.println(id + " -> generic GMT"); // When TimeZone.getTimeZone() can't parse the id, it // returns GMT -- a dubious practice, but required for // backward compatibility. @@ -283,7 +284,7 @@ public void TestCustomParse() throws Exception { else { int ioffset = zone.getRawOffset() / 1_000; String offset = formatSeconds(ioffset); - logln(id + " -> " + zone.getID() + " GMT" + offset); + System.out.println(id + " -> " + zone.getID() + " GMT" + offset); if (exp == null) { throw new Exception("Expected parse failure for " + id + ", got offset of " + offset + @@ -310,12 +311,13 @@ else if (ioffset != exp.intValue()) { * 4/21/98 - make smarter, so the test works if the ext resources * are present or not. */ + @Test public void TestDisplayName() { TimeZone zone = TimeZone.getTimeZone("PST"); String name = zone.getDisplayName(Locale.ENGLISH); - logln("PST->" + name); + System.out.println("PST->" + name); if (!name.equals("Pacific Standard Time")) - errln("Fail: Expected \"Pacific Standard Time\""); + fail("Fail: Expected \"Pacific Standard Time\""); //***************************************************************** // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES @@ -334,7 +336,7 @@ public void TestDisplayName() { ((Integer)DATA[i+1]).intValue(), Locale.ENGLISH); if (!name.equals(DATA[i+2])) - errln("Fail: Expected " + DATA[i+2] + "; got " + name); + fail("Fail: Expected " + DATA[i+2] + "; got " + name); } // Make sure that we don't display the DST name by constructing a fake @@ -342,11 +344,11 @@ public void TestDisplayName() { SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST"); zone2.setStartRule(Calendar.JANUARY, 1, 0); zone2.setEndRule(Calendar.DECEMBER, 31, 0); - logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date())); + System.out.println("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date())); name = zone2.getDisplayName(Locale.ENGLISH); - logln("Modified PST->" + name); + System.out.println("Modified PST->" + name); if (!name.equals("Pacific Standard Time")) - errln("Fail: Expected \"Pacific Standard Time\""); + fail("Fail: Expected \"Pacific Standard Time\""); // Make sure we get the default display format for Locales // with no display name data. @@ -357,7 +359,7 @@ public void TestDisplayName() { // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES //***************************************************************** - logln("PST(zh_CN)->" + name); + System.out.println("PST(zh_CN)->" + name); // Now be smart -- check to see if zh resource is even present. // If not, we expect the en fallback behavior. @@ -369,9 +371,9 @@ public void TestDisplayName() { boolean noZH = enRB == zhRB; if (noZH) { - logln("Warning: Not testing the zh_CN behavior because resource is absent"); + System.out.println("Warning: Not testing the zh_CN behavior because resource is absent"); if (!name.equals("Pacific Standard Time")) - errln("Fail: Expected Pacific Standard Time"); + fail("Fail: Expected Pacific Standard Time"); } else if (!name.equals("Pacific Standard Time") && !name.equals("\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4") && @@ -380,48 +382,49 @@ else if (!name.equals("Pacific Standard Time") && !name.equals("GMT-8:00") && !name.equals("GMT-0800") && !name.equals("GMT-800")) { - errln("Fail: Expected GMT-08:00 or something similar"); - errln("************************************************************"); - errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED"); - errln("************************************************************"); + fail("Fail: Expected GMT-08:00 or something similar\n" + + "************************************************************\n" + + "THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED\n" + + "************************************************************\n"); } // Now try a non-existent zone zone2 = new SimpleTimeZone(90*60*1000, "xyzzy"); name = zone2.getDisplayName(Locale.ENGLISH); - logln("GMT+90min->" + name); + System.out.println("GMT+90min->" + name); if (!name.equals("GMT+01:30") && !name.equals("GMT+1:30") && !name.equals("GMT+0130") && !name.equals("GMT+130")) - errln("Fail: Expected GMT+01:30 or something similar"); + fail("Fail: Expected GMT+01:30 or something similar"); } + @Test public void TestGenericAPI() { String id = "NewGMT"; int offset = 12345; SimpleTimeZone zone = new SimpleTimeZone(offset, id); if (zone.useDaylightTime()) { - errln("FAIL: useDaylightTime should return false"); + fail("FAIL: useDaylightTime should return false"); } TimeZone zoneclone = (TimeZone)zone.clone(); if (!zoneclone.equals(zone)) { - errln("FAIL: clone or operator== failed"); + fail("FAIL: clone or operator== failed"); } zoneclone.setID("abc"); if (zoneclone.equals(zone)) { - errln("FAIL: clone or operator!= failed"); + fail("FAIL: clone or operator!= failed"); } zoneclone = (TimeZone)zone.clone(); if (!zoneclone.equals(zone)) { - errln("FAIL: clone or operator== failed"); + fail("FAIL: clone or operator== failed"); } zoneclone.setRawOffset(45678); if (zoneclone.equals(zone)) { - errln("FAIL: clone or operator!= failed"); + fail("FAIL: clone or operator!= failed"); } TimeZone saveDefault = TimeZone.getDefault(); @@ -429,10 +432,10 @@ public void TestGenericAPI() { TimeZone.setDefault(zone); TimeZone defaultzone = TimeZone.getDefault(); if (defaultzone == zone) { - errln("FAIL: Default object is identical, not clone"); + fail("FAIL: Default object is identical, not clone"); } if (!defaultzone.equals(zone)) { - errln("FAIL: Default object is not equal"); + fail("FAIL: Default object is not equal"); } } finally { @@ -441,13 +444,14 @@ public void TestGenericAPI() { } @SuppressWarnings("deprecation") + @Test public void TestRuleAPI() { // ErrorCode status = ZERO_ERROR; int offset = (int)(60*60*1000*1.75); // Pick a weird offset SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone"); - if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false"); + if (zone.useDaylightTime()) fail("FAIL: useDaylightTime should return false"); // Establish our expected transition times. Do this with a non-DST // calendar with the (above) declared local offset. @@ -475,18 +479,18 @@ public void TestRuleAPI() long expMarchOne = 636251400000L; if (marchOne != expMarchOne) { - errln("FAIL: Expected start computed as " + marchOne + + fail("FAIL: Expected start computed as " + marchOne + " = " + new Date(marchOne)); - logln(" Should be " + expMarchOne + + System.out.println(" Should be " + expMarchOne + " = " + new Date(expMarchOne)); } long expJulyOne = 646793100000L; if (julyOne != expJulyOne) { - errln("FAIL: Expected start computed as " + julyOne + + fail("FAIL: Expected start computed as " + julyOne + " = " + new Date(julyOne)); - logln(" Should be " + expJulyOne + + System.out.println(" Should be " + expJulyOne + " = " + new Date(expJulyOne)); } @@ -497,15 +501,15 @@ public void TestRuleAPI() if (zone.inDaylightTime(new Date(marchOne - 1000)) || !zone.inDaylightTime(new Date(marchOne))) - errln("FAIL: Start rule broken"); + fail("FAIL: Start rule broken"); if (!zone.inDaylightTime(new Date(julyOne - 1000)) || zone.inDaylightTime(new Date(julyOne))) - errln("FAIL: End rule broken"); + fail("FAIL: End rule broken"); zone.setStartYear(1991); if (zone.inDaylightTime(new Date(marchOne)) || zone.inDaylightTime(new Date(julyOne - 1000))) - errln("FAIL: Start year broken"); + fail("FAIL: Start year broken"); // failure(status, "TestRuleAPI"); // delete gc; @@ -518,7 +522,7 @@ void testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedB boolean startsInDST = tz.inDaylightTime(new Date(min)); // if (failure(status, "SimpleTimeZone::inDaylightTime")) return; if (tz.inDaylightTime(new Date(max)) == startsInDST) { - logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST)); + System.out.println("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST)); return; } // if (failure(status, "SimpleTimeZone::inDaylightTime")) return; @@ -532,52 +536,54 @@ void testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedB } // if (failure(status, "SimpleTimeZone::inDaylightTime")) return; } - logln("Binary Search Before: " + min + " = " + new Date(min)); - logln("Binary Search After: " + max + " = " + new Date(max)); + System.out.println("Binary Search Before: " + min + " = " + new Date(min)); + System.out.println("Binary Search After: " + max + " = " + new Date(max)); long mindelta = expectedBoundary - min; long maxdelta = max - expectedBoundary; if (mindelta >= 0 && mindelta <= INTERVAL && mindelta >= 0 && mindelta <= INTERVAL) - logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary)); + System.out.println("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary)); else - errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary)); + fail("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary)); } static final int INTERVAL = 100; // Bug 006; verify the offset for a specific zone. + @Test public void TestPRTOffset() { TimeZone tz = TimeZone.getTimeZone( "PRT" ); if( tz == null ) { - errln( "FAIL: TimeZone(PRT) is null" ); + fail( "FAIL: TimeZone(PRT) is null" ); } else{ if (tz.getRawOffset() != (-4*millisPerHour)) - errln("FAIL: Offset for PRT should be -4"); + fail("FAIL: Offset for PRT should be -4"); } } // Test various calls @SuppressWarnings("deprecation") + @Test public void TestVariousAPI518() { TimeZone time_zone = TimeZone.getTimeZone("PST"); Date d = new Date(97, Calendar.APRIL, 30); - logln("The timezone is " + time_zone.getID()); + System.out.println("The timezone is " + time_zone.getID()); if (time_zone.inDaylightTime(d) != true) - errln("FAIL: inDaylightTime returned false"); + fail("FAIL: inDaylightTime returned false"); if (time_zone.useDaylightTime() != true) - errln("FAIL: useDaylightTime returned false"); + fail("FAIL: useDaylightTime returned false"); if (time_zone.getRawOffset() != -8*millisPerHour) - errln( "FAIL: getRawOffset returned wrong value"); + fail( "FAIL: getRawOffset returned wrong value"); GregorianCalendar gc = new GregorianCalendar(); gc.setTime(d); @@ -585,10 +591,11 @@ public void TestVariousAPI518() gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK), 0) != -7*millisPerHour) - errln("FAIL: getOffset returned wrong value"); + fail("FAIL: getOffset returned wrong value"); } // Test getAvailableID API + @Test public void TestGetAvailableIDs913() { StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { "); @@ -599,7 +606,7 @@ public void TestGetAvailableIDs913() buf.append(s[i]); } buf.append(" };"); - logln(buf.toString()); + System.out.println(buf.toString()); buf.setLength(0); buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { "); @@ -610,31 +617,32 @@ public void TestGetAvailableIDs913() buf.append(s[i]); } buf.append(" };"); - logln(buf.toString()); + System.out.println(buf.toString()); TimeZone tz = TimeZone.getTimeZone("PST"); if (tz != null) - logln("getTimeZone(PST) = " + tz.getID()); + System.out.println("getTimeZone(PST) = " + tz.getID()); else - errln("FAIL: getTimeZone(PST) = null"); + fail("FAIL: getTimeZone(PST) = null"); tz = TimeZone.getTimeZone("America/Los_Angeles"); if (tz != null) - logln("getTimeZone(America/Los_Angeles) = " + tz.getID()); + System.out.println("getTimeZone(America/Los_Angeles) = " + tz.getID()); else - errln("FAIL: getTimeZone(PST) = null"); + fail("FAIL: getTimeZone(PST) = null"); // Bug 4096694 tz = TimeZone.getTimeZone("NON_EXISTENT"); if (tz == null) - errln("FAIL: getTimeZone(NON_EXISTENT) = null"); + fail("FAIL: getTimeZone(NON_EXISTENT) = null"); else if (!tz.getID().equals("GMT")) - errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID()); + fail("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID()); } /** * Bug 4107276 */ + @Test public void TestDSTSavings() { // It might be better to find a way to integrate this test into the main TimeZone // tests above, but I don't have time to figure out how to do this (or if it's @@ -644,43 +652,44 @@ public void TestDSTSavings() { (int)(0.5 * millisPerHour)); if (tz.getRawOffset() != -5 * millisPerHour) - errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) + + fail("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) + " hours instead of -5 hours."); if (!tz.useDaylightTime()) - errln("Test time zone should use DST but claims it doesn't."); + fail("Test time zone should use DST but claims it doesn't."); if (tz.getDSTSavings() != 0.5 * millisPerHour) - errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() / + fail("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() / millisPerHour) + " hours instead."); int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1, Calendar.THURSDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got " + fail("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY, 10 * millisPerHour); if (offset != -4.5 * millisPerHour) - errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got " + fail("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got " + (offset / millisPerHour) + " hours."); tz.setDSTSavings(millisPerHour); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1, Calendar.THURSDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got " + fail("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY, 10 * millisPerHour); if (offset != -4 * millisPerHour) - errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got " + fail("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got " + (offset / millisPerHour) + " hours."); } /** * Bug 4107570 */ + @Test public void TestAlternateRules() { // Like TestDSTSavings, this test should probably be integrated somehow with the main // test at the top of this class, but I didn't have time to figure out how to do that. @@ -695,25 +704,25 @@ public void TestAlternateRules() { int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5, Calendar.THURSDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got " + fail("The offset for 10AM, 3/5/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15, Calendar.SUNDAY, 10 * millisPerHour); if (offset != -4 * millisPerHour) - errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got " + fail("The offset for 10AM, 3/15/98 should have been -4 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15, Calendar.THURSDAY, 10 * millisPerHour); if (offset != -4 * millisPerHour) - errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got " + fail("The offset for 10AM, 10/15/98 should have been -4 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25, Calendar.SUNDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got " + fail("The offset for 10AM, 10/25/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); // test the day-of-week-after-day-in-month API @@ -723,25 +732,25 @@ public void TestAlternateRules() { offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11, Calendar.WEDNESDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got " + fail("The offset for 10AM, 3/11/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14, Calendar.SATURDAY, 10 * millisPerHour); if (offset != -4 * millisPerHour) - errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got " + fail("The offset for 10AM, 3/14/98 should have been -4 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15, Calendar.THURSDAY, 10 * millisPerHour); if (offset != -4 * millisPerHour) - errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got " + fail("The offset for 10AM, 10/15/98 should have been -4 hours, but we got " + (offset / millisPerHour) + " hours."); offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17, Calendar.SATURDAY, 10 * millisPerHour); if (offset != -5 * millisPerHour) - errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got " + fail("The offset for 10AM, 10/17/98 should have been -5 hours, but we got " + (offset / millisPerHour) + " hours."); } } diff --git a/test/jdk/java/util/TimeZone/TransitionTest.java b/test/jdk/java/util/TimeZone/TransitionTest.java index 5f012d09d72..fb3e42cf17e 100644 --- a/test/jdk/java/util/TimeZone/TransitionTest.java +++ b/test/jdk/java/util/TimeZone/TransitionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -24,8 +24,8 @@ /* * @test * @bug 4278609 4761696 - * @library /java/text/testlib * @summary Make sure to handle DST transition ending at 0:00 January 1. + * @run junit TransitionTest */ import java.text.SimpleDateFormat; @@ -36,12 +36,13 @@ import java.util.SimpleTimeZone; import java.util.TimeZone; -public class TransitionTest extends IntlTest { +import org.junit.jupiter.api.Test; - public static void main(String[] args) throws Exception { - new TransitionTest().run(args); - } +import static org.junit.jupiter.api.Assertions.fail; + +public class TransitionTest { + @Test public void Test4278609() { SimpleTimeZone tz = new SimpleTimeZone(0, "MyTimeZone", /* DST start day: August, 1, 0:00 */ @@ -77,7 +78,7 @@ public void Test4278609() { SimpleDateFormat format = new SimpleDateFormat("dd MMM HH:mm:ss zzz", Locale.US); format.setTimeZone(tz); - errln("Wrong DST transition: " + tz + fail("Wrong DST transition: " + tz + "\na date just after DST = " + format.format(date) + "\ngetOffset = " + offset); } @@ -88,6 +89,7 @@ public void Test4278609() { * * Derived from JCK test cases some of which specify wrong day of week values. */ + @Test public void Test4761696() { GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); @@ -121,7 +123,7 @@ public void Test4761696() { long endTime = cal.getTimeInMillis() + rawOffset; long expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("test#1: wrong offset: got "+offset+", expected="+expectedOffset); + fail("test#1: wrong offset: got "+offset+", expected="+expectedOffset); } // test#2 @@ -150,7 +152,7 @@ public void Test4761696() { endTime = cal.getTimeInMillis() + rawOffset; expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("Wrong offset: got "+offset+", expected="+expectedOffset); + fail("Wrong offset: got "+offset+", expected="+expectedOffset); } rawOffset = 43200000; @@ -179,7 +181,7 @@ public void Test4761696() { endTime = cal.getTimeInMillis() + rawOffset; expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("test#2: wrong offset: got "+offset+", expected="+expectedOffset); + fail("test#2: wrong offset: got "+offset+", expected="+expectedOffset); } // test#3 @@ -209,7 +211,7 @@ public void Test4761696() { endTime = cal.getTimeInMillis() + rawOffset; expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("test#3: wrong offset: got "+offset+", expected="+expectedOffset); + fail("test#3: wrong offset: got "+offset+", expected="+expectedOffset); } // test#4 @@ -243,7 +245,7 @@ public void Test4761696() { long startTime = cal.getTimeInMillis() + rawOffset; expectedOffset = (localtime >= startTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("test#4: wrong offset: got "+offset+", expected="+expectedOffset); + fail("test#4: wrong offset: got "+offset+", expected="+expectedOffset); } // test#5 @@ -272,7 +274,7 @@ public void Test4761696() { endTime = cal.getTimeInMillis() + rawOffset; expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset; if (offset != expectedOffset) { - errln("test#5: wrong offset: got "+offset+", expected="+expectedOffset); + fail("test#5: wrong offset: got "+offset+", expected="+expectedOffset); } } diff --git a/test/jdk/sun/util/resources/TimeZone/IntlTest.java b/test/jdk/sun/util/resources/TimeZone/IntlTest.java deleted file mode 100644 index 137a610f3d9..00000000000 --- a/test/jdk/sun/util/resources/TimeZone/IntlTest.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2007, 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.lang.reflect.*; -import java.util.Hashtable; -import java.util.Enumeration; -import java.util.Vector; -import java.io.*; -import java.text.*; - -/** - * IntlTest is a base class for tests that can be run conveniently from - * the command line as well as under the Java test harness. - *

    - * Sub-classes implement a set of methods named Test. Each - * of these methods performs some test. Test methods should indicate - * errors by calling either err or errln. This will increment the - * errorCount field and may optionally print a message to the log. - * Debugging information may also be added to the log via the log - * and logln methods. These methods will add their arguments to the - * log only if the test is being run in verbose mode. - */ -public class IntlTest { - - //------------------------------------------------------------------------ - // Everything below here is boilerplate code that makes it possible - // to add a new test by simply adding a function to an existing class - //------------------------------------------------------------------------ - - protected IntlTest() { - // Create a hashtable containing all the test methods. - testMethods = new Hashtable(); - Method[] methods = getClass().getDeclaredMethods(); - for( int i=0; i Date: Tue, 19 Mar 2024 13:58:25 +0000 Subject: [PATCH 081/298] 8288989: Make tests not depend on the source code Backport-of: 2838a916ab98cb0152f8b1e3f96eccca198af5e9 --- .../doclet/testDocletExample/TestDocletExample.java | 8 ++++++-- .../tools/javac/api/snippets/TestJavaxToolsSnippets.java | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java index 0f03248d733..f210b940b60 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java +++ b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java @@ -50,8 +50,12 @@ public class TestDocletExample extends TestRunner { public static void main(String... args) throws Exception { - var t = new TestDocletExample(); - t.runTests(m -> new Object[] { Path.of(m.getName()) }); + try { + var t = new TestDocletExample(); + t.runTests(m -> new Object[] { Path.of(m.getName()) }); + } catch (SnippetUtils.ConfigurationException e) { + System.err.println("NOTE: " + e.getMessage() + "; test skipped"); + } } SnippetUtils snippets; diff --git a/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java index 10030df1679..eb5b071df6f 100644 --- a/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java +++ b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java @@ -58,7 +58,11 @@ */ public class TestJavaxToolsSnippets extends TestRunner { public static void main(String... args) throws Exception { - new TestJavaxToolsSnippets().runTests(m -> new Object[] { Path.of(m.getName()) }); + try { + new TestJavaxToolsSnippets().runTests(m -> new Object[] { Path.of(m.getName()) }); + } catch (SnippetUtils.ConfigurationException e) { + System.err.println("NOTE: " + e.getMessage() + "; test skipped"); + } } SnippetUtils snippets = new SnippetUtils("java.compiler"); From 700fd39911864787e51fedc3134b15b1e3023d6b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 19 Mar 2024 14:02:50 +0000 Subject: [PATCH 082/298] 8322920: Some ProcessTools.execute* functions are declared to throw Throwable Backport-of: 868f8745faf70c915d8294ae8f85b2d6aa096900 --- test/lib/jdk/test/lib/process/ProcessTools.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index e7cf434d615..f4d42a2aef4 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -698,7 +698,7 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, * @param cmds The command line to execute. * @return The output from the process. */ - public static OutputAnalyzer executeProcess(String... cmds) throws Throwable { + public static OutputAnalyzer executeProcess(String... cmds) throws Exception { return executeProcess(new ProcessBuilder(cmds)); } @@ -743,8 +743,7 @@ public static String getCommandLine(ProcessBuilder pb) { * @param cmds The command line to execute. * @return The {@linkplain OutputAnalyzer} instance wrapping the process. */ - public static OutputAnalyzer executeCommand(String... cmds) - throws Throwable { + public static OutputAnalyzer executeCommand(String... cmds) throws Exception { String cmdLine = String.join(" ", cmds); System.out.println("Command line: [" + cmdLine + "]"); OutputAnalyzer analyzer = ProcessTools.executeProcess(cmds); @@ -761,8 +760,7 @@ public static OutputAnalyzer executeCommand(String... cmds) * @param pb The ProcessBuilder to execute. * @return The {@linkplain OutputAnalyzer} instance wrapping the process. */ - public static OutputAnalyzer executeCommand(ProcessBuilder pb) - throws Throwable { + public static OutputAnalyzer executeCommand(ProcessBuilder pb) throws Exception { String cmdLine = pb.command().stream() .map(x -> (x.contains(" ") || x.contains("$")) ? ("'" + x + "'") : x) From 196a851b13e5e5f8fcabcef9e71dec2997d388e8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 19 Mar 2024 14:04:58 +0000 Subject: [PATCH 083/298] 8223696: java/net/httpclient/MaxStreams.java failed with didn't finish within the time-out Backport-of: 95310eab6ce73512b1afc0a7a26a396dd7b6cb7c --- test/jdk/java/net/httpclient/MaxStreams.java | 29 +++++++------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/test/jdk/java/net/httpclient/MaxStreams.java b/test/jdk/java/net/httpclient/MaxStreams.java index 0a4afd7bb7d..3d7f579ab61 100644 --- a/test/jdk/java/net/httpclient/MaxStreams.java +++ b/test/jdk/java/net/httpclient/MaxStreams.java @@ -27,7 +27,7 @@ * @summary Should HttpClient support SETTINGS_MAX_CONCURRENT_STREAMS from the server * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -ea -esa MaxStreams + * @run testng/othervm MaxStreams */ import java.io.IOException; @@ -45,7 +45,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Semaphore; import javax.net.ssl.SSLContext; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -74,9 +73,7 @@ public class MaxStreams { SSLContext ctx; String http2FixedURI; String https2FixedURI; - volatile CountDownLatch latch; ExecutorService exec; - final Semaphore canStartTestRun = new Semaphore(1); // we send an initial warm up request, then MAX_STREAMS+1 requests // in parallel. The last of them should hit the limit. @@ -98,11 +95,9 @@ public Object[][] variants() { } - @Test(dataProvider = "uris", timeOut=20000) + @Test(dataProvider = "uris") void testAsString(String uri) throws Exception { - System.err.println("Semaphore acquire"); - canStartTestRun.acquire(); - latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); handler.setLatch(latch); HttpClient client = HttpClient.newBuilder().sslContext(ctx).build(); List>> responses = new LinkedList<>(); @@ -209,12 +204,11 @@ synchronized CountDownLatch getLatch() { @Override public void handle(Http2TestExchange t) throws IOException { - int c = -1; try (InputStream is = t.getRequestBody(); OutputStream os = t.getResponseBody()) { is.readAllBytes(); - c = counter.getAndIncrement(); + int c = counter.getAndIncrement(); if (c > 0 && c <= MAX_STREAMS) { // Wait for latch. try { @@ -223,18 +217,15 @@ public void handle(Http2TestExchange t) throws IOException { getLatch().await(); System.err.println("Latch resume"); } catch (InterruptedException ee) {} + } else if (c == MAX_STREAMS + 1) { + // client issues MAX_STREAMS + 3 requests in total + // but server should only see MAX_STREAMS + 2 in total. One is rejected by client + // counter c captured before increment so final value is MAX_STREAMS + 1 + System.err.println("Counter reset"); + counter.set(0); } t.sendResponseHeaders(200, RESPONSE.length()); os.write(RESPONSE.getBytes()); - } finally { - // client issues MAX_STREAMS + 3 requests in total - // but server should only see MAX_STREAMS + 2 in total. One is rejected by client - // counter c captured before increment so final value is MAX_STREAMS + 1 - if (c == MAX_STREAMS + 1) { - System.err.println("Semaphore release"); - counter.set(0); - canStartTestRun.release(); - } } } } From eb4f76e5b8a0759c056e916fce167d895570b30e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 19 Mar 2024 14:07:09 +0000 Subject: [PATCH 084/298] 8328066: WhiteBoxResizeTest failure on linux-x86: Could not reserve enough space for 2097152KB object heap Backport-of: dde519dc2180742c119ac07221c2a149b9f06c18 --- test/jdk/java/util/HashMap/WhiteBoxResizeTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java b/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java index e04b9d680d1..e517d5570d0 100644 --- a/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java +++ b/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, Red Hat, Inc. All rights reserved. - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -55,6 +55,8 @@ * @bug 8186958 8210280 8281631 8285386 8284780 * @modules java.base/java.util:open * @summary White box tests for HashMap-related internals around table sizing + * @comment skip running this test on 32 bit VM + * @requires vm.bits == "64" * @run testng/othervm -Xmx2g WhiteBoxResizeTest */ public class WhiteBoxResizeTest { From c8ddf40f1a535379216cbf023f768700588e95db Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Tue, 19 Mar 2024 14:10:38 +0000 Subject: [PATCH 085/298] 8326529: JFR: Test for CompilerCompile events fails due to time out Backport-of: 4dd6c44cbdb0b5957414fa87b6c559fa4d6f2fa8 --- test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java index 77352ba26e9..775d7789bee 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java @@ -47,6 +47,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:CompileOnly=jdk.jfr.event.compiler.TestCompilerCompile::dummyMethod,jdk.jfr.event.compiler.TestCompilerCompile::doTest * jdk.jfr.event.compiler.TestCompilerCompile */ public class TestCompilerCompile { From eaa8ed99009b137a8337c2e4a8c65fa88df30b87 Mon Sep 17 00:00:00 2001 From: Oli Gillespie Date: Tue, 19 Mar 2024 14:14:56 +0000 Subject: [PATCH 086/298] 8324646: Avoid Class.forName in SecureRandom constructor Reviewed-by: shade Backport-of: 8ef918d6678437a5b351b172bb4cf144eeaa975f --- .../share/classes/java/security/Provider.java | 31 +++++++------ .../java/security/SecureRandomBench.java | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 test/micro/org/openjdk/bench/java/security/SecureRandomBench.java diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index 7246285b349..de857d014bc 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.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 @@ -27,7 +27,9 @@ import jdk.internal.event.SecurityProviderServiceEvent; +import javax.security.auth.login.Configuration; import java.io.*; +import java.security.cert.CertStoreParameters; import java.util.*; import static java.util.Locale.ENGLISH; import java.lang.ref.*; @@ -1556,20 +1558,20 @@ public String toString() { private static class EngineDescription { final String name; final boolean supportsParameter; - final String constructorParameterClassName; + final Class constructorParameterClass; - EngineDescription(String name, boolean sp, String paramName) { + EngineDescription(String name, boolean sp, Class constructorParameterClass) { this.name = name; this.supportsParameter = sp; - this.constructorParameterClassName = paramName; + this.constructorParameterClass = constructorParameterClass; } } // built in knowledge of the engine types shipped as part of the JDK private static final Map knownEngines; - private static void addEngine(String name, boolean sp, String paramName) { - EngineDescription ed = new EngineDescription(name, sp, paramName); + private static void addEngine(String name, boolean sp, Class constructorParameterClass) { + EngineDescription ed = new EngineDescription(name, sp, constructorParameterClass); // also index by canonical name to avoid toLowerCase() for some lookups knownEngines.put(name.toLowerCase(ENGLISH), ed); knownEngines.put(name, ed); @@ -1585,13 +1587,13 @@ private static void addEngine(String name, boolean sp, String paramName) { addEngine("KeyStore", false, null); addEngine("MessageDigest", false, null); addEngine("SecureRandom", false, - "java.security.SecureRandomParameters"); + SecureRandomParameters.class); addEngine("Signature", true, null); addEngine("CertificateFactory", false, null); addEngine("CertPathBuilder", false, null); addEngine("CertPathValidator", false, null); addEngine("CertStore", false, - "java.security.cert.CertStoreParameters"); + CertStoreParameters.class); // JCE addEngine("Cipher", true, null); addEngine("ExemptionMechanism", false, null); @@ -1610,18 +1612,20 @@ private static void addEngine(String name, boolean sp, String paramName) { addEngine("SaslClientFactory", false, null); addEngine("SaslServerFactory", false, null); // POLICY + @SuppressWarnings("removal") + Class policyParams = Policy.Parameters.class; addEngine("Policy", false, - "java.security.Policy$Parameters"); + policyParams); // CONFIGURATION addEngine("Configuration", false, - "javax.security.auth.login.Configuration$Parameters"); + Configuration.Parameters.class); // XML DSig addEngine("XMLSignatureFactory", false, null); addEngine("KeyInfoFactory", false, null); addEngine("TransformService", false, null); // Smart Card I/O addEngine("TerminalFactory", false, - "java.lang.Object"); + Object.class); } // get the "standard" (mixed-case) engine name for arbitrary case engine name @@ -1895,8 +1899,7 @@ public Object newInstance(Object constructorParameter) ctrParamClz = constructorParameter == null? null : constructorParameter.getClass(); } else { - ctrParamClz = cap.constructorParameterClassName == null? - null : Class.forName(cap.constructorParameterClassName); + ctrParamClz = cap.constructorParameterClass; if (constructorParameter != null) { if (ctrParamClz == null) { throw new InvalidParameterException @@ -1907,7 +1910,7 @@ public Object newInstance(Object constructorParameter) if (!ctrParamClz.isAssignableFrom(argClass)) { throw new InvalidParameterException ("constructorParameter must be instanceof " - + cap.constructorParameterClassName.replace('$', '.') + + cap.constructorParameterClass.getName().replace('$', '.') + " for engine type " + type); } } diff --git a/test/micro/org/openjdk/bench/java/security/SecureRandomBench.java b/test/micro/org/openjdk/bench/java/security/SecureRandomBench.java new file mode 100644 index 00000000000..b9196b25c62 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/security/SecureRandomBench.java @@ -0,0 +1,43 @@ +/* + * Copyright Amazon.com Inc. 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. + * + */ + +package org.openjdk.bench.java.security; + +import org.openjdk.jmh.annotations.*; + +import java.security.SecureRandom; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 3) +public class SecureRandomBench { + + @Benchmark + public SecureRandom create() throws Exception { + return new SecureRandom(); + } +} From 6b0cfd441eecafe0181aae830504c2922485f690 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Tue, 19 Mar 2024 15:17:21 +0000 Subject: [PATCH 087/298] 8320365: IPPPrintService.getAttributes() causes blanket re-initialisation Backport-of: 91ffdfb1fcacbb95b93491d412e506695198946e --- .../classes/sun/print/IPPPrintService.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 91be3e06a5a..95a2682e058 100644 --- a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -456,12 +456,14 @@ private void initAttributes() { // IPP currently does not support it but PPD does. try { - cps = new CUPSPrinter(printer); - mediaSizeNames = cps.getMediaSizeNames(); - mediaTrays = cps.getMediaTrays(); - customMediaSizeNames = cps.getCustomMediaSizeNames(); - defaultMediaIndex = cps.getDefaultMediaIndex(); - rawResolutions = cps.getRawResolutions(); + if (cps == null) { + cps = new CUPSPrinter(printer); + mediaSizeNames = cps.getMediaSizeNames(); + mediaTrays = cps.getMediaTrays(); + customMediaSizeNames = cps.getCustomMediaSizeNames(); + defaultMediaIndex = cps.getDefaultMediaIndex(); + rawResolutions = cps.getRawResolutions(); + } urlConnection.disconnect(); init = true; return; @@ -1225,9 +1227,17 @@ T getAttribute(Class category) public synchronized PrintServiceAttributeSet getAttributes() { - // update getAttMap by sending again get-attributes IPP request - init = false; - initAttributes(); + if (!init) { + // get all attributes for the first time. + initAttributes(); + } else { + // only need service attributes updated. + // update getAttMap by sending again get-attributes IPP request + if ((urlConnection = getIPPConnection(myURL)) != null) { + opGetAttributes(); + urlConnection.disconnect(); + } + } HashPrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); From 93a4707f13aafc08a131e24c3c5ccbbe189da529 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Tue, 19 Mar 2024 17:36:25 +0000 Subject: [PATCH 088/298] 7001133: OutOfMemoryError by CustomMediaSizeName implementation Backport-of: 10335f60f923aa4f315e64acb2bfd7bb06d47a1b --- .../sun/print/CustomMediaSizeName.java | 56 +++++++++++++++++ .../classes/sun/print/CustomMediaTray.java | 36 +++++++++++ .../unix/classes/sun/print/CUPSPrinter.java | 21 ++----- .../classes/sun/print/IPPPrintService.java | 6 +- .../print/CustomMediaSizeNameOOMETest.java | 61 +++++++++++++++++++ 5 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 test/jdk/javax/print/CustomMediaSizeNameOOMETest.java diff --git a/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java b/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java index 34035e5c1a3..b8d3ec723b8 100644 --- a/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java +++ b/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java @@ -27,15 +27,20 @@ import java.io.Serial; import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Objects; import javax.print.attribute.EnumSyntax; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.Size2DSyntax; class CustomMediaSizeName extends MediaSizeName { private static ArrayList customStringTable = new ArrayList<>(); private static ArrayList customEnumTable = new ArrayList<>(); + private static Map customMap = new HashMap<>(); private String choiceName; private MediaSizeName mediaName; @@ -191,4 +196,55 @@ protected EnumSyntax[] getEnumValueTable() { return customEnumTable.toArray(enumTable); } + public static CustomMediaSizeName create(String name, String choice, + float width, float length) { + SizeNameChoiceItem key = new SizeNameChoiceItem(name, choice, width, length); + CustomMediaSizeName value = customMap.get(key); + if (value == null) { + value = new CustomMediaSizeName(name, choice, width, length); + customMap.put(key, value); + + // add this new custom media size name to MediaSize array + if ((width > 0.0) && (length > 0.0)) { + try { + new MediaSize(width, length, Size2DSyntax.INCH, value); + } catch (IllegalArgumentException e) { + /* PDF printer in Linux for Ledger paper causes + "IllegalArgumentException: X dimension > Y dimension". + We rotate based on IPP spec. */ + new MediaSize(length, width, Size2DSyntax.INCH, value); + } + } + } + return value; + } + + private static class SizeNameChoiceItem { + + private final String name; + private final String choice; + private final float width; + private final float length; + + public SizeNameChoiceItem(String name, String choice, float width, float length) { + this.name = name; + this.choice = choice; + this.width = width; + this.length = length; + } + + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + SizeNameChoiceItem that = (SizeNameChoiceItem) object; + return Objects.equals(this.name, that.name) + && Objects.equals(this.choice, that.choice) && + Float.compare(this.width, that.width) == 0 && + Float.compare(this.length, that.length) == 0; + } + + public int hashCode() { + return Objects.hash(name, choice, width, length); + } + } } diff --git a/src/java.desktop/share/classes/sun/print/CustomMediaTray.java b/src/java.desktop/share/classes/sun/print/CustomMediaTray.java index 324059a56d6..e1ce64106b1 100644 --- a/src/java.desktop/share/classes/sun/print/CustomMediaTray.java +++ b/src/java.desktop/share/classes/sun/print/CustomMediaTray.java @@ -27,6 +27,9 @@ import java.io.Serial; import java.util.ArrayList; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; import javax.print.attribute.EnumSyntax; import javax.print.attribute.standard.Media; @@ -35,6 +38,7 @@ public class CustomMediaTray extends MediaTray { private static ArrayList customStringTable = new ArrayList<>(); private static ArrayList customEnumTable = new ArrayList<>(); + private static Map customMap = new HashMap<>(); private String choiceName; private CustomMediaTray(int x) { @@ -93,4 +97,36 @@ protected EnumSyntax[] getEnumValueTable() { return customEnumTable.toArray(enumTable); } + public static CustomMediaTray create(String name, String choice) { + NameChoiceItem key = new NameChoiceItem(name, choice); + CustomMediaTray value = customMap.get(key); + if (value == null) { + value = new CustomMediaTray(name, choice); + customMap.put(key, value); + } + return value; + } + + private static class NameChoiceItem { + + private final String name; + private final String choice; + + public NameChoiceItem(String name, String choice) { + this.name = name; + this.choice = choice; + } + + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + NameChoiceItem that = (NameChoiceItem) object; + return Objects.equals(this.name, that.name) + && Objects.equals(this.choice, that.choice); + } + + public int hashCode() { + return Objects.hash(name, choice); + } + } } diff --git a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java index e2a69c79c3e..6c75949731d 100644 --- a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java +++ b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java @@ -225,26 +225,13 @@ private synchronized void initMedia() { w = (float)(pageSizes[i*6+4]/PRINTER_DPI); y = (float)(pageSizes[i*6+5]/PRINTER_DPI); - msn = new CustomMediaSizeName(media[i*2], media[i*2+1], - width, length); + msn = CustomMediaSizeName.create(media[i*2], media[i*2+1], + width, length); // add to list of standard MediaSizeNames if ((cupsMediaSNames[i] = msn.getStandardMedia()) == null) { // add custom if no matching standard media cupsMediaSNames[i] = msn; - - // add this new custom msn to MediaSize array - if ((width > 0.0) && (length > 0.0)) { - try { - new MediaSize(width, length, - Size2DSyntax.INCH, msn); - } catch (IllegalArgumentException e) { - /* PDF printer in Linux for Ledger paper causes - "IllegalArgumentException: X dimension > Y dimension". - We rotate based on IPP spec. */ - new MediaSize(length, width, Size2DSyntax.INCH, msn); - } - } } // add to list of custom MediaSizeName @@ -269,8 +256,8 @@ private synchronized void initMedia() { MediaTray mt; for (int i=0; i System.currentTimeMillis()); + } +} From f17d3863c170ca3f979166801f6a16ac49fd257f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 20 Mar 2024 08:55:19 +0000 Subject: [PATCH 089/298] 8317631: Refactor ChoiceFormat tests to use JUnit Backport-of: 5e8d893c4809fdb30e01bdfe06b4f488f7bbef83 --- .../Format/ChoiceFormat/Bug4185732Test.java | 49 +++++----- .../text/Format/ChoiceFormat/Bug4387255.java | 59 ++++++++---- .../text/Format/ChoiceFormat/Bug8001209.java | 94 +++++++++++-------- 3 files changed, 127 insertions(+), 75 deletions(-) diff --git a/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java b/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java index 51edac17d38..449af839b62 100644 --- a/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java +++ b/test/jdk/java/text/Format/ChoiceFormat/Bug4185732Test.java @@ -21,15 +21,6 @@ * questions. */ -/* - * @test - * @bug 4185732 - * @library /java/text/testlib - * @build Bug4185732Test HexDumpReader - * @run junit Bug4185732Test - * @summary test that ChoiceFormat invariants are preserved across serialization. - */ - /* * This file is available under and governed by the GNU General Public * License version 2 only, as published by the Free Software Foundation. @@ -64,36 +55,50 @@ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ -import java.util.*; -import java.io.*; +/* + * @test + * @bug 4185732 + * @library /java/text/testlib + * @build HexDumpReader + * @summary Test that ChoiceFormat invariants are preserved across serialization. + * This test depends on Bug4185732.ser.txt and will fail otherwise. + * @run junit Bug4185732Test + */ + +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.text.ChoiceFormat; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.fail; -/** - * A Locale can never contain language codes of he, yi or id. - */ public class Bug4185732Test { + + /* + * The ChoiceFormat class requires that its choiceFormats and choiceLimits + * arrays have the same length. This test ensures that the invariant is enforced + * during the readObject() call. + */ @Test - public void testIt() throws Exception { + public void choiceFormatSerializationInvariantsTest() { try { + // A serialized ChoiceFormat with unequal formats and limits final ObjectInputStream in = new ObjectInputStream(HexDumpReader.getStreamFromHexDump("Bug4185732.ser.txt")); final ChoiceFormat loc = (ChoiceFormat)in.readObject(); if (loc.getFormats().length != loc.getLimits().length) { fail("ChoiceFormat did not properly check stream"); } else { - //for some reason, the data file was VALID. This test - //requires a corrupt data file the format and limit - //arrays are of different length. + // for some reason, the data file was VALID. This test + // requires a corrupt data file the format and limit + // arrays are of different length. fail("Test data file was not properly created"); } - } catch (InvalidObjectException e) { - //this is what we want to have happen - } catch (Exception e) { - fail(e.toString()); + } catch (InvalidObjectException expectedException) { + // Expecting an IOE + } catch (Exception wrongException) { + fail("Expected an InvalidObjectException, instead got: " + wrongException); } } } diff --git a/test/jdk/java/text/Format/ChoiceFormat/Bug4387255.java b/test/jdk/java/text/Format/ChoiceFormat/Bug4387255.java index d211bb6976e..2221844fed2 100644 --- a/test/jdk/java/text/Format/ChoiceFormat/Bug4387255.java +++ b/test/jdk/java/text/Format/ChoiceFormat/Bug4387255.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -21,16 +21,25 @@ * questions. */ -/** +/* * @test * @bug 4387255 * @summary Verifies that ChoiceFormat can handle large numbers of choices + * (previously capped at 30). + * @run junit Bug4387255 */ import java.text.ChoiceFormat; -public class Bug4387255 { +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; +public class Bug4387255 { private static final double[] doubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, @@ -49,21 +58,39 @@ public class Bug4387255 { "|20#K|21#L|22#M|23#N|24#O|25#P|26#Q|27#R|28#S|29#T" + "|30#U|31#V|32#W|33#X|34#Y|35#Z"; - public static void main(String[] args) throws Exception { - ChoiceFormat choiceFormat1 = new ChoiceFormat(doubles, strings); - ChoiceFormat choiceFormat2 = new ChoiceFormat(pattern); - if (!choiceFormat1.equals(choiceFormat2)) { - System.out.println("choiceFormat1: " + choiceFormat1.toPattern()); - System.out.println("choiceFormat2: " + choiceFormat2.toPattern()); - throw new RuntimeException(); - } + private static final ChoiceFormat choiceFormat1 = new ChoiceFormat(doubles, strings); + private static final ChoiceFormat choiceFormat2 = new ChoiceFormat(pattern); + // Ensure that both the large ChoiceFormats format each value properly + @ParameterizedTest + @MethodSource + public void largeChoicesTest(double db, String expectedString) { + String result = choiceFormat2.format(db); + assertEquals(expectedString, result, + "Wrong format result with: " + choiceFormat2); + } + + + /* + * Create arguments in form of : (double, string) + * Each string is the expected result of ChoiceFormat.format(double) + */ + private static Arguments[] largeChoicesTest() { + Arguments[] doublesAndStrings = new Arguments[doubles.length]; for (int i = 0; i < doubles.length; i++) { - String result = choiceFormat2.format(doubles[i]); - if (!result.equals(strings[i])) { - throw new RuntimeException("Wrong format result - expected " + - strings[i] + ", got " + result); - } + doublesAndStrings[i] = arguments(doubles[i], strings[i]); } + return doublesAndStrings; + } + + /* + * Check that creating a ChoiceFormat with limits and formats arrays + * equivalent to a string pattern are equal. (Checks that both constructors + * allow for a large number of choices and formats) + */ + @Test + public void patternEqualsArraysTest() { + assertEquals(choiceFormat1, choiceFormat2, "Pattern is equivalent to " + + "formats and limits, but ChoiceFormats are not equal"); } } diff --git a/test/jdk/java/text/Format/ChoiceFormat/Bug8001209.java b/test/jdk/java/text/Format/ChoiceFormat/Bug8001209.java index b9f490fad62..3eaa96de4d0 100644 --- a/test/jdk/java/text/Format/ChoiceFormat/Bug8001209.java +++ b/test/jdk/java/text/Format/ChoiceFormat/Bug8001209.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -21,70 +21,90 @@ * questions. */ -/** +/* * @test * @bug 8001209 * @summary Confirm that the values set by setChoices() are not mutable. + * @run junit Bug8001209 */ -import java.text.*; + +import java.text.ChoiceFormat; +import java.text.ParsePosition; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; public class Bug8001209 { - public static void main(String[] args) throws Exception { - boolean err = false; + // Represents the expected output of formatting the ChoiceFormat + private static String expectedFormattedOutput; + private static ChoiceFormat cFmt; + private static ParsePosition status; + private static String[] originalSetterArray; - // Borrow an example in API doc - double[] limits = {1,2,3,4,5,6,7}; - String[] dayOfWeekNames = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; - ChoiceFormat form = new ChoiceFormat(limits, dayOfWeekNames); - ParsePosition status = new ParsePosition(0); + // Build the original ChoiceFormat to test if it can be mutated + @BeforeAll + static void setUpChoiceFormatAndOutput() { + double[] limits = {1, 2, 3, 4, 5, 6, 7}; + originalSetterArray = new String[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + // Constructor calls setChoices + cFmt = new ChoiceFormat(limits, originalSetterArray); + status = new ParsePosition(0); + // Build the expected results of formatting with the original ChoiceFormat StringBuilder before = new StringBuilder(); for (double i = 1.0; i <= 7.0; ++i) { status.setIndex(0); - String s = form.format(i); + String s = cFmt.format(i); before.append(" "); before.append(s); - before.append(form.parse(form.format(i),status)); + before.append(cFmt.parse(cFmt.format(i), status)); } - String original = before.toString(); + expectedFormattedOutput = before.toString(); + } - double[] newLimits = form.getLimits(); - String[] newFormats = (String[])form.getFormats(); + /* + * Ensure that mutating the arrays returned by getChoices and getLimits does + * not affect the internal representation of the ChoiceFormat. + */ + @Test + public void immutableArraysFromGetters() { + // Modify the array returned by getFormats() -> newFormats + String[] newFormats = (String[]) cFmt.getFormats(); newFormats[6] = "Doyoubi"; StringBuilder after = new StringBuilder(); for (double i = 1.0; i <= 7.0; ++i) { status.setIndex(0); - String s = form.format(i); + String s = cFmt.format(i); after.append(" "); after.append(s); - after.append(form.parse(form.format(i),status)); - } - if (!original.equals(after.toString())) { - err = true; - System.err.println(" Expected:" + before - + "\n Got: " + after); + after.append(cFmt.parse(cFmt.format(i), status)); } + // Compare the expected results with the new formatted results + assertEquals(after.toString(), expectedFormattedOutput, + "Mutating array returned from getter changed internals of ChoiceFormat"); + } - dayOfWeekNames[6] = "Saturday"; - after = new StringBuilder(); + /* + * Ensure that mutating the arrays passed to setChoices/constructor does + * not affect the internal representation of the ChoiceFormat. + */ + @Test + public void immutableArraysFromSetter() { + // Modify the array passed to setFormats() -> dayOfWeekNames + originalSetterArray[6] = "Saturday"; + StringBuilder after = new StringBuilder(); for (double i = 1.0; i <= 7.0; ++i) { status.setIndex(0); - String s = form.format(i); + String s = cFmt.format(i); after.append(" "); after.append(s); - after.append(form.parse(form.format(i),status)); - } - if (!original.equals(after.toString())) { - err = true; - System.err.println(" Expected:" + before - + "\n Got: " + after); - } - - if (err) { - throw new RuntimeException("Failed."); - } else { - System.out.println("Passed."); + after.append(cFmt.parse(cFmt.format(i), status)); } + // Compare the expected results with the new formatted results + assertEquals(after.toString(), expectedFormattedOutput, + "Mutating array passed to setter changed internals of ChoiceFormat"); } } From 6a89849e11a84eade09b8e2984421248de21d397 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 20 Mar 2024 08:59:10 +0000 Subject: [PATCH 090/298] 8328524: [x86] StringRepeat.java failure on linux-x86: Could not reserve enough space for 2097152KB object heap Backport-of: eebcc2181fe27f6aa10559233c7c58882a146f56 --- test/jdk/java/lang/String/StringRepeat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/lang/String/StringRepeat.java b/test/jdk/java/lang/String/StringRepeat.java index c36e512f8ba..11a0393766e 100644 --- a/test/jdk/java/lang/String/StringRepeat.java +++ b/test/jdk/java/lang/String/StringRepeat.java @@ -31,7 +31,7 @@ * @test * @summary This exercises String#repeat patterns with 16 * 1024 * 1024 repeats. * @requires os.maxMemory >= 2G - * @requires !(os.family == "windows" & sun.arch.data.model == "32") + * @requires vm.bits == "64" * @run main/othervm -Xmx2g StringRepeat 16777216 */ From cc918abe2f6e6a95c956d4f2a37e77d2f53eab36 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 21 Mar 2024 09:49:41 +0000 Subject: [PATCH 091/298] 8319048: Monitor deflation unlink phase prolongs time to safepoint Backport-of: efc392259c64986bbbe880259e95b09058b9076a --- src/hotspot/share/runtime/globals.hpp | 4 + src/hotspot/share/runtime/synchronizer.cpp | 66 +++++-- src/hotspot/share/runtime/synchronizer.hpp | 1 + .../Monitor/MonitorUnlinkBatchTest.java | 178 ++++++++++++++++++ 4 files changed, 235 insertions(+), 14 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 7137270fd17..a066d0d3749 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -732,6 +732,10 @@ const int ObjectAlignmentInBytes = 8; "at one time (minimum is 1024).") \ range(1024, max_jint) \ \ + product(intx, MonitorUnlinkBatch, 500, DIAGNOSTIC, \ + "The maximum number of monitors to unlink in one batch. ") \ + range(1, max_jint) \ + \ product(intx, MonitorUsedDeflationThreshold, 90, DIAGNOSTIC, \ "Percentage of used monitors before triggering deflation (0 is " \ "off). The check is performed on GuaranteedSafepointInterval, " \ diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index dd10a6e361f..6cdb95be2e6 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -84,44 +84,68 @@ size_t MonitorList::max() const { return Atomic::load(&_max); } -// Walk the in-use list and unlink (at most MonitorDeflationMax) deflated -// ObjectMonitors. Returns the number of unlinked ObjectMonitors. +// Walk the in-use list and unlink deflated ObjectMonitors. +// Returns the number of unlinked ObjectMonitors. size_t MonitorList::unlink_deflated(Thread* current, LogStream* ls, elapsedTimer* timer_p, + size_t deflated_count, GrowableArray* unlinked_list) { size_t unlinked_count = 0; ObjectMonitor* prev = nullptr; - ObjectMonitor* head = Atomic::load_acquire(&_head); - ObjectMonitor* m = head; + ObjectMonitor* m = Atomic::load_acquire(&_head); + // The in-use list head can be null during the final audit. while (m != nullptr) { if (m->is_being_async_deflated()) { - // Find next live ObjectMonitor. + // Find next live ObjectMonitor. Batch up the unlinkable monitors, so we can + // modify the list once per batch. The batch starts at "m". + size_t unlinked_batch = 0; ObjectMonitor* next = m; + // Look for at most MonitorUnlinkBatch monitors, or the number of + // deflated and not unlinked monitors, whatever comes first. + assert(deflated_count >= unlinked_count, "Sanity: underflow"); + size_t unlinked_batch_limit = MIN2(deflated_count - unlinked_count, MonitorUnlinkBatch); do { ObjectMonitor* next_next = next->next_om(); - unlinked_count++; + unlinked_batch++; unlinked_list->append(next); next = next_next; - if (unlinked_count >= (size_t)MonitorDeflationMax) { - // Reached the max so bail out on the gathering loop. + if (unlinked_batch >= unlinked_batch_limit) { + // Reached the max batch, so bail out of the gathering loop. + break; + } + if (prev == nullptr && Atomic::load(&_head) != m) { + // Current batch used to be at head, but it is not at head anymore. + // Bail out and figure out where we currently are. This avoids long + // walks searching for new prev during unlink under heavy list inserts. break; } } while (next != nullptr && next->is_being_async_deflated()); + + // Unlink the found batch. if (prev == nullptr) { - ObjectMonitor* prev_head = Atomic::cmpxchg(&_head, head, next); - if (prev_head != head) { - // Find new prev ObjectMonitor that just got inserted. + // The current batch is the first batch, so there is a chance that it starts at head. + // Optimistically assume no inserts happened, and try to unlink the entire batch from the head. + ObjectMonitor* prev_head = Atomic::cmpxchg(&_head, m, next); + if (prev_head != m) { + // Something must have updated the head. Figure out the actual prev for this batch. for (ObjectMonitor* n = prev_head; n != m; n = n->next_om()) { prev = n; } + assert(prev != nullptr, "Should have found the prev for the current batch"); prev->set_next_om(next); } } else { + // The current batch is preceded by another batch. This guarantees the current batch + // does not start at head. Unlink the entire current batch without updating the head. + assert(Atomic::load(&_head) != m, "Sanity"); prev->set_next_om(next); } - if (unlinked_count >= (size_t)MonitorDeflationMax) { - // Reached the max so bail out on the searching loop. + + unlinked_count += unlinked_batch; + if (unlinked_count >= deflated_count) { + // Reached the max so bail out of the searching loop. + // There should be no more deflated monitors left. break; } m = next; @@ -137,6 +161,20 @@ size_t MonitorList::unlink_deflated(Thread* current, LogStream* ls, ls, timer_p); } } + +#ifdef ASSERT + // Invariant: the code above should unlink all deflated monitors. + // The code that runs after this unlinking does not expect deflated monitors. + // Notably, attempting to deflate the already deflated monitor would break. + { + ObjectMonitor* m = Atomic::load_acquire(&_head); + while (m != nullptr) { + assert(!m->is_being_async_deflated(), "All deflated monitors should be unlinked"); + m = m->next_om(); + } + } +#endif + Atomic::sub(&_count, unlinked_count); return unlinked_count; } @@ -1632,7 +1670,7 @@ size_t ObjectSynchronizer::deflate_idle_monitors() { // Unlink deflated ObjectMonitors from the in-use list. ResourceMark rm; GrowableArray delete_list((int)deflated_count); - unlinked_count = _in_use_list.unlink_deflated(current, ls, &timer, &delete_list); + unlinked_count = _in_use_list.unlink_deflated(current, ls, &timer, deflated_count, &delete_list); if (current->is_monitor_deflation_thread()) { if (ls != nullptr) { timer.stop(); diff --git a/src/hotspot/share/runtime/synchronizer.hpp b/src/hotspot/share/runtime/synchronizer.hpp index d65a1e14bfa..4dea13432e7 100644 --- a/src/hotspot/share/runtime/synchronizer.hpp +++ b/src/hotspot/share/runtime/synchronizer.hpp @@ -47,6 +47,7 @@ class MonitorList { public: void add(ObjectMonitor* monitor); size_t unlink_deflated(Thread* current, LogStream* ls, elapsedTimer* timer_p, + size_t deflated_count, GrowableArray* unlinked_list); size_t count() const; size_t max() const; diff --git a/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java b/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java new file mode 100644 index 00000000000..063940ce643 --- /dev/null +++ b/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java @@ -0,0 +1,178 @@ +/* + * Copyright Amazon.com Inc. 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 jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/* + * @test id=defaults + * @bug 8319048 + * @summary Test the MonitorUnlinkBatch options + * @library /test/lib + * @run driver MonitorUnlinkBatchTest defaults + */ + +/* + * @test id=legal + * @library /test/lib + * @run driver MonitorUnlinkBatchTest legal + */ + +/* + * @test id=illegal + * @library /test/lib + * @run driver MonitorUnlinkBatchTest illegal + */ + +/* + * @test id=aggressive + * @library /test/lib + * @run driver MonitorUnlinkBatchTest aggressive + */ + +/* + * @test id=lazy + * @library /test/lib + * @run driver MonitorUnlinkBatchTest lazy + */ + + +public class MonitorUnlinkBatchTest { + + public static class Test { + // Inflate a lot of monitors, so that threshold heuristics definitely fires + private static final int MONITORS = 10_000; + + // Use a handful of threads to inflate the monitors, to eat the cost of + // wait(1) calls. This can be larger than available parallelism, since threads + // would be time-waiting. + private static final int THREADS = 16; + + private static Thread[] threads; + private static Object[] monitors; + + public static void main(String... args) throws Exception { + monitors = new Object[MONITORS]; + threads = new Thread[THREADS]; + + for (int t = 0; t < THREADS; t++) { + int monStart = t * MONITORS / THREADS; + int monEnd = (t + 1) * MONITORS / THREADS; + threads[t] = new Thread(() -> { + for (int m = monStart; m < monEnd; m++) { + Object o = new Object(); + synchronized (o) { + try { + o.wait(1); + } catch (InterruptedException e) { + } + } + monitors[m] = o; + } + }); + threads[t].start(); + } + + for (Thread t : threads) { + t.join(); + } + + try { + Thread.sleep(10_000); + } catch (InterruptedException ie) { + } + } + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + throw new IllegalArgumentException("Expect the test label"); + } + + String test = args[0]; + switch (test) { + case "defaults": + test(""); + break; + + case "legal": + // Legal, even if not useful settings + test("", + "-XX:MonitorDeflationMax=100000", + "-XX:MonitorUnlinkBatch=100001" + ); + break; + + case "illegal": + // Quick tests that should fail on JVM flags verification. + test("outside the allowed range", + "-XX:MonitorUnlinkBatch=-1" + ); + test("outside the allowed range", + "-XX:MonitorUnlinkBatch=0" + ); + break; + + case "aggressive": + // The smallest batch possible. + test("", + "-XX:MonitorUnlinkBatch=1" + ); + break; + + case "lazy": + // The largest batch possible. + test("", + "-XX:MonitorDeflationMax=1000000", + "-XX:MonitorUnlinkBatch=1000000" + ); + break; + + default: + throw new IllegalArgumentException("Unknown test: " + test); + } + } + + public static void test(String msg, String... args) throws Exception { + List opts = new ArrayList<>(); + opts.add("-Xmx128M"); + opts.add("-XX:+UnlockDiagnosticVMOptions"); + opts.add("-XX:GuaranteedAsyncDeflationInterval=100"); + opts.addAll(Arrays.asList(args)); + opts.add("MonitorUnlinkBatchTest$Test"); + + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(opts); + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + if (msg.isEmpty()) { + oa.shouldHaveExitValue(0); + } else { + oa.shouldNotHaveExitValue(0); + oa.shouldContain(msg); + } + } + +} From 8ecc67bdb88319e7dc8c7daa4074e0b02df93cfb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 21 Mar 2024 12:25:04 +0000 Subject: [PATCH 092/298] 8303891: Speed up Zip64SizeTest using a small ZIP64 file 8259866: two java.util tests failed with "IOException: There is not enough space on the disk" Backport-of: 842b895f093e15ecd8aa0153d712f5f81cf1cf67 --- .../java/util/zip/ZipFile/Zip64SizeTest.java | 209 ++++++++++++------ 1 file changed, 137 insertions(+), 72 deletions(-) diff --git a/test/jdk/java/util/zip/ZipFile/Zip64SizeTest.java b/test/jdk/java/util/zip/ZipFile/Zip64SizeTest.java index a7afa2681a0..ca472aa2aa7 100644 --- a/test/jdk/java/util/zip/ZipFile/Zip64SizeTest.java +++ b/test/jdk/java/util/zip/ZipFile/Zip64SizeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -20,117 +20,174 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import java.io.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import static org.testng.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * @test - * @bug 8226530 - * @summary ZIP File System tests that leverage DirectoryStream + * @bug 8226530 8303891 + * @summary Verify that ZipFile reads size fields using the Zip64 extra + * field when only the 'uncompressed size' field has the ZIP64 "magic value" 0xFFFFFFFF * @compile Zip64SizeTest.java - * @run testng Zip64SizeTest + * @run junit Zip64SizeTest */ public class Zip64SizeTest { - - private static final int BUFFER_SIZE = 2048; // ZIP file to create - private static final String ZIP_FILE_NAME = "Zip64SizeTest.zip"; - // File that will be created with a size greater than 0xFFFFFFFF - private static final String LARGE_FILE_NAME = "LargeZipEntry.txt"; - // File that will be created with a size less than 0xFFFFFFFF - private static final String SMALL_FILE_NAME = "SmallZipEntry.txt"; - // List of files to be added to the ZIP file - private static final List ZIP_ENTRIES = List.of(LARGE_FILE_NAME, - SMALL_FILE_NAME); - private static final long LARGE_FILE_SIZE = 5L * 1024L * 1024L * 1024L; // 5GB - private static final long SMALL_FILE_SIZE = 0x100000L; // 1024L x 1024L; + private static final Path ZIP_FILE = Path.of("Zip64SizeTest.zip"); + // Contents to write to ZIP entries + private static final byte[] CONTENT = "Hello".getBytes(StandardCharsets.UTF_8); + // This opaque tag will be ignored by ZipEntry.setExtra0 + private static final int UNKNOWN_TAG = 0x9902; + // Tag used when converting the extra field to a real ZIP64 extra field + private static final short ZIP64_TAG = 0x1; + // Marker value to indicate that the actual value is stored in the ZIP64 extra field + private static final int ZIP64_MAGIC_VALUE = 0xFFFFFFFF; /** - * Validate that if the size of a ZIP entry exceeds 0xFFFFFFFF, that the - * correct size is returned from the ZIP64 Extended information. - * @throws IOException + * Validate that if the 'uncompressed size' of a ZIP CEN header is 0xFFFFFFFF, then the + * actual size is retrieved from the corresponding ZIP64 Extended information field. + * + * @throws IOException if an unexpected IOException occurs */ @Test - private static void validateZipEntrySizes() throws IOException { - createFiles(); + public void validateZipEntrySizes() throws IOException { createZipFile(); System.out.println("Validating Zip Entry Sizes"); - try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) { - ZipEntry ze = zip.getEntry(LARGE_FILE_NAME); + try (ZipFile zip = new ZipFile(ZIP_FILE.toFile())) { + ZipEntry ze = zip.getEntry("first"); System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize()); - assertTrue(ze.getSize() == LARGE_FILE_SIZE); - ze = zip.getEntry(SMALL_FILE_NAME); + assertEquals(CONTENT.length, ze.getSize()); + ze = zip.getEntry("second"); System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize()); - assertTrue(ze.getSize() == SMALL_FILE_SIZE); - + assertEquals(CONTENT.length, ze.getSize()); } } /** - * Delete the files created for use by the test - * @throws IOException if an error occurs deleting the files + * Create a ZIP file with a CEN entry where the 'uncompressed size' is stored in + * the ZIP64 field, but the 'compressed size' is in the CEN field. This makes the + * ZIP64 data block 8 bytes long, which triggers the regression described in 8226530. + * + * The CEN entry for the "first" entry will have the following structure: + * (Note the CEN 'Uncompressed Length' being 0xFFFFFFFF and the ZIP64 + * 'Uncompressed Size' being 5) + * + * 0081 CENTRAL HEADER #1 02014B50 + * 0085 Created Zip Spec 14 '2.0' + * 0086 Created OS 00 'MS-DOS' + * [...] Omitted for brevity + * 0091 CRC F7D18982 + * 0095 Compressed Length 00000007 + * 0099 Uncompressed Length FFFFFFFF + * [...] Omitted for brevity + * 00AF Filename 'first' + * 00B4 Extra ID #0001 0001 'ZIP64' + * 00B6 Length 0008 + * 00B8 Uncompressed Size 0000000000000005 + * + * @throws IOException if an error occurs creating the ZIP File */ - private static void deleteFiles() throws IOException { - Files.deleteIfExists(Path.of(ZIP_FILE_NAME)); - Files.deleteIfExists(Path.of(LARGE_FILE_NAME)); - Files.deleteIfExists(Path.of(SMALL_FILE_NAME)); + private static void createZipFile() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + + // The 'first' entry will store 'uncompressed size' in the Zip64 format + ZipEntry e1 = new ZipEntry("first"); + + // Make an extra field with the correct size for an 8-byte 'uncompressed size' + // Zip64 field. Temporarily use the 'unknown' tag 0x9902 to make + // ZipEntry.setExtra0 skip parsing this as a Zip64. + // See APPNOTE.TXT, 4.6.1 Third Party Mappings + byte[] opaqueExtra = createBlankExtra((short) UNKNOWN_TAG, (short) Long.BYTES); + e1.setExtra(opaqueExtra); + + zos.putNextEntry(e1); + zos.write(CONTENT); + + // A second entry, not in Zip64 format + ZipEntry e2 = new ZipEntry("second"); + zos.putNextEntry(e2); + zos.write(CONTENT); + } + + byte[] zip = baos.toByteArray(); + + // Update the CEN of 'first' to use the Zip64 format + updateCENHeaderToZip64(zip); + Files.write(ZIP_FILE, zip); } /** - * Create the ZIP file adding an entry whose size exceeds 0xFFFFFFFF - * @throws IOException if an error occurs creating the ZIP File + * Update the CEN entry of the "first" entry to use ZIP64 format for the + * 'uncompressed size' field. The updated extra field will have the following + * structure: + * + * 00B4 Extra ID #0001 0001 'ZIP64' + * 00B6 Length 0008 + * 00B8 Uncompressed Size 0000000000000005 + * + * @param zip the ZIP file to update to ZIP64 */ - private static void createZipFile() throws IOException { - try (FileOutputStream fos = new FileOutputStream(ZIP_FILE_NAME); - ZipOutputStream zos = new ZipOutputStream(fos)) { - System.out.printf("Creating Zip file: %s%n", ZIP_FILE_NAME); - for (String srcFile : ZIP_ENTRIES) { - System.out.printf("...Adding Entry: %s%n", srcFile); - File fileToZip = new File(srcFile); - try (FileInputStream fis = new FileInputStream(fileToZip)) { - ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); - zipEntry.setSize(fileToZip.length()); - zos.putNextEntry(zipEntry); - byte[] bytes = new byte[BUFFER_SIZE]; - int length; - while ((length = fis.read(bytes)) >= 0) { - zos.write(bytes, 0, length); - } - } - } - } + private static void updateCENHeaderToZip64(byte[] zip) { + ByteBuffer buffer = ByteBuffer.wrap(zip).order(ByteOrder.LITTLE_ENDIAN); + // Find the offset of the first CEN header + int cenOffset = buffer.getInt(zip.length- ZipFile.ENDHDR + ZipFile.ENDOFF); + // Find the offset of the extra field + int nlen = buffer.getShort(cenOffset + ZipFile.CENNAM); + int extraOffset = cenOffset + ZipFile.CENHDR + nlen; + + // Change the header ID from 'unknown' to ZIP64 + buffer.putShort(extraOffset, ZIP64_TAG); + // Update the 'uncompressed size' ZIP64 value to the actual uncompressed length + int fieldOffset = extraOffset + + Short.BYTES // TAG + + Short.BYTES; // data size + buffer.putLong(fieldOffset, CONTENT.length); + + // Set the 'uncompressed size' field of the CEN to 0xFFFFFFFF + buffer.putInt(cenOffset + ZipFile.CENLEN, ZIP64_MAGIC_VALUE); } /** - * Create the files that will be added to the ZIP file - * @throws IOException if there is a problem creating the files + * Create an extra field with the given tag and data block size, and a + * blank data block. + * @return an extra field with the specified tag and size + * @param tag the header id of the extra field + * @param blockSize the size of the extra field's data block */ - private static void createFiles() throws IOException { - try (RandomAccessFile largeFile = new RandomAccessFile(LARGE_FILE_NAME, "rw"); - RandomAccessFile smallFile = new RandomAccessFile(SMALL_FILE_NAME, "rw")) { - System.out.printf("Creating %s%n", LARGE_FILE_NAME); - largeFile.setLength(LARGE_FILE_SIZE); - System.out.printf("Creating %s%n", SMALL_FILE_NAME); - smallFile.setLength(SMALL_FILE_SIZE); - } + private static byte[] createBlankExtra(short tag, short blockSize) { + int size = Short.BYTES // tag + + Short.BYTES // data block size + + blockSize; // data block; + + byte[] extra = new byte[size]; + ByteBuffer.wrap(extra).order(ByteOrder.LITTLE_ENDIAN) + .putShort(0, tag) + .putShort(Short.BYTES, blockSize); + return extra; } /** * Make sure the needed test files do not exist prior to executing the test * @throws IOException */ - @BeforeMethod + @BeforeEach public void setUp() throws IOException { deleteFiles(); } @@ -139,8 +196,16 @@ public void setUp() throws IOException { * Remove the files created for the test * @throws IOException */ - @AfterMethod + @AfterEach public void tearDown() throws IOException { deleteFiles(); } + + /** + * Delete the files created for use by the test + * @throws IOException if an error occurs deleting the files + */ + private static void deleteFiles() throws IOException { + Files.deleteIfExists(ZIP_FILE); + } } From d9539f599aef5667879e7357c42da550b180e344 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 21 Mar 2024 12:28:48 +0000 Subject: [PATCH 093/298] 8325908: Finish removal of IntlTest and CollatorTest Backport-of: 4c7b313e0dc917cdaffbb2ecc86d1347683acad0 --- .../java/text/BreakIterator/Bug4533872.java | 10 ++++- test/jdk/java/text/Collator/APITest.java | 22 +++++++---- .../DateFormat/DateFormatRoundTripTest.java | 19 +++++++-- .../Format/NumberFormat/BigDecimalFormat.java | 17 ++++++-- .../Format/NumberFormat/DFSExponential.java | 39 +++++++------------ .../Format/NumberFormat/DFSSerialization.java | 4 +- test/jdk/java/util/TimeZone/Bug4322313.java | 9 ++--- 7 files changed, 73 insertions(+), 47 deletions(-) diff --git a/test/jdk/java/text/BreakIterator/Bug4533872.java b/test/jdk/java/text/BreakIterator/Bug4533872.java index b6a6f16340c..594bb2f4821 100644 --- a/test/jdk/java/text/BreakIterator/Bug4533872.java +++ b/test/jdk/java/text/BreakIterator/Bug4533872.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -21,7 +21,7 @@ * questions. */ -/** +/* * @test * @bug 4533872 4640853 * @summary Unit tests for supplementary character support (JSR-204) and Unicode 4.0 support @@ -62,6 +62,7 @@ public class Bug4533872 { /* * Test for next(int n) */ + @Test void TestNext() { iter = BreakIterator.getWordInstance(Locale.US); @@ -84,6 +85,7 @@ void TestNext() { /* * Test for isBoundary(int n) */ + @Test void TestIsBoundary() { iter = BreakIterator.getWordInstance(Locale.US); @@ -112,6 +114,7 @@ void TestIsBoundary() { /* * Test mainly for next() and current() */ + @Test void TestPrintEachForward() { iter = BreakIterator.getWordInstance(Locale.US); @@ -151,6 +154,7 @@ void TestPrintEachForward() { /* * Test mainly for previous() and current() */ + @Test void TestPrintEachBackward() { iter = BreakIterator.getWordInstance(Locale.US); @@ -190,6 +194,7 @@ void TestPrintEachBackward() { /* * Test mainly for following() and previous() */ + @Test void TestPrintAt_1() { iter = BreakIterator.getWordInstance(Locale.US); @@ -219,6 +224,7 @@ void TestPrintAt_1() { /* * Test mainly for preceding() and next() */ + @Test void TestPrintAt_2() { iter = BreakIterator.getWordInstance(Locale.US); diff --git a/test/jdk/java/text/Collator/APITest.java b/test/jdk/java/text/Collator/APITest.java index 1c2fc88a620..cbe68efb5a5 100644 --- a/test/jdk/java/text/Collator/APITest.java +++ b/test/jdk/java/text/Collator/APITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -21,13 +21,6 @@ * questions. */ -/* - * @test - * @library /java/text/testlib - * @summary test Collation API - * @modules jdk.localedata - * @run junit APITest - */ /* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved (C) Copyright IBM Corp. 1996 - All Rights Reserved @@ -40,6 +33,14 @@ Taligent is a registered trademark of Taligent, Inc. */ +/* + * @test + * @library /java/text/testlib + * @summary test Collation API + * @modules jdk.localedata + * @run junit APITest + */ + import java.util.Locale; import java.text.Collator; import java.text.RuleBasedCollator; @@ -59,6 +60,7 @@ final void doAssert(boolean condition, String message) } } + @Test public final void TestProperty( ) { Collator col = null; @@ -134,6 +136,7 @@ public final void TestProperty( ) System.out.println("Collator property test ended."); } + @Test public final void TestHashCode( ) { System.out.println("hashCode tests begin."); @@ -175,6 +178,7 @@ public final void TestHashCode( ) //---------------------------------------------------------------------------- // ctor -- Tests the constructor methods // + @Test public final void TestCollationKey( ) { System.out.println("testing CollationKey begins..."); @@ -214,6 +218,7 @@ public final void TestCollationKey( ) //---------------------------------------------------------------------------- // ctor -- Tests the constructor methods // + @Test public final void TestElemIter( ) { System.out.println("testing sortkey begins..."); @@ -306,6 +311,7 @@ public final void TestElemIter( ) System.out.println("testing CollationElementIterator ends..."); } + @Test public final void TestGetAll() { Locale[] list = Collator.getAvailableLocales(); diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java b/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java index c3f86cf0fcd..2ef57b3d19f 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatRoundTripTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -25,11 +25,22 @@ * @test * @summary test Date Format (Round Trip) * @bug 8008577 - * @run junit/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRoundTripTest + * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRoundTripTest */ -import java.text.*; -import java.util.*; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Locale; +import java.util.Random; +import java.util.SimpleTimeZone; +import java.util.TimeZone; public class DateFormatRoundTripTest { diff --git a/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java b/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java index ddb713929b4..2fa6db702fc 100644 --- a/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java +++ b/test/jdk/java/text/Format/NumberFormat/BigDecimalFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -30,8 +30,11 @@ import java.math.BigDecimal; import java.math.BigInteger; -import java.text.*; -import java.util.*; +import java.text.DecimalFormat; +import java.text.FieldPosition; +import java.text.MessageFormat; +import java.text.NumberFormat; +import java.util.Locale; import org.junit.jupiter.api.Test; @@ -98,6 +101,7 @@ public class BigDecimalFormat { /** * Test for normal big numbers which have the fraction part */ + @Test void test_Format_in_NumberFormat_BigDecimal() { String from, to; @@ -519,6 +523,7 @@ void test_Format_in_NumberFormat_BigDecimal() { /** * Test for normal big numbers which have the fraction part with multiplier */ + @Test void test_Format_in_NumberFormat_BigDecimal_usingMultiplier() { String from, to; @@ -579,6 +584,7 @@ void test_Format_in_NumberFormat_BigDecimal_usingMultiplier() { /** * Test for normal big numbers which don't have the fraction part */ + @Test void test_Format_in_NumberFormat_BigInteger() { String from, to; @@ -719,6 +725,7 @@ void test_Format_in_NumberFormat_BigInteger() { * Test for normal big numbers which don't have the fraction part with * multiplier */ + @Test void test_Format_in_NumberFormat_BigInteger_usingMultiplier() { String from, to; @@ -774,6 +781,7 @@ void test_Format_in_NumberFormat_BigInteger_usingMultiplier() { * Test for normal Long numbers when maximum and minimum digits are * specified */ + @Test void test_Format_in_NumberFormat_Long_checkDigits() { String from, to; @@ -889,6 +897,7 @@ void test_Format_in_NumberFormat_Long_checkDigits() { * Double.POSITIVE_INFINITY * Double.NEGATIVE_INFINITY */ + @Test void test_Format_in_NumberFormat_SpecialNumber() { String from, to; @@ -931,6 +940,7 @@ void test_Format_in_NumberFormat_SpecialNumber() { * (Formatting Long.MIN_VALUE w/ multiplier=-1 used to return a wrong * number.) */ + @Test void test_Format_in_NumberFormat_Other() { String from, to; @@ -963,6 +973,7 @@ void test_Format_in_NumberFormat_Other() { /** * Test for MessageFormat */ + @Test void test_Format_in_MessageFormat() { MessageFormat mf = new MessageFormat( " {0, number}\n" + diff --git a/test/jdk/java/text/Format/NumberFormat/DFSExponential.java b/test/jdk/java/text/Format/NumberFormat/DFSExponential.java index 8ad22872ae8..e421e76508e 100644 --- a/test/jdk/java/text/Format/NumberFormat/DFSExponential.java +++ b/test/jdk/java/text/Format/NumberFormat/DFSExponential.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -21,7 +21,7 @@ * questions. */ -/** +/* * @test * @bug 4068067 * @summary test NumberFormat with exponential separator symbols. It also tests the new @@ -30,37 +30,32 @@ * @run junit DFSExponential */ -import java.util.*; -import java.text.*; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.fail; -public class DFSExponential -{ - +public class DFSExponential { - public void DFSExponenTest() throws Exception { + @Test + public void TestDFSExponential() { DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US); - String pat[] = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" }; - double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 }; - long lval[] = { 0, -1, 1, 123456789 }; - String valFormat[][] = { + String[] pat = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]"}; + double[] val = { 0.01234, 123456789, 1.23e300, -3.141592653e-271}; + String[][] valFormat = { {"1.234x10^-2", "1.2346x10^8", "1.23x10^300", "-3.1416x10^-271"}, {"12.340x10^-03", "12.346x10^07", "12.300x10^299", "-31.416x10^-272"}, {"12.34x10^-003", "123.4568x10^006", "1.23x10^300", "-314.1593x10^-273"}, {"1.234x10^-2", "1.235x10^8", "1.23x10^300", "[3.142x10^-271]"}, }; - - - int ival = 0, ilval = 0; System.out.println("Default exponent separator: "+sym.getExponentSeparator()); try { sym.setExponentSeparator("x10^"); } catch (NullPointerException e){ fail("null String was passed to set an exponent separator symbol"); - throw new RuntimeException("Test Malfunction: null String was passed to set an exponent separator symbol" ); } System.out.println("Current exponent separator: "+sym.getExponentSeparator()); @@ -69,19 +64,15 @@ public void DFSExponenTest() throws Exception { System.out.println(" Pattern: " + fmt.toPattern()); String locPattern = fmt.toLocalizedPattern(); System.out.println(" Localized pattern: "+locPattern); - //fmt.applyLocalizedPattern(locPattern); - //System.out.println(" fmt.applyLocalizedPattern(): "+fmt.toLocalizedPattern()); - for (int v=0; v "+s); - if(valFormat[p][v].equals(s)){ + if (valFormat[p][v].equals(s)){ System.out.println(": Passed"); - }else{ + } else{ fail(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s); - throw new RuntimeException(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s); } } - } //end of the first for loop - } + } + } } diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java index 7e27a7ac265..dea1d68ff6e 100644 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java +++ b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,6 +48,8 @@ import static org.junit.jupiter.api.Assertions.fail; public class DFSSerialization{ + + @Test public void TestDFSSerialization(){ /* * 1. read from the object created using jdk1.4.2 diff --git a/test/jdk/java/util/TimeZone/Bug4322313.java b/test/jdk/java/util/TimeZone/Bug4322313.java index d3c87b50595..e9060bc1e54 100644 --- a/test/jdk/java/util/TimeZone/Bug4322313.java +++ b/test/jdk/java/util/TimeZone/Bug4322313.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -30,9 +30,8 @@ * @run junit Bug4322313 */ -import java.io.*; -import java.text.*; -import java.util.*; +import java.util.Locale; +import java.util.TimeZone; import org.junit.jupiter.api.Test; @@ -84,6 +83,7 @@ public class Bug4322313 { "GMT+09:00 ", }; + @Test void Test4322313() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); @@ -227,5 +227,4 @@ void Test4322313() { System.out.println("TimeZone.getTimeZone() test passed"); } } - } From 9228cdda841e8f53ff7d7653c891ba27eebf12a6 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Fri, 22 Mar 2024 02:12:22 +0000 Subject: [PATCH 094/298] 8312383: Log X509ExtendedKeyManager implementation class name in TLS/SSL connection Backport-of: bdd1aebea379b63ae405827074530ef8e8a7c239 --- .../classes/sun/security/ssl/X509Authentication.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java index 6c29db30c60..e92c7c575a6 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java +++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -201,6 +201,10 @@ public static SSLPossession createPossession( private static SSLPossession createClientPossession( ClientHandshakeContext chc, String[] keyTypes) { X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest("X509KeyManager class: " + + km.getClass().getName()); + } String clientAlias = null; if (chc.conContext.transport instanceof SSLSocketImpl socket) { clientAlias = km.chooseClientAlias( @@ -270,6 +274,10 @@ private static SSLPossession createClientPossession( private static SSLPossession createServerPossession( ServerHandshakeContext shc, String[] keyTypes) { X509ExtendedKeyManager km = shc.sslContext.getX509KeyManager(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest("X509KeyManager class: " + + km.getClass().getName()); + } String serverAlias = null; for (String keyType : keyTypes) { if (shc.conContext.transport instanceof SSLSocketImpl socket) { From bac3b94c106a485b864b84d08109d4d7fa900a17 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Fri, 22 Mar 2024 02:12:50 +0000 Subject: [PATCH 095/298] 8315663: Open source misc awt tests Backport-of: a36f5a54ab4871739f2ccbabb684942fc3cadf20 --- .../awt/Icon/SetIconImageExceptionTest.java | 59 +++++ test/jdk/sun/awt/PaletteTester.java | 204 ++++++++++++++++++ test/jdk/sun/awt/duke.gif | Bin 0 -> 1929 bytes 3 files changed, 263 insertions(+) create mode 100644 test/jdk/java/awt/Icon/SetIconImageExceptionTest.java create mode 100644 test/jdk/sun/awt/PaletteTester.java create mode 100644 test/jdk/sun/awt/duke.gif diff --git a/test/jdk/java/awt/Icon/SetIconImageExceptionTest.java b/test/jdk/java/awt/Icon/SetIconImageExceptionTest.java new file mode 100644 index 00000000000..6af6974a035 --- /dev/null +++ b/test/jdk/java/awt/Icon/SetIconImageExceptionTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4475478 + * @summary Tests that there is no NullPointerException + thrown when we try to set Frame's icon + which has null data + * @key headful + * @run main SetIconImageExceptionTest +*/ +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Toolkit; + +public class SetIconImageExceptionTest { + static Frame f; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + // Test with non-existent image to test with null data + // not throwing NPE + Image icon = Toolkit.getDefaultToolkit().getImage("notexistent.gif"); + f = new Frame("Frame with icon"); + f.setIconImage(icon); + f.setVisible(true); + } finally { + if (f != null) { + f.dispose(); + } + } + }); + } + + }// class SetIconImageExceptionTest + diff --git a/test/jdk/sun/awt/PaletteTester.java b/test/jdk/sun/awt/PaletteTester.java new file mode 100644 index 00000000000..7fb0d6b26ad --- /dev/null +++ b/test/jdk/sun/awt/PaletteTester.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4366799 + * @key headful + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary verifies that Windows applications react to palette + * changes in 8-bit mode correctly. + * @run main/manual PaletteTester +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Frame; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.VolatileImage; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import java.io.File; + +public class PaletteTester { + + static VImageColors demo; + + private static final String INSTRUCTIONS = """ + This test should be run on any Windows platform in 8-bit + (256 color) display mode only. To check for errors, run a browser + application (Firefox or Internet Explorer) at the same time + and switch between this test and the browser (by clicking on the + title bars). + + The three panels in this test should look roughly the same (there + may be some dithering differences if you switch display modes + during the test, but the overall look should be the same. If + completely different colors are being used (either for the orange + background fill, the text, the image, or the rectangles), then the + test has failed. + """; + + private static void init() { + + int width = 300, height = 300; + + demo = new VImageColors(); + Frame f = new Frame("PaletteTester"); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) {} + public void windowDeiconified(WindowEvent e) { demo.start(); } + public void windowIconified(WindowEvent e) { demo.stop(); } + }); + f.add(demo); + f.setSize(new Dimension(width, height)); + f.setLocationRelativeTo(null); + + PassFailJFrame.addTestWindow(f); + PassFailJFrame.positionTestWindow(f, PassFailJFrame.Position.HORIZONTAL); + f.setVisible(true); + + demo.start(); + + }//End init() + + public static void main( String args[] ) throws Exception { + + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("PaletteTester Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(5) + .rows(15) + .columns(40) + .screenCapture() + .build(); + + EventQueue.invokeAndWait(PaletteTester::init); + + + try { + passFailJFrame.awaitAndCheck(); + } finally { + demo.stop(); + } + }//main +} + +//************ Begin classes defined for the test **************** + +class VImageColors extends JPanel implements Runnable { + + VolatileImage vImage; + Image bImage; + private static int width = 300, height = 300; + private Thread thread; + Color fillColor = new Color(240, 188, 136); + Color textColor = new Color(40, 18, 97); + Color rectColor = new Color(0, 150, 0); + File f = new File(System.getProperty("test.src", "."), "duke.gif"); + Image duke = new ImageIcon(f.toString()).getImage(); + + public void initOffscreen() { + vImage = this.createVolatileImage(getWidth()/3, getHeight()); + bImage = this.createImage(getWidth()/3, getHeight()); + } + + public void paint(Graphics g) { + int width = getWidth(); + int height = getHeight(); + + if (vImage == null) { + initOffscreen(); + } + + // Render the left panel via VolatileImage + do { + if ( + vImage.validate(getGraphicsConfiguration()) == + VolatileImage.IMAGE_INCOMPATIBLE) + { + vImage = createVolatileImage(width/3, height); + } + Graphics vg = vImage.createGraphics(); + vg.setColor(fillColor); + vg.fillRect(0, 0, width/3, height); + vg.drawImage(duke, 0, 0, null); + vg.setColor(textColor); + vg.drawString("Vol Image", 5, height-1); + vg.setColor(rectColor); + vg.drawRect(0, 0, width/3-1, height-1); + vg.dispose(); + g.drawImage(vImage, 0, 0, width/3, height, null); + } while (vImage.contentsLost()); + + // Render the middle panel via BufferedImage + Graphics bg = bImage.getGraphics(); + bg.setColor(fillColor); + bg.fillRect(0, 0, width/3, height); + bg.drawImage(duke, 0, 0, null); + bg.setColor(textColor); + bg.drawString("Buff Image", 5, height-1); + bg.setColor(rectColor); + bg.drawRect(0, 0, width/3-1, height-1); + bg.dispose(); + g.drawImage(bImage, width/3, 0, width/3, height, null); + + // Render the right panel directly to the screen + g.setColor(fillColor); + g.fillRect(2*(width/3), 0, width/3, height); + g.drawImage(duke, 2*(width/3), 0, null); + g.setColor(textColor); + g.drawString("Screen", 2*(width/3) + 5, height-1); + g.setColor(rectColor); + g.drawRect(2*(width/3), 0, width/3-1, height-1); + + } + + public void start() { + thread = new Thread(this); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public synchronized void stop() { + thread = null; + } + + public void run() { + Thread me = Thread.currentThread(); + while (thread == me) { + try { + thread.sleep(100); + } catch (InterruptedException e) { break; } + } + thread = null; + } +} + +//************** End classes defined for the test ******************* diff --git a/test/jdk/sun/awt/duke.gif b/test/jdk/sun/awt/duke.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed32e0ff79b05c07b82863ce6fb07fa9898adaa2 GIT binary patch literal 1929 zcmWlYe^AtB8pi`HvM4_?{J2I$8$dLc1#@!R2zwgXMWdj^k;9xr+bDW&4{JlE8WpDj z7F-cwwK{H<)?L&#SJz$!;hJ{%BY2FYf)Wp^xl?aq!5Xcdi$c#hV~>m9_n-Hl=Xsy+ z=li^?*Q~;pZ+R1N1J40KRkeWM7ew3~jLM24A{CM-A}~TzqzYpq&od0GC=z71!w_=b z-==B0rt2t*nA}((5YSLs6a*Z@X__WqiSjTW6oLo{5km&|K1mGAimYjhs#wwZtvV8SV~7LCFpgub+-TTAk%UQb0dE_cj+pc?!+0o?qG$?% zVFD)%!w7Z;g)ndE8Uk6Aky=+kLaUQ{UW`XS?Nn*s@SQ{VmFgGdkV{&&98EcEQ5hjc@H$`e)fX zj@&GdchxpMUo|-A^M4iBP3(#Ib53Ap?5{nGT7SBA_V!o!TTzL5R~FUWe)4X?@iTd8 z1;TcF^rQLj?4p0uy?@ikb2eUSXdHVa_jIn=@W%a<6~57D>am6&Z!{lzc=@ZbuGB8` zpU38H8d~@82Da!+qdYG5ls&Cx?~|oPMnbqTHMw%I*KlV~?fc{rSwe29?Om}fsknG# z@n5IwY=4Mx>>0WJLG>=yJX^WbHA30iQ$H!X)3<4K zBe1|sf3NKKTS;)mg{$k(2eDJG^u5=&x{@M!V>EWgzRA((>}?o{WQBehp1mIHU!BGG zYz5_6B(+KIVdCVoum2ItM&gXZd+SB^vQTN=a zeYbbah=i-xCho2{4Pazv_i%2mH`EkM{r8XYDLbdY@(a7Ud}$%!$QrTN_DqwNXA9~g zTGKxKyfto7NDp;5A3O5zgb(hyxjN@OAG!(zy^*Ug4!yjF=Y*8aHA@ovB1({&a4;sR zTf1CVC{>Pgy`m$lG;P1$pC_6F7u%iP+qz0q4{lXT`i9g-ThiYgO^GXC`f?JNo*|@p zr{b%U-tSKw99q0|YJa9{Va?`H{IaNICo>p5lGEY*+IDR4bfIUwq~CTRuC_mGWA%~W zea{@eKJ(Iq^7MvdsPsR%&vt$@4i&s?bPptz#y#!FcRZEaMS0WFTyXMCUEfsNxnJ_9 zPwpt`Er4O>``2G{7=4r1GCSTO8#0xw+{<^L4X(K8y1wKj72KLrYD}Y7SJuY7y==wf z;UkI5?(v?h+4r;vR{P*U`ul~=D@U7K5$eV8c!%rX-38vE>azU80UrhFXCv#d`(ylZS4+i2a^vI91MTIxCx%9gd2&N&D9RC&xcpx8#f=GZv%9;F z#?CEVT%UV$nk;L%RJA+d=f8ZB@U*Xz-TZbG?HKKT(VJZMBH!)$#qRuwbFc%Aljqha zoNBs8od~V$_^vux0ZSk!iP!hI($t35SxY8`FV{pxCjpU}Ova2VIg1&>V)CvvMb_ Date: Fri, 22 Mar 2024 08:26:13 +0000 Subject: [PATCH 096/298] 8328165: improve assert(idx < _maxlrg) failed: oob Backport-of: d57bdd85ab5e45a2ecfce0c022da067ac30bb80d --- src/hotspot/share/opto/chaitin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/chaitin.hpp b/src/hotspot/share/opto/chaitin.hpp index dd917571b06..d3c9e14bc7c 100644 --- a/src/hotspot/share/opto/chaitin.hpp +++ b/src/hotspot/share/opto/chaitin.hpp @@ -292,7 +292,7 @@ class PhaseIFG : public Phase { #endif //--------------- Live Range Accessors - LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob"); return _lrgs[idx]; } + LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob: index %u not smaller than %u", idx, _maxlrg); return _lrgs[idx]; } // Compute and set effective degree. Might be folded into SquareUp(). void Compute_Effective_Degree(); From 8c6e32dc0ee4fbba183e4bccd728ef46d39bde9a Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 25 Mar 2024 08:53:01 +0000 Subject: [PATCH 097/298] 8326960: GHA: RISC-V sysroot cannot be debootstrapped due to ongoing Debian t64 transition Backport-of: f207aa94f9296932276c2952252b263efc793b3f --- .github/workflows/build-cross-compile.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 8f88075e112..3f5206c486f 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -61,27 +61,32 @@ jobs: debian-arch: arm64 debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: arm gnu-arch: arm debian-arch: armhf debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false gnu-abi: eabihf - target-cpu: s390x gnu-arch: s390x debian-arch: s390x debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: ppc64le gnu-arch: powerpc64le debian-arch: ppc64el debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: riscv64 gnu-arch: riscv64 debian-arch: riscv64 debian-repository: https://httpredir.debian.org/debian/ debian-version: sid + tolerate-sysroot-errors: true steps: - name: 'Checkout the JDK source' @@ -130,6 +135,7 @@ jobs: if: steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Create sysroot' + id: create-sysroot run: > sudo debootstrap --arch=${{ matrix.debian-arch }} @@ -140,6 +146,7 @@ jobs: ${{ matrix.debian-version }} sysroot ${{ matrix.debian-repository }} + continue-on-error: ${{ matrix.tolerate-sysroot-errors }} if: steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Prepare sysroot' @@ -151,7 +158,12 @@ jobs: rm -rf sysroot/usr/{sbin,bin,share} rm -rf sysroot/usr/lib/{apt,gcc,udev,systemd} rm -rf sysroot/usr/libexec/gcc - if: steps.get-cached-sysroot.outputs.cache-hit != 'true' + if: steps.create-sysroot.outcome == 'success' && steps.get-cached-sysroot.outputs.cache-hit != 'true' + + - name: 'Remove broken sysroot' + run: | + sudo rm -rf sysroot/ + if: steps.create-sysroot.outcome != 'success' && steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Configure' run: > @@ -173,6 +185,7 @@ jobs: echo "Dumping config.log:" && cat config.log && exit 1) + if: steps.create-sysroot.outcome == 'success' - name: 'Build' id: build @@ -180,3 +193,4 @@ jobs: with: make-target: 'hotspot ${{ inputs.make-arguments }}' platform: linux-${{ matrix.target-cpu }} + if: steps.create-sysroot.outcome == 'success' From 39f717876ac18bc3c0aeb87b2b3de9b02ed808ed Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 25 Mar 2024 10:26:41 +0000 Subject: [PATCH 098/298] 8324998: Add test cases for String.regionMatches comparing Turkic dotted/dotless I with uppercase latin I Backport-of: c3c1d5bd12f80c6a720e431961e90b09c2d972f9 --- test/jdk/java/lang/String/CompactString/RegionMatches.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/lang/String/CompactString/RegionMatches.java b/test/jdk/java/lang/String/CompactString/RegionMatches.java index e796708a5e7..0364d0ea2e1 100644 --- a/test/jdk/java/lang/String/CompactString/RegionMatches.java +++ b/test/jdk/java/lang/String/CompactString/RegionMatches.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -96,9 +96,13 @@ public Object[][] provider() { // Turkish I with dot new Object[] { "\u0130", false, 0, "i", 0, 1, false }, new Object[] { "\u0130", true, 0, "i", 0, 1, true }, + new Object[] { "\u0130", false, 0, "I", 0, 1, false }, + new Object[] { "\u0130", true, 0, "I", 0, 1, true }, // i without dot new Object[] { "\u0131", false, 0, "i", 0, 1, false }, new Object[] { "\u0131", true, 0, "i", 0, 1, true }, + new Object[] { "\u0131", false, 0, "I", 0, 1, false }, + new Object[] { "\u0131", true, 0, "I", 0, 1, true }, // Exhaustive list of 1-char latin1 strings that match // case-insensitively: // for (char c1 = 0; c1 < 255; c1++) { From 5694ad27abe33d1283d2e0e43e064cdb5635de5e Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 25 Mar 2024 10:28:09 +0000 Subject: [PATCH 099/298] 8303972: (zipfs) Make test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java independent of the zip command line 8301183: (zipfs) jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java failing with ZipException:R0 on OL9 Backport-of: 7004c2724d9b150112c66febb7f24b781ff379dd --- test/jdk/ProblemList.txt | 2 - .../nio/zipfs/TestLocOffsetFromZip64EF.java | 282 ++++++++++-------- 2 files changed, 165 insertions(+), 119 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 4c794f552a7..cbad8670a83 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -562,8 +562,6 @@ java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc6 java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64 java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all -jdk/nio/zipfs/TestLocOffsetFromZip64EF.java 8301183 linux-all - java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc64 ############################################################################ diff --git a/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java index 3084687c249..7fc789d5606 100644 --- a/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java +++ b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -21,50 +21,72 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; -import java.util.List; +import java.nio.file.attribute.FileTime; +import java.time.Instant; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; -import static java.lang.String.format; /** * @test * @bug 8255380 8257445 * @summary Test that Zip FS can access the LOC offset from the Zip64 extra field * @modules jdk.zipfs - * @requires (os.family == "linux") | (os.family == "mac") - * @run testng/manual TestLocOffsetFromZip64EF + * @run junit TestLocOffsetFromZip64EF */ public class TestLocOffsetFromZip64EF { - private static final String ZIP_FILE_NAME = "LargeZipTest.zip"; - // File that will be created with a size greater than 0xFFFFFFFF - private static final String LARGE_FILE_NAME = "LargeZipEntry.txt"; - // File that will be created with a size less than 0xFFFFFFFF - private static final String SMALL_FILE_NAME = "SmallZipEntry.txt"; - // The size (4GB) of the large file to be created - private static final long LARGE_FILE_SIZE = 4L * 1024L * 1024L * 1024L; + private static final String ZIP_FILE_NAME = "LocOffsetFromZip64.zip"; + + // Size of the data block of a Zip64 extended information field with long + // fields for 'uncompressed size', 'compressed size' and 'local header offset' + private static short ZIP64_DATA_SIZE = (short) Long.BYTES // Uncompressed size + + Long.BYTES // Compressed size + + Long.BYTES; // Loc offset + + // Size of the extra field header + private static short EXTRA_HEADER_SIZE = Short.BYTES // tag + + Short.BYTES; // data size + + // Size of a Zip64 extended information field including the header + private static final int ZIP64_SIZE = EXTRA_HEADER_SIZE + ZIP64_DATA_SIZE; + + // The Zip64 Magic value for 32-bit fields + private static final int ZIP64_MAGIC_VALUE = 0XFFFFFFFF; + // The 'unknown' tag, see APPNOTE.txt + private static final short UNKNOWN_TAG = (short) 0x9902; + // The 'Zip64 extended information' tag, see APPNOTE.txt + private static final short ZIP64_TAG = (short) 0x1; /** * Create the files used by this test + * * @throws IOException if an error occurs */ - @BeforeClass + @BeforeEach public void setUp() throws IOException { - System.out.println("In setup"); cleanup(); - createFiles(); createZipWithZip64Ext(); } @@ -72,39 +94,22 @@ public void setUp() throws IOException { * Delete files used by this test * @throws IOException if an error occurs */ - @AfterClass + @AfterEach public void cleanup() throws IOException { - System.out.println("In cleanup"); Files.deleteIfExists(Path.of(ZIP_FILE_NAME)); - Files.deleteIfExists(Path.of(LARGE_FILE_NAME)); - Files.deleteIfExists(Path.of(SMALL_FILE_NAME)); - } - - /** - * Create a Zip file that will result in a Zip64 Extra (EXT) header - * being added to the CEN entry in order to find the LOC offset for - * SMALL_FILE_NAME. - */ - public static void createZipWithZip64Ext() { - System.out.println("Executing zip..."); - List commands = List.of("zip", "-0", ZIP_FILE_NAME, - LARGE_FILE_NAME, SMALL_FILE_NAME); - Result rc = run(new ProcessBuilder(commands)); - rc.assertSuccess(); } /* - * DataProvider used to verify that a Zip file that contains a Zip64 Extra + * MethodSource used to verify that a Zip file that contains a Zip64 Extra * (EXT) header can be traversed */ - @DataProvider(name = "zipInfoTimeMap") - protected Object[][] zipInfoTimeMap() { - return new Object[][]{ - {Map.of()}, - {Map.of("zipinfo-time", "False")}, - {Map.of("zipinfo-time", "true")}, - {Map.of("zipinfo-time", "false")} - }; + static Stream> zipInfoTimeMap() { + return Stream.of( + Map.of(), + Map.of("zipinfo-time", "False"), + Map.of("zipinfo-time", "true"), + Map.of("zipinfo-time", "false") + ); } /** @@ -112,8 +117,11 @@ protected Object[][] zipInfoTimeMap() { * @param env Zip FS properties to use when accessing the Zip file * @throws IOException if an error occurs */ - @Test(dataProvider = "zipInfoTimeMap") + @ParameterizedTest + @MethodSource("zipInfoTimeMap") public void walkZipFSTest(final Map env) throws IOException { + Set entries = new HashSet<>(); + try (FileSystem fs = FileSystems.newFileSystem(Paths.get(ZIP_FILE_NAME), env)) { for (Path root : fs.getRootDirectories()) { @@ -121,6 +129,7 @@ public void walkZipFSTest(final Map env) throws IOException { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + entries.add(file.getFileName().toString()); System.out.println(Files.readAttributes(file, BasicFileAttributes.class).toString()); return FileVisitResult.CONTINUE; @@ -128,6 +137,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes }); } } + // Sanity check that ZIP file had the expected entries + assertEquals(Set.of("entry", "entry2", "entry3"), entries); } /** @@ -139,92 +150,129 @@ public void walkZipFileTest() throws IOException { try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) { zip.stream().forEach(z -> System.out.printf("%s, %s, %s%n", z.getName(), z.getMethod(), z.getLastModifiedTime())); - } - } - /** - * Create the files that will be added to the ZIP file - * @throws IOException if there is a problem creating the files - */ - private static void createFiles() throws IOException { - try (RandomAccessFile file = new RandomAccessFile(LARGE_FILE_NAME, "rw") - ) { - System.out.printf("Creating %s%n", LARGE_FILE_NAME); - file.setLength(LARGE_FILE_SIZE); - System.out.printf("Creating %s%n", SMALL_FILE_NAME); - Files.writeString(Path.of(SMALL_FILE_NAME), "Hello"); + // Sanity check that ZIP file had the expected entries + assertEquals(zip.stream().map(ZipEntry::getName).collect(Collectors.toSet()), + Set.of("entry", "entry2", "entry3")); } } /** - * Utility method to execute a ProcessBuilder command - * @param pb ProcessBuilder to execute - * @return The Result(s) from the ProcessBuilder execution + * This produces a ZIP with similar features as the one created by 'Info-ZIP' which + * caused 'Extended timestamp' parsing to fail before JDK-8255380. + * + * The issue was sensitive to the ordering of 'Info-ZIP extended timestamp' fields and + * 'Zip64 extended information' fields. ZipOutputStream and 'Info-ZIP' order these differently. + * + * ZipFileSystem tried to read the Local file header while parsing the extended timestamp, + * but if the Zip64 extra field was not read yet, ZipFileSystem would incorrecly try to read + * the Local File header from offset 0xFFFFFFFF. + * + * This method creates a ZIP file which includes a CEN with the following features: + * + * - Its extra field has a 'Info-ZIP extended timestamp' field followed by a + * 'Zip64 extended information' field. + * - The sizes and offset fields values of the CEN are set to 0xFFFFFFFF (Zip64 magic values) + * */ - private static Result run(ProcessBuilder pb) { - Process p; - System.out.printf("Running: %s%n", pb.command()); - try { - p = pb.start(); - } catch (IOException e) { - throw new RuntimeException( - format("Couldn't start process '%s'", pb.command()), e); - } + public void createZipWithZip64Ext() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (ZipOutputStream zo = new ZipOutputStream(out)) { - String output; - try { - output = toString(p.getInputStream(), p.getErrorStream()); - } catch (IOException e) { - throw new RuntimeException( - format("Couldn't read process output '%s'", pb.command()), e); - } + ZipEntry e = new ZipEntry("entry"); + // Add an entry, make it STORED and empty to simplify parsing + e.setMethod(ZipEntry.STORED); + e.setSize(0); + e.setCrc(0); + zo.putNextEntry(e); + + // Add an additional entry as a sanity check that we can navigate past the first + ZipEntry e2 = new ZipEntry("entry2"); + e2.setMethod(ZipEntry.STORED); + e2.setSize(0); + e2.setCrc(0); + zo.putNextEntry(e2); + + // For good measure, add a third, DEFLATED entry with some content + ZipEntry e3 = new ZipEntry("entry3"); + e3.setMethod(ZipEntry.DEFLATED); + zo.putNextEntry(e3); + zo.write("Hello".getBytes(StandardCharsets.UTF_8)); - try { - p.waitFor(); - } catch (InterruptedException e) { - throw new RuntimeException( - format("Process hasn't finished '%s'", pb.command()), e); + zo.closeEntry(); // At this point, all LOC headers are written. + + // We want the first CEN entry to have two extra fields: + // 1: A 'Info-Zip extended timestamp' extra field, generated by ZipOutputStream + // when the following date fields are set: + e.setLastModifiedTime(FileTime.from(Instant.now())); + e.setLastAccessTime(FileTime.from(Instant.now())); + + // 2: An opaque extra field, right-sized for a Zip64 extended field, + // to be updated below + byte[] zip64 = makeOpaqueExtraField(); + e.setExtra(zip64); + + zo.finish(); // Write out CEN and END records } - return new Result(p.exitValue(), output); + + byte[] zip = out.toByteArray(); + + // ZIP now has the right structure, but we need to update the CEN to Zip64 format + updateToZip64(zip); + // Write the ZIP to disk + Files.write(Path.of(ZIP_FILE_NAME), zip); } /** - * Utility Method for combining the output from a ProcessBuilder invocation - * @param in1 ProccessBuilder.getInputStream - * @param in2 ProcessBuilder.getErrorStream - * @return The ProcessBuilder output - * @throws IOException if an error occurs + * Returns an opaque extra field with the tag 'unknown', which makes ZipEntry.setExtra ignore it. + * The returned field has the expected field and data size of a Zip64 extended information field + * including the fields 'uncompressed size' (8 bytes), 'compressed size' (8 bytes) and + * 'local header offset' (8 bytes). */ - static String toString(InputStream in1, InputStream in2) throws IOException { - try (ByteArrayOutputStream dst = new ByteArrayOutputStream(); - InputStream concatenated = new SequenceInputStream(in1, in2)) { - concatenated.transferTo(dst); - return new String(dst.toByteArray(), StandardCharsets.UTF_8); - } + private static byte[] makeOpaqueExtraField() { + byte[] zip64 = new byte[ZIP64_SIZE]; + ByteBuffer buffer = ByteBuffer.wrap(zip64).order(ByteOrder.LITTLE_ENDIAN); + // Using the 'unknown' tag makes ZipEntry.setExtra ignore it + buffer.putShort(UNKNOWN_TAG); + // Data size + buffer.putShort(ZIP64_DATA_SIZE); + return zip64; } /** - * Utility class used to hold the results from a ProcessBuilder execution + * Update the CEN record to Zip64 format */ - static class Result { - final int ec; - final String output; + private static void updateToZip64(byte[] bytes) throws IOException { - private Result(int ec, String output) { - this.ec = ec; - this.output = output; - } - Result assertSuccess() { - assertTrue(ec == 0, "Expected ec 0, got: ", ec, " , output [", output, "]"); - return this; - } + ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); + + // Look up CEN offset from the End of central directory header + int cenOff = getCenOffet(buffer); + + // Read name, extra field and comment lengths from CEN + short nlen = buffer.getShort(cenOff + ZipFile.CENNAM); + short elen = buffer.getShort(cenOff + ZipFile.CENEXT); + + // Update CEN sizes and loc offset to 0xFFFFFFFF, meaning + // actual values should be read from the Zip64 field + buffer.putInt(cenOff + ZipFile.CENLEN, ZIP64_MAGIC_VALUE); + buffer.putInt(cenOff + ZipFile.CENSIZ, ZIP64_MAGIC_VALUE); + buffer.putInt(cenOff + ZipFile.CENOFF, ZIP64_MAGIC_VALUE); + + // Offset of the extra fields + int extraOff = cenOff + ZipFile.CENHDR + nlen; + + // Position at the start of the Zip64 extra field + int zip64ExtraOff = extraOff + elen - ZIP64_SIZE; + + // Update tag / Header ID to be the actual Zip64 tag instead of the 'unknown' + buffer.putShort(zip64ExtraOff, ZIP64_TAG); } - static void assertTrue(boolean cond, Object ... failedArgs) { - if (cond) - return; - StringBuilder sb = new StringBuilder(); - for (Object o : failedArgs) - sb.append(o); - Assert.fail(sb.toString()); + + /** + * Look up the CEN offset field from the End of central directory header + */ + private static int getCenOffet(ByteBuffer buffer) { + return buffer.getInt(buffer.capacity() - ZipFile.ENDHDR + ZipFile.ENDOFF); } } From 3050bf3bd034b6b68a9c8fe09060c4e0a5472785 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 25 Mar 2024 10:28:27 +0000 Subject: [PATCH 100/298] 8159927: Add a test to verify JMOD files created in the images do not have debug symbols Backport-of: 6c0bebccb0092d9726eb89a054e023e92edf7ca6 --- .../jdk/modules/etc/JmodExcludedFiles.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 test/jdk/jdk/modules/etc/JmodExcludedFiles.java diff --git a/test/jdk/jdk/modules/etc/JmodExcludedFiles.java b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java new file mode 100644 index 00000000000..c3ec4408232 --- /dev/null +++ b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java @@ -0,0 +1,76 @@ +/* + * 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. + */ + +/** + * @test + * @bug 8159927 + * @modules java.base/jdk.internal.util + * @run main JmodExcludedFiles + * @summary Test that JDK JMOD files do not include native debug symbols + */ + +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import jdk.internal.util.OperatingSystem; + +public class JmodExcludedFiles { + public static void main(String[] args) throws Exception { + String javaHome = System.getProperty("java.home"); + Path jmods = Path.of(javaHome, "jmods"); + try (DirectoryStream stream = Files.newDirectoryStream(jmods, "*.jmod")) { + for (Path jmodFile : stream) { + try (ZipFile zip = new ZipFile(jmodFile.toFile())) { + if (zip.stream().map(ZipEntry::getName) + .anyMatch(JmodExcludedFiles::isNativeDebugSymbol)) { + throw new RuntimeException(jmodFile + " is expected not to include native debug symbols"); + } + } + } + } + } + + private static boolean isNativeDebugSymbol(String name) { + int index = name.indexOf("/"); + if (index < 0) { + throw new RuntimeException("unexpected entry name: " + name); + } + String section = name.substring(0, index); + if (section.equals("lib") || section.equals("bin")) { + if (OperatingSystem.isMacOS()) { + String n = name.substring(index+1); + int i = n.indexOf("/"); + if (i != -1) { + return n.substring(0, i).endsWith(".dSYM"); + } + } + return name.endsWith(".diz") + || name.endsWith(".debuginfo") + || name.endsWith(".map") + || name.endsWith(".pdb"); + } + return false; + } +} From 7d4a6fc01b45272fda1888c6ba0b974fe7995462 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Mon, 25 Mar 2024 13:31:15 +0000 Subject: [PATCH 101/298] 8326591: New test JmodExcludedFiles.java fails on Windows when --with-external-symbols-in-bundles=public is used Backport-of: 43c6f0b5880899b797fab2f851bd35be1c342439 --- .../jdk/modules/etc/JmodExcludedFiles.java | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/test/jdk/jdk/modules/etc/JmodExcludedFiles.java b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java index c3ec4408232..6c338a25b4f 100644 --- a/test/jdk/jdk/modules/etc/JmodExcludedFiles.java +++ b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java @@ -32,19 +32,22 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import jdk.internal.util.OperatingSystem; public class JmodExcludedFiles { + private static String javaHome = System.getProperty("java.home"); + public static void main(String[] args) throws Exception { - String javaHome = System.getProperty("java.home"); Path jmods = Path.of(javaHome, "jmods"); try (DirectoryStream stream = Files.newDirectoryStream(jmods, "*.jmod")) { for (Path jmodFile : stream) { try (ZipFile zip = new ZipFile(jmodFile.toFile())) { + JModSymbolFileMatcher jsfm = new JModSymbolFileMatcher(jmodFile.toString()); if (zip.stream().map(ZipEntry::getName) - .anyMatch(JmodExcludedFiles::isNativeDebugSymbol)) { + .anyMatch(jsfm::isNativeDebugSymbol)) { throw new RuntimeException(jmodFile + " is expected not to include native debug symbols"); } } @@ -52,25 +55,47 @@ public static void main(String[] args) throws Exception { } } - private static boolean isNativeDebugSymbol(String name) { - int index = name.indexOf("/"); - if (index < 0) { - throw new RuntimeException("unexpected entry name: " + name); + static class JModSymbolFileMatcher { + private String jmod; + + JModSymbolFileMatcher(String jmod) { + this.jmod = jmod; } - String section = name.substring(0, index); - if (section.equals("lib") || section.equals("bin")) { - if (OperatingSystem.isMacOS()) { - String n = name.substring(index+1); - int i = n.indexOf("/"); - if (i != -1) { - return n.substring(0, i).endsWith(".dSYM"); + + boolean isNativeDebugSymbol(String name) { + int index = name.indexOf("/"); + if (index < 0) { + throw new RuntimeException("unexpected entry name: " + name); + } + String section = name.substring(0, index); + if (section.equals("lib") || section.equals("bin")) { + if (OperatingSystem.isMacOS()) { + String n = name.substring(index + 1); + int i = n.indexOf("/"); + if (i != -1) { + if (n.substring(0, i).endsWith(".dSYM")) { + System.err.println("Found symbols in " + jmod + ": " + name); + return true; + } + } + } + if (OperatingSystem.isWindows() && name.endsWith(".pdb")) { + // on Windows we check if we should have public symbols through --with-external-symbols-in-bundles=public (JDK-8237192) + String strippedpdb = javaHome + "/bin/" + name.substring(index + 1, name.length() - 4) + ".stripped.pdb"; + if (!Files.exists(Paths.get(strippedpdb))) { + System.err.println("Found symbols in " + jmod + ": " + name + + ". No stripped pdb file " + strippedpdb + " exists."); + return true; + } + } + if (name.endsWith(".diz") + || name.endsWith(".debuginfo") + || name.endsWith(".map")) { + System.err.println("Found symbols in " + jmod + ": " + name); + return true; } } - return name.endsWith(".diz") - || name.endsWith(".debuginfo") - || name.endsWith(".map") - || name.endsWith(".pdb"); + return false; } - return false; } } From 6b85c74f3bfc43e5ab2a3b90d7e8f1bfe927ba6c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 14:31:00 +0000 Subject: [PATCH 102/298] 8316164: Opensource JMenuBar manual test Backport-of: 8f4dfc443ba5820f5799fff1418d6632d502d57b --- test/jdk/javax/swing/JMenuBar/bug4403749.java | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 test/jdk/javax/swing/JMenuBar/bug4403749.java diff --git a/test/jdk/javax/swing/JMenuBar/bug4403749.java b/test/jdk/javax/swing/JMenuBar/bug4403749.java new file mode 100644 index 00000000000..e98c0eaee3f --- /dev/null +++ b/test/jdk/javax/swing/JMenuBar/bug4403749.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4403749 + * @summary Tests that keyboard accelerator implementation in JMenuBar is + MenuElement aware + * @key headful + * @run main bug4403749 + */ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; + +public class bug4403749 { + static JFrame frame; + static volatile Point pt; + static volatile Dimension dim; + static volatile boolean passed; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4403749"); + JMenuBar mbar = new JMenuBar(); + JMenu menu = new JMenu("Menu"); + JPanel panel = new TestMenuElement(); + menu.add(panel); + mbar.add(menu); + frame.setJMenuBar(mbar); + + frame.getContentPane().add(new JButton("")); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pt = frame.getLocationOnScreen(); + dim = frame.getSize(); + }); + robot.mouseMove(pt.x + dim.width / 2, pt.y + dim.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(200); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_ALT); + if (!passed) { + throw new RuntimeException("Failed: processKeyBinding wasn't called"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + static class TestMenuElement extends JPanel implements MenuElement { + public void processMouseEvent(MouseEvent event, + MenuElement[] path, + MenuSelectionManager manager) {} + + public void processKeyEvent(KeyEvent event, + MenuElement[] path, + MenuSelectionManager manager) {} + + public void menuSelectionChanged(boolean isIncluded) {} + + public MenuElement[] getSubElements() { + return new MenuElement[0]; + } + + public Component getComponent() { + return this; + } + + protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, + int condition, boolean pressed) { + passed = true; + return super.processKeyBinding(ks, e, condition, pressed); + } + } +} From f96f632e6a1aa23cd95767994d23d2f84be367c3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 14:32:45 +0000 Subject: [PATCH 103/298] 8315741: Open source few swing JFormattedTextField and JPopupMenu tests Backport-of: bfbc41c1f177c7a2b8e91351ac41eaffaab2d8fc --- .../swing/JFormattedTextField/bug4741926.java | 134 ++++++++++++++++++ .../swing/JFormattedTextField/bug4863121.java | 101 +++++++++++++ .../swing/JFormattedTextField/bug4886538.java | 75 ++++++++++ .../javax/swing/JPopupMenu/bug4123919.java | 74 ++++++++++ .../javax/swing/JPopupMenu/bug4197019.java | 102 +++++++++++++ 5 files changed, 486 insertions(+) create mode 100644 test/jdk/javax/swing/JFormattedTextField/bug4741926.java create mode 100644 test/jdk/javax/swing/JFormattedTextField/bug4863121.java create mode 100644 test/jdk/javax/swing/JFormattedTextField/bug4886538.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4123919.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4197019.java diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4741926.java b/test/jdk/javax/swing/JFormattedTextField/bug4741926.java new file mode 100644 index 00000000000..58725e68780 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4741926.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4741926 + * @summary JFormattedTextField/JSpinner always consumes certain key events + * @key headful + * @run main bug4741926 + */ + +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.util.Date; +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +public class bug4741926 { + + static MyFormattedTextField ftf; + static JFrame fr; + static Robot robot; + static volatile boolean passed_enter = false; + static volatile boolean passed_escape = false; + static volatile boolean ftfFocused = false; + static volatile boolean keyProcessed = false; + + public static void main(String[] args) throws Exception { + + try { + robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + ftf = new MyFormattedTextField(); + ftf.setValue("JFormattedTextField"); + JPanel p = (JPanel) fr.getContentPane(); + p.add(ftf); + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + ftfFocused = true; + } + }); + InputMap map = p.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); + + map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), + "enter-action"); + p.getActionMap().put("enter-action", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + passed_enter = true; + keyProcessed = true; + } + }); + map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + "escape-action"); + p.getActionMap().put("escape-action", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + passed_escape = true; + keyProcessed = true; + } + }); + fr.pack(); + fr.setLocationRelativeTo(null); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + test(); + if (!(passed_enter && passed_escape)) { + throw new RuntimeException("JFormattedTextField consume " + + "Enter/Escape key event"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static void test() throws Exception { + SwingUtilities.invokeAndWait(() -> { + ftf.requestFocus(); + }); + robot.delay(500); + doTest(KeyEvent.VK_ENTER); + doTest(KeyEvent.VK_ESCAPE); + } + + static void doTest(int keyCode) throws InterruptedException { + keyProcessed = false; + KeyEvent key = new KeyEvent(ftf, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, + keyCode, + KeyEvent.CHAR_UNDEFINED); + ftf.processKey(key); + } + + static class MyFormattedTextField extends JFormattedTextField { + public void processKey(KeyEvent e) { + processKeyEvent(e); + } + } +} diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4863121.java b/test/jdk/javax/swing/JFormattedTextField/bug4863121.java new file mode 100644 index 00000000000..22e50f087c7 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4863121.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4863121 + * @summary JFormattedTextField's NotifyAction should invoke invalidEdit if + commit fails + * @key headful + * @run main bug4863121 + */ + +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.text.Format; +import java.text.DecimalFormat; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4863121 { + + static TestFormattedTextField ftf; + static JFrame fr; + static Robot robot; + + private static volatile boolean focused = false; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + ftf = new TestFormattedTextField(new DecimalFormat("####")); + ftf.setText("q"); + fr.getContentPane().add(ftf); + + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + focused = true; + } + }); + fr.pack(); + fr.setLocationRelativeTo(null); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + ftf.requestFocus(); + }); + robot.waitForIdle(); + robot.delay(500); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + if (!passed) { + throw new RuntimeException("JFormattedTextField's NotifyAction " + + "should invoke invalidEdit if commit fails"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static class TestFormattedTextField extends JFormattedTextField { + public TestFormattedTextField(Format f) { + super(f); + } + protected void invalidEdit() { + passed = true; + } + } +} diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4886538.java b/test/jdk/javax/swing/JFormattedTextField/bug4886538.java new file mode 100644 index 00000000000..e50b15e9175 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4886538.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4886538 + * @summary JFormattedTextField not returning correct value (class) + * @run main bug4886538 + */ + +import javax.swing.JFormattedTextField; +import javax.swing.SwingUtilities; +import javax.swing.text.DefaultFormatterFactory; + +public class bug4886538 { + + public static void main(String[] args) throws Exception { + // test default display formatter + TestFormattedTextField field = new TestFormattedTextField(0.0); + field.setFormatter(((DefaultFormatterFactory) field. + getFormatterFactory()).getDisplayFormatter()); + field.setText("10"); + field.commitEdit(); + + Object dblValue = field.getValue(); + if (!(dblValue instanceof Double)) { + throw new RuntimeException("The JFormattedTextField's value " + + "should be instanceof Double"); + } + + // test default editor formatter + field = new TestFormattedTextField(0.0); + field.setFormatter(((DefaultFormatterFactory) field. + getFormatterFactory()).getEditFormatter()); + field.setText("10"); + field.commitEdit(); + + dblValue = field.getValue(); + if (!(dblValue instanceof Double)) { + throw new RuntimeException("The JFormattedTextField's value " + + "should be instanceof Double"); + } + + } + + static class TestFormattedTextField extends JFormattedTextField { + public TestFormattedTextField(Object value) { + super(value); + } + public void setFormatter(JFormattedTextField.AbstractFormatter formatter) { + super.setFormatter(formatter); + } + } + +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4123919.java b/test/jdk/javax/swing/JPopupMenu/bug4123919.java new file mode 100644 index 00000000000..fcc37795b7d --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4123919.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4123919 + * @requires (os.family == "windows") + * @summary JPopupMenu.isPopupTrigger() under a different L&F. + * @key headful + * @run main bug4123919 + */ + +import javax.swing.JLabel; +import javax.swing.JPopupMenu; +import javax.swing.UIManager; +import javax.swing.SwingUtilities; +import java.awt.event.MouseEvent; +import java.util.Date; + +public class bug4123919 { + + public static void main(String[] args) throws Exception { + JPopupMenu popup = new JPopupMenu("Test"); + JLabel lb = new JLabel(); + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + SwingUtilities.updateComponentTreeUI(lb); + SwingUtilities.updateComponentTreeUI(popup); + if (!popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_PRESSED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " MotifLookAndFeel when mouse pressed..."); + } + if (popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_RELEASED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " MotifLookAndFeel when mouse released..."); + } + + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + SwingUtilities.updateComponentTreeUI(lb); + SwingUtilities.updateComponentTreeUI(popup); + + if (popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_PRESSED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " WindowsLookAndFeel when mouse pressed..."); + } + if (!popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_RELEASED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " WindowsLookAndFeel when mouse released..."); + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4197019.java b/test/jdk/javax/swing/JPopupMenu/bug4197019.java new file mode 100644 index 00000000000..428bef49174 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4197019.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4197019 + * @key headful + * @run main bug4197019 + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Polygon; +import java.awt.event.ActionEvent; + +import javax.swing.Action; +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JMenuItem; +import javax.swing.JMenu; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; + +public class bug4197019 { + static volatile JMenuItem mi1; + static volatile JMenuItem mi2; + static volatile Icon i2; + static volatile boolean isPassed = false; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JMenu fileMenu = new JMenu("File"); + JPopupMenu p = new JPopupMenu(); + Icon i = new ArrowIcon(); + Action a = new TestAction("Test", i); + mi1 = fileMenu.add(a); + mi2 = p.add(a); + + i2 = new SquareIcon(); + a.putValue(Action.SMALL_ICON, i2); + + isPassed = (mi2.getIcon() != i2) || (mi1.getIcon() != i2) || + (mi1.getIcon() != mi2.getIcon()); + }); + if (isPassed) { + throw new RuntimeException("Failed bug test 4197019"); + } + } + + private static class TestAction extends AbstractAction { + public TestAction(String s, Icon i) { + super(s,i); + } + public void actionPerformed(ActionEvent e) { + + } + } + + private static class ArrowIcon implements Icon { + public void paintIcon(Component c, Graphics g, int x, int y) { + Polygon p = new Polygon(); + p.addPoint(x, y); + p.addPoint(x+getIconWidth(), y+getIconHeight()/2); + p.addPoint(x, y+getIconHeight()); + g.fillPolygon(p); + + } + public int getIconWidth() { return 4; } + public int getIconHeight() { return 8; } + } // End class MenuArrowIcon + + private static class SquareIcon implements Icon { + public void paintIcon(Component c, Graphics g, int x, int y) { + g.setColor(Color.red); + g.fill3DRect(x,y,4,8,true); + } + public int getIconWidth() { return 8; } + public int getIconHeight() { return 8; } + } // End class MenuArrowIcon + +} From bb8b64635c0dd932cf14f5c04052501b04262040 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 14:34:14 +0000 Subject: [PATCH 104/298] 8319574: Exec/process tests should be marked as flagless Backport-of: 68110b7a82ae82e2485aec23aba5406d2a5c0327 --- test/jdk/java/lang/ProcessBuilder/Basic.java | 3 ++- test/jdk/java/lang/ProcessBuilder/InheritIOTest.java | 1 + test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java | 1 + .../jdk/java/lang/ProcessBuilder/ProcessStartLoggingTest.java | 1 + test/jdk/java/lang/ProcessBuilder/ReaderWriterTest.java | 1 + test/jdk/java/lang/ProcessBuilder/SkipTest.java | 3 ++- test/jdk/java/lang/ProcessHandle/OnExitTest.java | 3 ++- test/jdk/java/lang/ProcessHandle/TreeTest.java | 1 + test/jdk/java/lang/RuntimeTests/RuntimeExitLogTest.java | 1 + .../lang/RuntimeTests/exec/ArgWithSpaceAndFinalBackslash.java | 3 ++- test/jdk/java/lang/RuntimeTests/exec/Duped.java | 3 ++- test/jdk/java/lang/RuntimeTests/exec/ExecWithLotsOfArgs.java | 3 ++- test/jdk/java/lang/RuntimeTests/exec/ExitValue.java | 3 ++- test/jdk/java/lang/RuntimeTests/exec/SetCwd.java | 4 ++-- 14 files changed, 22 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/lang/ProcessBuilder/Basic.java b/test/jdk/java/lang/ProcessBuilder/Basic.java index 532dde18fe4..382df89050c 100644 --- a/test/jdk/java/lang/ProcessBuilder/Basic.java +++ b/test/jdk/java/lang/ProcessBuilder/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -34,6 +34,7 @@ * java.base/java.io:open * java.base/jdk.internal.misc * @requires !vm.musl + * @requires vm.flagless * @library /test/lib * @run main/othervm/native/timeout=300 -Djava.security.manager=allow Basic * @run main/othervm/native/timeout=300 -Djava.security.manager=allow -Djdk.lang.Process.launchMechanism=fork Basic diff --git a/test/jdk/java/lang/ProcessBuilder/InheritIOTest.java b/test/jdk/java/lang/ProcessBuilder/InheritIOTest.java index f1c1940f538..a372eeefbf8 100644 --- a/test/jdk/java/lang/ProcessBuilder/InheritIOTest.java +++ b/test/jdk/java/lang/ProcessBuilder/InheritIOTest.java @@ -25,6 +25,7 @@ * @test * @bug 8023130 8166026 * @summary Unit test for java.lang.ProcessBuilder inheritance of standard output and standard error streams + * @requires vm.flagless * @library /test/lib * @build jdk.test.lib.process.* * @run testng InheritIOTest diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java index 00543b09947..1949571cca7 100644 --- a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java +++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java @@ -27,6 +27,7 @@ * @bug 8307990 * @requires (os.family == "linux") | (os.family == "aix") * @requires vm.debug + * @requires vm.flagless * @library /test/lib * @run main/othervm/timeout=300 JspawnhelperProtocol */ diff --git a/test/jdk/java/lang/ProcessBuilder/ProcessStartLoggingTest.java b/test/jdk/java/lang/ProcessBuilder/ProcessStartLoggingTest.java index e33ec0bc69a..e9b2fa6b264 100644 --- a/test/jdk/java/lang/ProcessBuilder/ProcessStartLoggingTest.java +++ b/test/jdk/java/lang/ProcessBuilder/ProcessStartLoggingTest.java @@ -40,6 +40,7 @@ /* * @test * @summary verify logging of ProcessBuilder.start() + * @requires vm.flagless * @run junit/othervm ProcessStartLoggingTest */ public class ProcessStartLoggingTest { diff --git a/test/jdk/java/lang/ProcessBuilder/ReaderWriterTest.java b/test/jdk/java/lang/ProcessBuilder/ReaderWriterTest.java index 3768b34ea53..a73451417bf 100644 --- a/test/jdk/java/lang/ProcessBuilder/ReaderWriterTest.java +++ b/test/jdk/java/lang/ProcessBuilder/ReaderWriterTest.java @@ -49,6 +49,7 @@ /* * @test + * @requires vm.flagless * @library /test/lib * @build jdk.test.lib.process.ProcessTools jdk.test.lib.hexdump.HexPrinter * @run testng ReaderWriterTest diff --git a/test/jdk/java/lang/ProcessBuilder/SkipTest.java b/test/jdk/java/lang/ProcessBuilder/SkipTest.java index 329e3a1affb..cad2adaa6fe 100644 --- a/test/jdk/java/lang/ProcessBuilder/SkipTest.java +++ b/test/jdk/java/lang/ProcessBuilder/SkipTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -24,6 +24,7 @@ /* * @test * @bug 8155808 + * @requires vm.flagless * @run main SkipTest * @summary verify skip method of Process Input Stream */ diff --git a/test/jdk/java/lang/ProcessHandle/OnExitTest.java b/test/jdk/java/lang/ProcessHandle/OnExitTest.java index 98133e7bfbb..b75775b51a2 100644 --- a/test/jdk/java/lang/ProcessHandle/OnExitTest.java +++ b/test/jdk/java/lang/ProcessHandle/OnExitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ /* * @test + * @requires vm.flagless * @library /test/lib * @modules jdk.management * @build jdk.test.lib.Utils diff --git a/test/jdk/java/lang/ProcessHandle/TreeTest.java b/test/jdk/java/lang/ProcessHandle/TreeTest.java index 1fe1f10cb38..cec880f1fef 100644 --- a/test/jdk/java/lang/ProcessHandle/TreeTest.java +++ b/test/jdk/java/lang/ProcessHandle/TreeTest.java @@ -44,6 +44,7 @@ /* * @test + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * jdk.management diff --git a/test/jdk/java/lang/RuntimeTests/RuntimeExitLogTest.java b/test/jdk/java/lang/RuntimeTests/RuntimeExitLogTest.java index e552dcb7bef..da40cdbd742 100644 --- a/test/jdk/java/lang/RuntimeTests/RuntimeExitLogTest.java +++ b/test/jdk/java/lang/RuntimeTests/RuntimeExitLogTest.java @@ -41,6 +41,7 @@ /* * @test * @summary verify logging of call to System.exit or Runtime.exit. + * @requires vm.flagless * @run junit/othervm RuntimeExitLogTest */ diff --git a/test/jdk/java/lang/RuntimeTests/exec/ArgWithSpaceAndFinalBackslash.java b/test/jdk/java/lang/RuntimeTests/exec/ArgWithSpaceAndFinalBackslash.java index ed74576abbd..c5edf6c1212 100644 --- a/test/jdk/java/lang/RuntimeTests/exec/ArgWithSpaceAndFinalBackslash.java +++ b/test/jdk/java/lang/RuntimeTests/exec/ArgWithSpaceAndFinalBackslash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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,6 +25,7 @@ * @bug 4794652 * @summary Ensure that a command argument that contains a space and a final * backslash is handled correctly + * @requires vm.flagless */ import java.io.*; diff --git a/test/jdk/java/lang/RuntimeTests/exec/Duped.java b/test/jdk/java/lang/RuntimeTests/exec/Duped.java index d86fbdae124..f2e29cf0e04 100644 --- a/test/jdk/java/lang/RuntimeTests/exec/Duped.java +++ b/test/jdk/java/lang/RuntimeTests/exec/Duped.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, 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 @@ -24,6 +24,7 @@ /* @test @bug 4180429 @summary Lossage in dup2 if System.in is closed. + @requires vm.flagless @run main/othervm Duped */ diff --git a/test/jdk/java/lang/RuntimeTests/exec/ExecWithLotsOfArgs.java b/test/jdk/java/lang/RuntimeTests/exec/ExecWithLotsOfArgs.java index 26267e0d6ab..454e468ce26 100644 --- a/test/jdk/java/lang/RuntimeTests/exec/ExecWithLotsOfArgs.java +++ b/test/jdk/java/lang/RuntimeTests/exec/ExecWithLotsOfArgs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,6 +25,7 @@ @bug 4033560 @summary 4033560 limited args of exec to 198 on Solaris. We check that we can actually exec more args than that. + @requires vm.flagless @author Anand Palaniswamy @run main/othervm ExecWithLotsOfArgs */ diff --git a/test/jdk/java/lang/RuntimeTests/exec/ExitValue.java b/test/jdk/java/lang/RuntimeTests/exec/ExitValue.java index 03f56240cd4..96b6ed9d5f9 100644 --- a/test/jdk/java/lang/RuntimeTests/exec/ExitValue.java +++ b/test/jdk/java/lang/RuntimeTests/exec/ExitValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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,6 +25,7 @@ * @test * @bug 4680945 4873419 * @summary Check process exit code + * @requires vm.flagless * @author kladko, Martin Buchholz */ diff --git a/test/jdk/java/lang/RuntimeTests/exec/SetCwd.java b/test/jdk/java/lang/RuntimeTests/exec/SetCwd.java index a457b48b5e5..0749847a9d7 100644 --- a/test/jdk/java/lang/RuntimeTests/exec/SetCwd.java +++ b/test/jdk/java/lang/RuntimeTests/exec/SetCwd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, 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 @@ -27,7 +27,7 @@ * @summary Basic functional test for * Runtime.exec(String[] command, String[] env, File path) and * Runtime.exec(String command, String[] env, File path). - * + * @requires vm.flagless * @library /test/lib * @run testng/othervm SetCwd */ From 998ba93aceda49759f2064cabbabe58f0919ad73 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:45:56 +0000 Subject: [PATCH 105/298] 8319567: Update java/lang/invoke tests to support vm flags 8319568: Update java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java to accept vm flags 8319672: Several classloader tests ignore VM flags 8319676: A couple of jdk/modules/incubator/ tests ignore VM flags 8319677: Test jdk/internal/misc/VM/RuntimeArguments.java should be marked as flagless Backport-of: 1588dd934ce4e00a060e329b80f721d894559597 --- test/jdk/java/lang/ClassLoader/Assert.java | 40 ++-- .../lang/ClassLoader/GetSystemPackage.java | 8 +- .../ClassLoader/getResource/GetResource.java | 22 +-- .../LoadLibraryUnloadTest.java | 26 +-- .../condy/CondyNestedResolutionTest.java | 2 +- .../invoke/findSpecial/FindSpecialTest.java | 20 +- test/jdk/java/lang/invoke/lambda/LUtils.java | 171 ------------------ .../LambdaAccessControlDoPrivilegedTest.java | 85 +++++---- .../lambda/LambdaAccessControlTest.java | 8 +- .../java/lang/invoke/lambda/LambdaAsm.java | 38 ++-- .../lang/invoke/lambda/LambdaStackTrace.java | 35 ++-- .../lambda/LogGeneratedClassesTest.java | 118 ++++++------ .../exeCallerAccessTest/CallerAccessTest.java | 36 +--- .../LargeClasspathWithPkgPrefix.java | 8 +- .../internal/misc/VM/RuntimeArguments.java | 12 +- .../jdk/modules/incubator/DefaultImage.java | 19 +- .../jdk/modules/incubator/ImageModules.java | 5 +- 17 files changed, 219 insertions(+), 434 deletions(-) delete mode 100644 test/jdk/java/lang/invoke/lambda/LUtils.java diff --git a/test/jdk/java/lang/ClassLoader/Assert.java b/test/jdk/java/lang/ClassLoader/Assert.java index d894fef5ef9..d7dc27c7f53 100644 --- a/test/jdk/java/lang/ClassLoader/Assert.java +++ b/test/jdk/java/lang/ClassLoader/Assert.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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 @@ -24,6 +24,8 @@ /* * @test * @bug 4290640 4785473 + * @requires vm.flagless + * @library /test/lib * @build package1.Class1 package2.Class2 package1.package3.Class3 Assert * @run main/othervm Assert * @summary Test the assertion facility @@ -31,12 +33,17 @@ * @key randomness */ +import jdk.test.lib.process.OutputAnalyzer; import package1.*; import package2.*; import package1.package3.*; -import java.io.*; + +import java.util.ArrayList; +import java.util.List; import java.util.Random; +import static jdk.test.lib.process.ProcessTools.*; + public class Assert { private static Class1 testClass1; @@ -56,7 +63,7 @@ public class Assert { * off at class load time. Once the class is loaded its assertion status * does not change. */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Throwable { // Switch values: 0=don't touch, 1=off, 2 = on int[] switches = new int[7]; @@ -77,28 +84,17 @@ public static void main(String[] args) throws Exception { } // Spawn new VM and load classes - String command = System.getProperty("java.home") + - File.separator + "bin" + File.separator + "java Assert"; - - StringBuffer commandString = new StringBuffer(command); + List commands = new ArrayList<>(); + commands.add("Assert"); for(int j=0; j<7; j++) - commandString.append(" "+switches[j]); - - Process p = null; - p = Runtime.getRuntime().exec(commandString.toString()); - + commands.add(Integer.toString(switches[j])); + OutputAnalyzer outputAnalyzer = executeCommand(createLimitedTestJavaProcessBuilder(commands)); if (debug) { // See output of test VMs - BufferedReader blah = new BufferedReader( - new InputStreamReader(p.getInputStream())); - String outString = blah.readLine(); - while (outString != null) { - System.out.println("from BufferedReader:"+outString); - outString = blah.readLine(); - } + outputAnalyzer.asLines() + .stream() + .forEach(s -> System.out.println(s)); } - - p.waitFor(); - int result = p.exitValue(); + int result = outputAnalyzer.getExitValue(); if (debug) { // See which switch configs failed if (result == 0) { for(int k=6; k>=0; k--) diff --git a/test/jdk/java/lang/ClassLoader/GetSystemPackage.java b/test/jdk/java/lang/ClassLoader/GetSystemPackage.java index 2af81f3c416..0b3653f2f98 100644 --- a/test/jdk/java/lang/ClassLoader/GetSystemPackage.java +++ b/test/jdk/java/lang/ClassLoader/GetSystemPackage.java @@ -24,6 +24,7 @@ /* * @test * @bug 8060130 + * @requires vm.flagless * @library /test/lib * @build package2.Class2 GetSystemPackage * @summary Test if getSystemPackage() return consistent values for cases @@ -41,6 +42,8 @@ import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; + +import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; public class GetSystemPackage { @@ -118,8 +121,9 @@ private static void buildJar(String name, Manifest man) throws Exception { private static void runSubProcess(String messageOnError, String ... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - int res = pb.directory(tmpFolder).inheritIO().start().waitFor(); + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args) + .directory(tmpFolder); + int res = ProcessTools.executeProcess(pb).getExitValue(); if (res != 0) { throw new RuntimeException(messageOnError); } diff --git a/test/jdk/java/lang/ClassLoader/getResource/GetResource.java b/test/jdk/java/lang/ClassLoader/getResource/GetResource.java index 8c97657853d..2a1b76e7d4f 100644 --- a/test/jdk/java/lang/ClassLoader/getResource/GetResource.java +++ b/test/jdk/java/lang/ClassLoader/getResource/GetResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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,11 +40,9 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.test.lib.JDKToolFinder; import static jdk.test.lib.process.ProcessTools.*; import org.testng.annotations.BeforeTest; @@ -144,26 +142,14 @@ public void testCurrentDirA(List options, String expected) throws Throwa private void runTest(Path dir, List options, String expected) throws Throwable { - String javapath = JDKToolFinder.getJDKTool("java"); - List cmdLine = new ArrayList<>(); - cmdLine.add(javapath); options.forEach(cmdLine::add); cmdLine.add("GetResource"); cmdLine.add(expected); - - System.out.println("Command line: " + cmdLine); - ProcessBuilder pb = - new ProcessBuilder(cmdLine.stream().toArray(String[]::new)); - - // change working directory - pb.directory(dir.toFile()); - - // remove CLASSPATH environment variable - Map env = pb.environment(); - String value = env.remove("CLASSPATH"); - + ProcessBuilder pb = createTestJavaProcessBuilder(cmdLine); + pb.directory(dir.toFile()); // change working directory + pb.environment().remove("CLASSPATH"); // remove CLASSPATH environment variable executeCommand(pb).shouldHaveExitValue(0); } diff --git a/test/jdk/java/lang/ClassLoader/loadLibraryUnload/LoadLibraryUnloadTest.java b/test/jdk/java/lang/ClassLoader/loadLibraryUnload/LoadLibraryUnloadTest.java index 1cbde7b943f..c358fa64214 100644 --- a/test/jdk/java/lang/ClassLoader/loadLibraryUnload/LoadLibraryUnloadTest.java +++ b/test/jdk/java/lang/ClassLoader/loadLibraryUnload/LoadLibraryUnloadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, BELLSOFT. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,31 +38,15 @@ */ import jdk.test.lib.Asserts; -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.OutputAnalyzer; -import java.lang.ProcessBuilder; -import java.lang.Process; -import java.io.File; -import java.util.*; +import static jdk.test.lib.process.ProcessTools.*; public class LoadLibraryUnloadTest { private static String testClassPath = System.getProperty("test.classes"); private static String testLibraryPath = System.getProperty("test.nativepath"); - private static Process runJavaCommand(String... command) throws Throwable { - String java = JDKToolFinder.getJDKTool("java"); - List commands = new ArrayList<>(); - Collections.addAll(commands, java); - Collections.addAll(commands, command); - System.out.println("COMMAND: " + String.join(" ", commands)); - return new ProcessBuilder(commands.toArray(new String[0])) - .redirectErrorStream(true) - .directory(new File(testClassPath)) - .start(); - } - private final static long countLines(OutputAnalyzer output, String string) { return output.asLines() .stream() @@ -78,12 +62,10 @@ private final static void dump(OutputAnalyzer output) { public static void main(String[] args) throws Throwable { - Process process = runJavaCommand( + OutputAnalyzer outputAnalyzer = executeCommand(createTestJavaProcessBuilder( "-Dtest.classes=" + testClassPath, "-Djava.library.path=" + testLibraryPath, - "LoadLibraryUnload"); - - OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process); + "LoadLibraryUnload")); dump(outputAnalyzer); Asserts.assertTrue( diff --git a/test/jdk/java/lang/invoke/condy/CondyNestedResolutionTest.java b/test/jdk/java/lang/invoke/condy/CondyNestedResolutionTest.java index 914e90650da..f7a36a344b1 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNestedResolutionTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNestedResolutionTest.java @@ -44,7 +44,7 @@ */ public class CondyNestedResolutionTest { public static void main(String args[]) throws Throwable { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("CondyNestedResolution"); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("CondyNestedResolution"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); oa.shouldContain("StackOverflowError"); oa.shouldContain("bsm1arg"); diff --git a/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java b/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java index 129951b79d0..9b6622a7e9c 100644 --- a/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java +++ b/test/jdk/java/lang/invoke/findSpecial/FindSpecialTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -37,13 +37,11 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.test.lib.JDKToolFinder; -import jdk.test.lib.process.ProcessTools; +import static jdk.test.lib.process.ProcessTools.*; import org.testng.annotations.Test; public class FindSpecialTest { - static final String JAVA_LAUNCHER = JDKToolFinder.getJDKTool("java"); static final String TEST_CLASSES = System.getProperty("test.classes", "."); static final String TEST_CLASS_PATH = System.getProperty("test.class.path"); static final String TEST_MAIN_CLASS = "test.FindSpecial"; @@ -59,8 +57,9 @@ public static void callerInUnnamedModule() throws Throwable { throw new Error(m1 + " not exist"); } String classpath = m1.toString() + File.pathSeparator + TEST_CLASS_PATH; - ProcessTools.executeCommand(JAVA_LAUNCHER, "-cp", classpath, TEST_MAIN_CLASS) - .shouldHaveExitValue(0); + executeCommand(createTestJavaProcessBuilder("-cp", classpath, + TEST_MAIN_CLASS)) + .shouldHaveExitValue(0); } /* @@ -72,10 +71,9 @@ public static void callerInNamedModule() throws Throwable { if (Files.notExists(modules)) { throw new Error(modules + " not exist"); } - ProcessTools.executeCommand(JAVA_LAUNCHER, - "-cp", TEST_CLASS_PATH, - "-p", modules.toString(), - "-m", TEST_MODULE + "/" + TEST_MAIN_CLASS) - .shouldHaveExitValue(0); + executeCommand(createTestJavaProcessBuilder("-cp", TEST_CLASS_PATH, + "-p", modules.toString(), + "-m", TEST_MODULE + "/" + TEST_MAIN_CLASS)) + .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/lang/invoke/lambda/LUtils.java b/test/jdk/java/lang/invoke/lambda/LUtils.java deleted file mode 100644 index cc052e43e90..00000000000 --- a/test/jdk/java/lang/invoke/lambda/LUtils.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/* - * support infrastructure to invoke a java class from the command line - */ -class LUtils { - static final com.sun.tools.javac.Main javac = - new com.sun.tools.javac.Main(); - static final File cwd = new File(".").getAbsoluteFile(); - static final String JAVAHOME = System.getProperty("java.home"); - static final boolean isWindows = - System.getProperty("os.name", "unknown").startsWith("Windows"); - static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin"); - static final File JAVA_CMD = new File(JAVA_BIN_FILE, - isWindows ? "java.exe" : "java"); - static final File JAR_BIN_FILE = new File(JAVAHOME, "bin"); - static final File JAR_CMD = new File(JAR_BIN_FILE, - isWindows ? "jar.exe" : "jar"); - - protected LUtils() { - } - - public static void compile(String... args) { - if (javac.compile(args) != 0) { - throw new RuntimeException("compilation fails"); - } - } - - static void createFile(File outFile, List content) { - try { - Files.write(outFile.getAbsoluteFile().toPath(), content, - Charset.defaultCharset()); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - static File getClassFile(File javaFile) { - return javaFile.getName().endsWith(".java") - ? new File(javaFile.getName().replace(".java", ".class")) - : null; - } - - static String getSimpleName(File inFile) { - String fname = inFile.getName(); - return fname.substring(0, fname.indexOf(".")); - } - - static TestResult doExec(String... cmds) { - return doExec(null, null, cmds); - } - - /* - * A method which executes a java cmd and returns the results in a container - */ - static TestResult doExec(Map envToSet, - java.util.Set envToRemove, String... cmds) { - String cmdStr = ""; - for (String x : cmds) { - cmdStr = cmdStr.concat(x + " "); - } - ProcessBuilder pb = new ProcessBuilder(cmds); - Map env = pb.environment(); - if (envToRemove != null) { - for (String key : envToRemove) { - env.remove(key); - } - } - if (envToSet != null) { - env.putAll(envToSet); - } - BufferedReader rdr = null; - try { - List outputList = new ArrayList<>(); - pb.redirectErrorStream(true); - Process p = pb.start(); - rdr = new BufferedReader(new InputStreamReader(p.getInputStream())); - String in = rdr.readLine(); - while (in != null) { - outputList.add(in); - in = rdr.readLine(); - } - p.waitFor(); - p.destroy(); - - return new TestResult(cmdStr, p.exitValue(), outputList, - env, new Throwable("current stack of the test")); - } catch (Exception ex) { - ex.printStackTrace(); - throw new RuntimeException(ex.getMessage()); - } - } - - static class TestResult { - String cmd; - int exitValue; - List testOutput; - Map env; - Throwable t; - - public TestResult(String str, int rv, List oList, - Map env, Throwable t) { - cmd = str; - exitValue = rv; - testOutput = oList; - this.env = env; - this.t = t; - } - - void assertZero(String message) { - if (exitValue != 0) { - System.err.println(this); - throw new RuntimeException(message); - } - } - - @Override - public String toString() { - StringWriter sw = new StringWriter(); - PrintWriter status = new PrintWriter(sw); - status.println("Cmd: " + cmd); - status.println("Return code: " + exitValue); - status.println("Environment variable:"); - for (String x : env.keySet()) { - status.println("\t" + x + "=" + env.get(x)); - } - status.println("Output:"); - for (String x : testOutput) { - status.println("\t" + x); - } - status.println("Exception:"); - status.println(t.getMessage()); - t.printStackTrace(status); - - return sw.getBuffer().toString(); - } - } -} diff --git a/test/jdk/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java b/test/jdk/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java index 37be43d0426..fc6fd91e5ac 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -24,19 +24,28 @@ /* * @test * @bug 8003881 - * @summary tests DoPrivileged action (implemented as lambda expressions) by - * inserting them into the BootClassPath. + * @library /test/lib/ * @modules jdk.compiler * jdk.zipfs - * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java LUtils.java + * @compile LambdaAccessControlDoPrivilegedTest.java * @run main/othervm -Djava.security.manager=allow LambdaAccessControlDoPrivilegedTest + * @summary tests DoPrivileged action (implemented as lambda expressions) by + * inserting them into the BootClassPath. */ -import java.io.File; +import jdk.test.lib.process.OutputAnalyzer; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.spi.ToolProvider; + +import static jdk.test.lib.process.ProcessTools.*; -public class LambdaAccessControlDoPrivilegedTest extends LUtils { - public static void main(String... args) { +public class LambdaAccessControlDoPrivilegedTest { + public static void main(String... args) throws Exception { final List scratch = new ArrayList(); scratch.clear(); scratch.add("import java.security.*;"); @@ -47,9 +56,9 @@ public static void main(String... args) { scratch.add("});"); scratch.add("}"); scratch.add("}"); - File doprivJava = new File("DoPriv.java"); - File doprivClass = getClassFile(doprivJava); - createFile(doprivJava, scratch); + Path doprivJava = Path.of("DoPriv.java"); + Path doprivClass = Path.of("DoPriv.class"); + Files.write(doprivJava, scratch, Charset.defaultCharset()); scratch.clear(); scratch.add("public class Bar {"); @@ -59,30 +68,40 @@ public static void main(String... args) { scratch.add("}"); scratch.add("}"); - File barJava = new File("Bar.java"); - File barClass = getClassFile(barJava); - createFile(barJava, scratch); + Path barJava = Path.of("Bar.java"); + Path barClass = Path.of("Bar.class"); + Files.write(barJava, scratch, Charset.defaultCharset()); + + compile(barJava.toString(), doprivJava.toString()); + + jar("cvf", "foo.jar", doprivClass.toString()); + Files.delete(doprivJava); + Files.delete(doprivClass); + + ProcessBuilder pb = createTestJavaProcessBuilder( + "-Xbootclasspath/a:foo.jar", + "-cp", ".", + "-Djava.security.manager=allow", + "Bar"); + executeProcess(pb).shouldHaveExitValue(0); + + Files.delete(barJava); + Files.delete(barClass); + Files.delete(Path.of("foo.jar")); + } + + static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar").orElseThrow(); + static final ToolProvider JAVAC = ToolProvider.findFirst("javac").orElseThrow(); + static void compile(String... args) throws IOException { + if (JAVAC.run(System.out, System.err, args) != 0) { + throw new RuntimeException("compilation fails"); + } + } - String[] javacArgs = {barJava.getName(), doprivJava.getName()}; - compile(javacArgs); - File jarFile = new File("foo.jar"); - String[] jargs = {"cvf", jarFile.getName(), doprivClass.getName()}; - TestResult tr = doExec(JAR_CMD.getAbsolutePath(), - "cvf", jarFile.getName(), - doprivClass.getName()); - if (tr.exitValue != 0){ - throw new RuntimeException(tr.toString()); + static void jar(String... args) { + int rc = JAR_TOOL.run(System.out, System.err, args); + if (rc != 0){ + throw new RuntimeException("fail to create JAR file"); } - doprivJava.delete(); - doprivClass.delete(); - tr = doExec(JAVA_CMD.getAbsolutePath(), - "-Xbootclasspath/a:foo.jar", - "-cp", ".", - "-Djava.security.manager=allow", - "Bar"); - tr.assertZero("testDoPrivileged fails"); - barJava.delete(); - barClass.delete(); - jarFile.delete(); } } diff --git a/test/jdk/java/lang/invoke/lambda/LambdaAccessControlTest.java b/test/jdk/java/lang/invoke/lambda/LambdaAccessControlTest.java index 2ae76b91111..2588d30be23 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaAccessControlTest.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaAccessControlTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -24,14 +24,12 @@ /* * @test * @bug 8003881 - * @summary tests Lambda expression with a security manager at top level * @modules jdk.compiler - * @compile -XDignore.symbol.file LambdaAccessControlTest.java LUtils.java - * * @run main/othervm -Djava.security.manager=allow LambdaAccessControlTest + * @summary tests Lambda expression with a security manager at top level */ -public class LambdaAccessControlTest extends LUtils { +public class LambdaAccessControlTest { public static void main(String... args) { System.setSecurityManager(new SecurityManager()); JJ iii = (new CC())::impl; diff --git a/test/jdk/java/lang/invoke/lambda/LambdaAsm.java b/test/jdk/java/lang/invoke/lambda/LambdaAsm.java index 647f906cba8..f0d79988783 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaAsm.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaAsm.java @@ -24,13 +24,14 @@ /* * @test * @bug 8027232 - * @summary ensures that j.l.i.InvokerByteCodeGenerator and ASM visitMethodInsn - * generate bytecodes with correct constant pool references + * @library /test/lib/ * @modules java.base/jdk.internal.org.objectweb.asm * jdk.jdeps/com.sun.tools.classfile * jdk.zipfs - * @compile -XDignore.symbol.file LambdaAsm.java LUtils.java + * @compile LambdaAsm.java * @run main/othervm LambdaAsm + * @summary ensures that j.l.i.InvokerByteCodeGenerator and ASM visitMethodInsn + * generate bytecodes with correct constant pool references */ import com.sun.tools.classfile.Attribute; import com.sun.tools.classfile.ClassFile; @@ -40,34 +41,36 @@ import com.sun.tools.classfile.Instruction; import com.sun.tools.classfile.Method; import java.io.ByteArrayInputStream; -import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; import java.util.ArrayList; import java.nio.file.DirectoryStream; import java.nio.file.Path; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.OutputAnalyzer; import static java.nio.file.Files.*; import static jdk.internal.org.objectweb.asm.Opcodes.*; +import static jdk.test.lib.process.ProcessTools.*; public class LambdaAsm { static final Path DUMP_LAMBDA_PROXY_CLASS_FILES = Path.of("DUMP_LAMBDA_PROXY_CLASS_FILES"); + static final Path SRC = Path.of("src"); + static final Path CLASSES = Path.of("classes"); - static final File TestFile = new File("A.java"); - - static void init() { + static void init() throws Exception { emitCode(); - LUtils.compile(TestFile.getName()); - LUtils.TestResult tr = LUtils.doExec(LUtils.JAVA_CMD.getAbsolutePath(), + CompilerUtils.compile(SRC, CLASSES); + OutputAnalyzer outputAnalyzer = executeProcess(createTestJavaProcessBuilder( "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles=true", - "-cp", ".", "A"); - if (tr.exitValue != 0) { - System.out.println("Error: " + tr.toString()); - throw new RuntimeException("could not create proxy classes"); - } + "-cp", CLASSES.toString(), "A")); + outputAnalyzer.shouldHaveExitValue(0); } - static void emitCode() { + static void emitCode() throws IOException { ArrayList scratch = new ArrayList<>(); scratch.add("import java.util.function.*;"); scratch.add("class A {"); @@ -89,7 +92,10 @@ static void emitCode() { scratch.add(" I.d();"); scratch.add(" }"); scratch.add("}"); - LUtils.createFile(TestFile, scratch); + + Path testFile = SRC.resolve("A.java"); + Files.createDirectories(SRC); + Files.write(testFile, scratch, Charset.defaultCharset()); } static void checkMethod(String cname, String mname, ConstantPool cp, diff --git a/test/jdk/java/lang/invoke/lambda/LambdaStackTrace.java b/test/jdk/java/lang/invoke/lambda/LambdaStackTrace.java index f27b56b72b3..6ae63e4b7d9 100644 --- a/test/jdk/java/lang/invoke/lambda/LambdaStackTrace.java +++ b/test/jdk/java/lang/invoke/lambda/LambdaStackTrace.java @@ -24,20 +24,23 @@ /* * @test * @bug 8025636 - * @summary Synthetic frames should be hidden in exceptions + * @library /test/lib/ * @modules java.base/jdk.internal.org.objectweb.asm * jdk.compiler - * @compile -XDignore.symbol.file LUtils.java LambdaStackTrace.java + * @compile LambdaStackTrace.java * @run main LambdaStackTrace + * @summary Synthetic frames should be hidden in exceptions */ import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.test.lib.compiler.CompilerUtils; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT; @@ -47,7 +50,7 @@ public class LambdaStackTrace { - static File classes = new File(System.getProperty("test.classes")); + static Path CLASSES = Path.of(System.getProperty("test.classes", ".")); public static void main(String[] args) throws Exception { testBasic(); @@ -121,12 +124,8 @@ private static void generateInterfaces() throws IOException { // We can't let javac compile these interfaces because in > 1.8 it will insert // bridge methods into the interfaces - we want code that looks like <= 1.7, // so we generate it. - try (FileOutputStream fw = new FileOutputStream(new File(classes, "Maker.class"))) { - fw.write(generateMaker()); - } - try (FileOutputStream fw = new FileOutputStream(new File(classes, "StringMaker.class"))) { - fw.write(generateStringMaker()); - } + Files.write(CLASSES.resolve("Maker.class"), generateMaker()); + Files.write(CLASSES.resolve("StringMaker.class"), generateStringMaker()); } private static byte[] generateMaker() { @@ -154,7 +153,7 @@ private static byte[] generateStringMaker() { } - static void emitCode(File f) { + static void emitCode(Path file) throws IOException { ArrayList scratch = new ArrayList<>(); scratch.add("public class Caller {"); scratch.add(" public static void callStringMaker() {"); @@ -166,13 +165,17 @@ static void emitCode(File f) { scratch.add(" ((Maker) sm).make();"); // <-- This will call the bridge method scratch.add(" }"); scratch.add("}"); - LUtils.createFile(f, scratch); + + Files.write(file, scratch, Charset.defaultCharset()); } - static void compileCaller() { - File caller = new File(classes, "Caller.java"); + static void compileCaller() throws IOException { + Path src = Path.of("src"); + Files.createDirectories(src); + + Path caller = src.resolve("Caller.java"); emitCode(caller); - LUtils.compile("-cp", classes.getAbsolutePath(), "-d", classes.getAbsolutePath(), caller.getAbsolutePath()); + CompilerUtils.compile(src, CLASSES, "-cp", CLASSES.toAbsolutePath().toString()); } private static void verifyFrames(StackTraceElement[] stack, String... patterns) throws Exception { diff --git a/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java b/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java index 26ed7b0058e..91ea4b932ca 100644 --- a/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java +++ b/test/jdk/java/lang/invoke/lambda/LogGeneratedClassesTest.java @@ -24,14 +24,16 @@ /* * @test * @bug 8023524 8304846 - * @summary tests logging generated classes for lambda + * @requires vm.flagless + * @library /test/lib/ * @library /java/nio/file * @modules jdk.compiler * jdk.zipfs * @run testng LogGeneratedClassesTest + * @summary tests logging generated classes for lambda */ -import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; @@ -40,18 +42,21 @@ import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributeView; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.OutputAnalyzer; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import org.testng.SkipException; import static java.nio.file.attribute.PosixFilePermissions.*; +import static jdk.test.lib.process.ProcessTools.*; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -public class LogGeneratedClassesTest extends LUtils { +public class LogGeneratedClassesTest { static final Path DUMP_LAMBDA_PROXY_CLASS_FILES = Path.of("DUMP_LAMBDA_PROXY_CLASS_FILES"); + static final Path CLASSES = Path.of("classes").toAbsolutePath(); String longFQCN; @BeforeClass @@ -74,9 +79,8 @@ public void setup() throws IOException { scratch.add(" }"); scratch.add("}"); - File test = new File("TestLambda.java"); - createFile(test, scratch); - compile("-d", ".", test.getName()); + Path testLambda = Path.of("TestLambda.java"); + Files.write(testLambda, scratch, Charset.defaultCharset()); scratch.remove(0); scratch.remove(0); @@ -91,9 +95,10 @@ public void setup() throws IOException { sb.append(";"); sb.insert(0, "package "); scratch.add(0, sb.toString()); - test = new File("LongPackageName.java"); - createFile(test, scratch); - compile("-d", ".", test.getName()); + Path lpnTest = Path.of("LongPackageName.java"); + Files.write(lpnTest, scratch, Charset.defaultCharset()); + + CompilerUtils.compile(Path.of("."), CLASSES); } @AfterClass @@ -107,49 +112,49 @@ public void cleanup() throws IOException { } @Test - public void testNotLogging() { - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", ".", + public void testNotLogging() throws Exception { + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), "-Djava.security.manager=allow", "com.example.TestLambda"); - tr.assertZero("Should still return 0"); + executeProcess(pb).shouldHaveExitValue(0); } @Test - public void testLogging() throws IOException { + public void testLogging() throws Exception { Path testDir = Path.of("dump"); Path dumpDir = testDir.resolve(DUMP_LAMBDA_PROXY_CLASS_FILES); Files.createDirectory(testDir); - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", "..", - "-Duser.dir=" + testDir.toAbsolutePath(), + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), "-Djava.security.manager=allow", "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", - "com.example.TestLambda"); + "com.example.TestLambda").directory(testDir.toFile()); + executeProcess(pb).shouldHaveExitValue(0); + // 2 our own class files. We don't care about the others assertEquals(Files.find( dumpDir, 99, (p, a) -> p.startsWith(dumpDir.resolve("com/example")) && a.isRegularFile()).count(), - 2, "Two lambda captured"); - tr.assertZero("Should still return 0"); + 2, "Two lambda captured"); } @Test - public void testDumpDirNotExist() throws IOException { + public void testDumpDirNotExist() throws Exception { Path testDir = Path.of("NotExist"); Path dumpDir = testDir.resolve(DUMP_LAMBDA_PROXY_CLASS_FILES); Files.createDirectory(testDir); TestUtil.removeAll(dumpDir); - assertFalse(Files.exists(dumpDir)); - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", "..", - "-Duser.dir=" + testDir.toAbsolutePath(), - "-Djava.security.manager=allow", - "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", - "com.example.TestLambda"); + + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), + "-Djava.security.manager=allow", + "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", + "com.example.TestLambda").directory(testDir.toFile()); + executeProcess(pb).shouldHaveExitValue(0); // The dump directory will be created if not exist assertEquals(Files.find( @@ -157,28 +162,24 @@ public void testDumpDirNotExist() throws IOException { 99, (p, a) -> p.startsWith(dumpDir.resolve("com/example")) && a.isRegularFile()).count(), - 2, "Two lambda captured"); - tr.assertZero("Should still return 0"); + 2, "Two lambda captured"); } @Test - public void testDumpDirIsFile() throws IOException { + public void testDumpDirIsFile() throws Exception { Path testDir = Path.of("notDir"); Path dumpFile = testDir.resolve(DUMP_LAMBDA_PROXY_CLASS_FILES); Files.createDirectory(testDir); Files.createFile(dumpFile); assertTrue(Files.isRegularFile(dumpFile)); - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", "..", - "-Duser.dir=" + testDir.toAbsolutePath(), - "-Djava.security.manager=allow", - "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", - "com.example.TestLambda"); - assertEquals(tr.testOutput.stream() - .filter(s -> s.contains("DUMP_LAMBDA_PROXY_CLASS_FILES is not a directory")) - .count(), - 1, "only show error once"); - assertTrue(tr.exitValue != 0); + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), + "-Djava.security.manager=allow", + "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", + "com.example.TestLambda").directory(testDir.toFile()); + executeProcess(pb) + .shouldContain("DUMP_LAMBDA_PROXY_CLASS_FILES is not a directory") + .shouldNotHaveExitValue(0); } private static boolean isWriteableDirectory(Path p) { @@ -205,7 +206,7 @@ private static boolean isWriteableDirectory(Path p) { } @Test - public void testDumpDirNotWritable() throws IOException { + public void testDumpDirNotWritable() throws Exception { if (!Files.getFileStore(Paths.get(".")) .supportsFileAttributeView(PosixFileAttributeView.class)) { // No easy way to setup readonly directory without POSIX @@ -230,35 +231,33 @@ public void testDumpDirNotWritable() throws IOException { return; } - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", "..", - "-Duser.dir=" + testDir.toAbsolutePath(), + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), "-Djava.security.manager=allow", "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", - "com.example.TestLambda"); - assertEquals(tr.testOutput.stream() - .filter(s -> s.contains("DUMP_LAMBDA_PROXY_CLASS_FILES is not writable")) - .count(), - 1, "only show error once"); - assertTrue(tr.exitValue != 0); + "com.example.TestLambda").directory(testDir.toFile()); + executeProcess(pb) + .shouldContain("DUMP_LAMBDA_PROXY_CLASS_FILES is not writable") + .shouldNotHaveExitValue(0); } finally { TestUtil.removeAll(testDir); } } @Test - public void testLoggingException() throws IOException { + public void testLoggingException() throws Exception { Path testDir = Path.of("dumpLong"); Path dumpDir = testDir.resolve(DUMP_LAMBDA_PROXY_CLASS_FILES); Files.createDirectories(dumpDir.resolve("com/example/nonsense")); Files.createFile(dumpDir.resolve("com/example/nonsense/nonsense")); - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", "..", - "-Duser.dir=" + testDir.toAbsolutePath(), + ProcessBuilder pb = createLimitedTestJavaProcessBuilder( + "-cp", CLASSES.toString(), "-Djava.security.manager=allow", "-Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles", - longFQCN); - assertEquals(tr.testOutput.stream() + longFQCN).directory(testDir.toFile()); + OutputAnalyzer outputAnalyzer = executeProcess(pb); + outputAnalyzer.shouldHaveExitValue(0); + assertEquals(outputAnalyzer.asLines().stream() .filter(s -> s.startsWith("WARNING: Exception")) .count(), 2, "show error each capture"); @@ -279,6 +278,5 @@ public void testLoggingException() throws IOException { assertEquals(Files.walk(dumpDir) .filter(filter) .count(), 5, "Two lambda captured failed to log"); - tr.assertZero("Should still return 0"); } } diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java index a6d17f90632..749133bb581 100644 --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -31,37 +31,15 @@ // Test disabled on AIX since we cannot invoke the JVM on the primordial thread. -import java.io.File; -import java.util.Map; import jdk.test.lib.Platform; -import jdk.test.lib.process.OutputAnalyzer; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; +import jdk.test.lib.process.ProcessTools; public class CallerAccessTest { - public static void main(String[] args) throws IOException { - Path launcher = Paths.get(System.getProperty("test.nativepath"), "CallerAccessTest"); - ProcessBuilder pb = new ProcessBuilder(launcher.toString()); - Map env = pb.environment(); - - String libDir = Platform.libDir().toString(); - String vmDir = Platform.jvmLibDir().toString(); - - // set up shared library path - String sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName(); - env.compute(sharedLibraryPathEnvName, - (k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir); - env.compute(sharedLibraryPathEnvName, - (k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir); - - System.out.println("Launching: " + launcher + " shared library path: " + - env.get(sharedLibraryPathEnvName)); - new OutputAnalyzer(pb.start()) - .outputTo(System.out) - .errorTo(System.err) - .shouldHaveExitValue(0); + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createNativeTestProcessBuilder("CallerAccessTest"); + System.out.println("Launching: " + pb.command() + " shared library path: " + + pb.environment().get(Platform.sharedLibraryPathVariableName())); + ProcessTools.executeProcess(pb).shouldHaveExitValue(0); } } diff --git a/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java b/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java index 17def65a6ba..0e532497a46 100644 --- a/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java +++ b/test/jdk/jdk/internal/loader/URLClassPath/LargeClasspathWithPkgPrefix.java @@ -25,7 +25,6 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -34,12 +33,12 @@ /* * @test * @bug 8308184 - * @summary Verify that an application can be launched when the classpath contains large number of - * jars and the java.protocol.handler.pkgs system property is set * @library /test/lib/ * @build jdk.test.lib.util.JarBuilder jdk.test.lib.compiler.CompilerUtils * jdk.test.lib.process.ProcessTools * @run driver LargeClasspathWithPkgPrefix + * @summary Verify that an application can be launched when the classpath contains large number of + * jars and the java.protocol.handler.pkgs system property is set */ public class LargeClasspathWithPkgPrefix { @@ -126,8 +125,7 @@ private static void compile(Path javaFile, Path destDir) throws Exception { // java -Djava.protocol.handler.pkgs=foo.bar.some.nonexistent.pkg -cp Foo private static void launchApplication(String classPath) throws Exception { - String java = JDKToolFinder.getJDKTool("java"); - ProcessBuilder pb = new ProcessBuilder(java, + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-Djava.protocol.handler.pkgs=foo.bar.some.nonexistent.pkg", "-cp", classPath, "Foo"); diff --git a/test/jdk/jdk/internal/misc/VM/RuntimeArguments.java b/test/jdk/jdk/internal/misc/VM/RuntimeArguments.java index c48de900ec3..dbcb30255a8 100644 --- a/test/jdk/jdk/internal/misc/VM/RuntimeArguments.java +++ b/test/jdk/jdk/internal/misc/VM/RuntimeArguments.java @@ -23,11 +23,12 @@ /** * @test - * @summary Basic test of VM::getRuntimeArguments + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * jdk.zipfs * @run testng RuntimeArguments + * @summary Basic test of VM::getRuntimeArguments */ import java.io.IOException; @@ -46,7 +47,6 @@ import static org.testng.Assert.*; public class RuntimeArguments { - static final String TEST_CLASSES = System.getProperty("test.classes"); static final List VM_OPTIONS = getInitialOptions(); /* @@ -112,11 +112,9 @@ public static void main(String... expected) { @Test(dataProvider = "options") public void test(List args, List expected) throws Exception { - // launch a test program - // $ java -classpath RuntimeArguments - Stream options = Stream.concat(args.stream(), - Stream.of("-classpath", TEST_CLASSES, "RuntimeArguments")); - + // launch a test program with classpath set by ProcessTools::createLimitedTestJavaProcessBuilder + // $ java RuntimeArguments + Stream options = Stream.concat(args.stream(), Stream.of("RuntimeArguments")); ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( // The runtime image may be created with jlink --add-options // The initial VM options will be included in the result diff --git a/test/jdk/jdk/modules/incubator/DefaultImage.java b/test/jdk/jdk/modules/incubator/DefaultImage.java index 25ff746529b..63bc46b26ad 100644 --- a/test/jdk/jdk/modules/incubator/DefaultImage.java +++ b/test/jdk/jdk/modules/incubator/DefaultImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -24,11 +24,12 @@ /* * @test * @bug 8170859 - * @summary Ensure no incubator modules are resolved by default in the image + * @requires vm.flagless * @library /test/lib * @modules jdk.compiler * @build jdk.test.lib.compiler.CompilerUtils * @run testng DefaultImage + * @summary Ensure no incubator modules are resolved by default in the image */ import java.io.ByteArrayOutputStream; @@ -43,6 +44,7 @@ import java.util.stream.Stream; import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.ProcessTools; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -108,10 +110,8 @@ public void testAllSystem() throws Throwable { static ToolResult java(String... opts) throws Throwable { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); - String[] options = Stream.concat(Stream.of(getJava()), Stream.of(opts)) - .toArray(String[]::new); - ProcessBuilder pb = new ProcessBuilder(options); + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(opts); int exitValue = executeCommand(pb).outputTo(ps) .errorTo(ps) .getExitValue(); @@ -155,15 +155,6 @@ ToolResult assertOutputDoesNotContain(String subString) { } } - static String getJava() { - Path image = Paths.get(JAVA_HOME); - boolean isWindows = System.getProperty("os.name").startsWith("Windows"); - Path java = image.resolve("bin").resolve(isWindows ? "java.exe" : "java"); - if (Files.notExists(java)) - throw new RuntimeException(java + " not found"); - return java.toAbsolutePath().toString(); - } - static boolean isExplodedBuild() { Path modulesPath = Paths.get(JAVA_HOME).resolve("lib").resolve("modules"); return Files.notExists(modulesPath); diff --git a/test/jdk/jdk/modules/incubator/ImageModules.java b/test/jdk/jdk/modules/incubator/ImageModules.java index b69c4022f13..b48a969669e 100644 --- a/test/jdk/jdk/modules/incubator/ImageModules.java +++ b/test/jdk/jdk/modules/incubator/ImageModules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 8170859 - * @summary Basic test for incubator modules in jmods and images + * @requires vm.flagless * @library /test/lib * @key intermittent * @modules jdk.compiler jdk.jartool jdk.jlink @@ -32,6 +32,7 @@ * jdk.test.lib.util.FileUtils * jdk.test.lib.compiler.CompilerUtils * @run testng/othervm ImageModules + * @summary Basic test for incubator modules in jmods and images */ import java.io.ByteArrayOutputStream; From d59d00d50f19f666f828513068b2b621a8739ef2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:49:27 +0000 Subject: [PATCH 106/298] 8319647: Few java/lang/System/LoggerFinder/modules tests ignore vm flags Backport-of: 62b7c5eaed1e6ffd6f2c8371eb4cf01dd9d53a06 --- .../System/LoggerFinder/modules/JDKLoggerForImageTest.java | 3 ++- .../lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java | 3 ++- .../lang/System/LoggerFinder/modules/LoggerInImageTest.java | 3 ++- .../System/LoggerFinder/modules/NamedLoggerForImageTest.java | 3 ++- .../System/LoggerFinder/modules/NamedLoggerForJDKTest.java | 3 ++- .../System/LoggerFinder/modules/UnnamedLoggerForImageTest.java | 3 ++- .../System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java index b155ba994a6..120bba40e0e 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -30,6 +30,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm JDKLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java index 68bc6fd839b..8c25b062002 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -30,6 +30,7 @@ * 2. clients are in named/unnamed module, * patched system module, or Xbootclasspath * This test DOES require existence of java.logging module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm JDKLoggerForJDKTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java index d3c3ace5a65..2cc510e7f99 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -30,6 +30,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm LoggerInImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java index 2e621597935..df14801c164 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm NamedLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java index 6abf98c5227..e48cf4786c7 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm NamedLoggerForJDKTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java index 038c96697cb..26f6246bb85 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm UnnamedLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java index b239483b0b7..74a76756162 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm UnnamedLoggerForJDKTest From dbb3dfdd429bb10f7ba26e25c5754a041e56d195 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:51:15 +0000 Subject: [PATCH 107/298] 8322858: compiler/c2/aarch64/TestFarJump.java fails on AArch64 due to unexpected PrintAssembly output Backport-of: 52a6c37558fa970f595067bc1bb5bc2b710c3876 --- test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java index d461d56d8a3..3fe213122bd 100644 --- a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java +++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, BELLSOFT. All rights reserved. + * Copyright (c) 2024, BELLSOFT. 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 @@ -89,10 +89,9 @@ static void runVM(boolean bigCodeHeap) throws Exception { "-Xbatch", "-XX:+TieredCompilation", "-XX:+SegmentedCodeCache", - "-XX:CompileOnly=" + className + "::main", "-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"), "-XX:+UnlockDiagnosticVMOptions", - "-XX:+PrintAssembly", + "-XX:CompileCommand=option," + className + "::main,bool,PrintAssembly,true", className}; ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(procArgs); From 438c41afd05476c42cc4b81a8a93e04abe2ab9b7 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 25 Mar 2024 17:51:32 +0000 Subject: [PATCH 108/298] 8328705: GHA: Cross-compilation jobs do not require build JDK Backport-of: 29ba4b7d1e62a834c1693fe6ad383c19467afc81 --- .github/workflows/build-cross-compile.yml | 8 -------- .github/workflows/main.yml | 4 +--- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 3f5206c486f..3928d3dc0cc 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -98,13 +98,6 @@ jobs: with: platform: linux-x64 - # Use linux-x64 JDK bundle as build JDK - - name: 'Get build JDK' - id: buildjdk - uses: ./.github/actions/get-bundles - with: - platform: linux-x64 - - name: 'Get GTest' id: gtest uses: ./.github/actions/get-gtest @@ -177,7 +170,6 @@ jobs: --disable-precompiled-headers --openjdk-target=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}} --with-sysroot=sysroot - --with-build-jdk=${{ steps.buildjdk.outputs.jdk-path }} --with-jmod-compress=zip-1 CC=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-gcc-${{ inputs.gcc-major-version }} CXX=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-g++-${{ inputs.gcc-major-version }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e99d17aa197..8e110eac738 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -132,8 +132,7 @@ jobs: gcc-major-version: '10' configure-arguments: ${{ github.event.inputs.configure-arguments }} make-arguments: ${{ github.event.inputs.make-arguments }} - # The linux-x64 jdk bundle is used as buildjdk for the cross-compile job - if: needs.select.outputs.linux-x64 == 'true' || needs.select.outputs.linux-cross-compile == 'true' + if: needs.select.outputs.linux-x64 == 'true' build-linux-x86: name: linux-x86 @@ -213,7 +212,6 @@ jobs: name: linux-cross-compile needs: - select - - build-linux-x64 uses: ./.github/workflows/build-cross-compile.yml with: gcc-major-version: '10' From 098656d11e4781bc70f091ca0aa6d40eec774f2c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:54:59 +0000 Subject: [PATCH 109/298] 8319571: Update jni/nullCaller/NullCallerTest.java to accept flags or mark as flagless Backport-of: b78896b9aafcb15f453eaed6e154a5461581407b --- test/jdk/jni/nullCaller/NullCallerTest.java | 32 ++++----------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/test/jdk/jni/nullCaller/NullCallerTest.java b/test/jdk/jni/nullCaller/NullCallerTest.java index c7a25b693d0..106a90e89c8 100644 --- a/test/jdk/jni/nullCaller/NullCallerTest.java +++ b/test/jdk/jni/nullCaller/NullCallerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -37,17 +37,15 @@ // Test disabled on AIX since we cannot invoke the JVM on the primordial thread. -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.Properties; import jdk.test.lib.Platform; -import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.ProcessTools; public class NullCallerTest { @@ -87,28 +85,10 @@ public static void main(String[] args) throws Exception { // build the module used for the test compileTestModule(); - var launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerTest"); - var pb = new ProcessBuilder(launcher.toString()); - var env = pb.environment(); - - var libDir = Platform.libDir().toString(); - var vmDir = Platform.jvmLibDir().toString(); - - // set up shared library path - var sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName(); - env.compute(sharedLibraryPathEnvName, - (k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir); - env.compute(sharedLibraryPathEnvName, - (k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir); - - // launch the actual test - System.out.println("Launching: " + launcher + " shared library path: " + - env.get(sharedLibraryPathEnvName)); - new OutputAnalyzer(pb.start()) - .outputTo(System.out) - .errorTo(System.err) - .shouldHaveExitValue(0); - + ProcessBuilder pb = ProcessTools.createNativeTestProcessBuilder("NullCallerTest"); + System.out.println("Launching: " + pb.command() + " shared library path: " + + pb.environment().get(Platform.sharedLibraryPathVariableName())); + ProcessTools.executeProcess(pb).shouldHaveExitValue(0); } } From 2836734607ab15e75b25e82908c2596d1bbff8ee Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:55:22 +0000 Subject: [PATCH 110/298] 8324236: compiler/ciReplay/TestInliningProtectionDomain.java failed with RuntimeException: should only dump inline information for ... expected true, was false Backport-of: 72ba8178a8271d4a04a0b789f28b23414b8989ed --- .../jtreg/compiler/ciReplay/TestInliningProtectionDomain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java index f2cad243325..31e05ba7ecf 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java +++ b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java @@ -61,7 +61,7 @@ public void testAction() { boolean inlineFails = testClass == ProtectionDomainTestNoOtherCompilationPrivate.class; int inlineeCount = inlineFails ? 1 : 5; - List inlineesNormal = parseLogFile(LOG_FILE_NORMAL, entryString, "compile_id='" + getCompileIdFromFile(getReplayFileName()), inlineeCount); + List inlineesNormal = parseLogFile(LOG_FILE_NORMAL, entryString, "compile_id='" + getCompileIdFromFile(getReplayFileName()) + "'", inlineeCount); List inlineesReplay = parseLogFile(LOG_FILE_REPLAY, entryString, "test ()V", inlineeCount); verifyLists(inlineesNormal, inlineesReplay, inlineeCount); From 1dfda33a1fce44fdd935c348d0aab3515a5599b0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:56:54 +0000 Subject: [PATCH 111/298] 8319651: Several network tests ignore vm flags when start java process Backport-of: 9538f5d317972bbb82f7f2575819d35d2a5f8b91 --- test/jdk/java/net/InetAddress/ptr/Lookup.java | 23 ++++++----------- .../AcceptCauseFileDescriptorLeak.java | 5 ++-- .../net/ServerSocket/AcceptInheritHandle.java | 12 ++++----- .../getresourceasstream/TestDriver.java | 25 +++++++++---------- .../sealing/CheckSealedTest.java | 21 ++++++++-------- .../net/URLConnection/6212146/TestDriver.java | 3 ++- .../ContentHandlers/ContentHandlersTest.java | 15 ++++++----- .../java/net/httpclient/security/Driver.java | 7 +++--- .../spi/URLStreamHandlerProvider/Basic.java | 12 ++++----- .../net/ssl/DTLS/DTLSWontNegotiateV10.java | 7 +++--- .../TLSWontNegotiateDisabledCipherAlgos.java | 10 +++++--- .../www/protocol/jar/GetContentTypeTest.java | 12 ++++----- .../www/protocol/jar/jarbug/TestDriver.java | 13 +++++----- .../www/protocol/jrt/OtherResourcesTest.java | 19 +++++++------- 14 files changed, 88 insertions(+), 96 deletions(-) diff --git a/test/jdk/java/net/InetAddress/ptr/Lookup.java b/test/jdk/java/net/InetAddress/ptr/Lookup.java index 06643f3264c..79c53190c24 100644 --- a/test/jdk/java/net/InetAddress/ptr/Lookup.java +++ b/test/jdk/java/net/InetAddress/ptr/Lookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -41,18 +41,15 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.List; import java.util.stream.Stream; import java.util.stream.Collectors; -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; public class Lookup { private static final String HOST = "icann.org"; private static final String SKIP = "SKIP"; - private static final String CLASS_PATH = System.getProperty( - "test.class.path"); public static void main(String args[]) throws IOException { String addr = null; @@ -135,20 +132,16 @@ public static void main(String args[]) throws IOException { } static String lookupWithIPv4Prefer() throws IOException { - String java = JDKToolFinder.getTestJDKTool("java"); String testClz = Lookup.class.getName(); - List cmd = List.of(java, "-Djava.net.preferIPv4Stack=true", - "-cp", CLASS_PATH, testClz); - System.out.println("Executing: " + cmd); - return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput(); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-Djava.net.preferIPv4Stack=true", testClz); + return new OutputAnalyzer(pb.start()).getOutput(); } static String reverseWithIPv4Prefer(String addr) throws IOException { - String java = JDKToolFinder.getTestJDKTool("java"); String testClz = Lookup.class.getName(); - List cmd = List.of(java, "-Djava.net.preferIPv4Stack=true", - "-cp", CLASS_PATH, testClz, "reverse", addr); - System.out.println("Executing: " + cmd); - return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput(); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-Djava.net.preferIPv4Stack=true", testClz, "reverse", addr); + return new OutputAnalyzer(pb.start()).getOutput(); } } diff --git a/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java b/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java index f386179eeb6..5bbcad43e7d 100644 --- a/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java +++ b/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -31,7 +31,8 @@ * can cause fd leak. * This test may fail intermittently if foreign processes will * try to establish connection to the test server socket. - * @requires (os.family != "windows") + * @requires os.family != "windows" + * @requires vm.flagless * @library /test/lib * @build jdk.test.lib.Utils * jdk.test.lib.Asserts diff --git a/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java b/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java index 81bf874f593..96f09e4e044 100644 --- a/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java +++ b/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -34,10 +34,12 @@ import java.nio.channels.ServerSocketChannel; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import jdk.test.lib.net.IPSupport; +import jdk.test.lib.process.ProcessTools; public class AcceptInheritHandle { @@ -95,16 +97,12 @@ static void test(ServerSocketProducer ssp, String... jvmArgs) throws Exception { System.out.println("\nStarting test for " + ssp.name()); List commands = new ArrayList<>(); - commands.add(JAVA); - for (String arg : jvmArgs) - commands.add(arg); - commands.add("-cp"); - commands.add(CLASSPATH); + Collections.addAll(commands, jvmArgs); commands.add("AcceptInheritHandle"); commands.add(ssp.name()); System.out.println("Executing: "+ commands); - ProcessBuilder pb = new ProcessBuilder(commands); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(commands); pb.redirectError(ProcessBuilder.Redirect.INHERIT); Process serverProcess = pb.start(); DataInputStream dis = new DataInputStream(serverProcess.getInputStream()); diff --git a/test/jdk/java/net/URLClassLoader/getresourceasstream/TestDriver.java b/test/jdk/java/net/URLClassLoader/getresourceasstream/TestDriver.java index 526689e21ea..a7cfae09c3e 100644 --- a/test/jdk/java/net/URLClassLoader/getresourceasstream/TestDriver.java +++ b/test/jdk/java/net/URLClassLoader/getresourceasstream/TestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -36,7 +36,6 @@ * @run main/othervm TestDriver */ -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.ProcessTools; import java.io.IOException; @@ -53,33 +52,33 @@ public static void main(String[] args) throws Throwable { Path userDir = Paths.get(System.getProperty("user.dir")); - String java = JDKToolFinder.getTestJDKTool("java"); String basename = userDir.getFileName().toString(); setup(userDir); ProcessBuilder[] tests = new ProcessBuilder[]{ - new ProcessBuilder( - java, TEST_NAME, "./" + ARCHIVE_NAME + ProcessTools.createTestJavaProcessBuilder( + TEST_NAME, + "./" + ARCHIVE_NAME ), - new ProcessBuilder( - java, "-cp", ".", + ProcessTools.createTestJavaProcessBuilder( + "-cp", ".", "-Djava.security.policy=file:./policy", "-Djava.security.manager", TEST_NAME, "./" + ARCHIVE_NAME ), - new ProcessBuilder( - java, "-cp", ".", + ProcessTools.createTestJavaProcessBuilder( + "-cp", ".", "-Djava.security.policy=file:./policy", "-Djava.security.manager", TEST_NAME, "./" + ARCHIVE_NAME ), - new ProcessBuilder( - java, "-cp", "..", + ProcessTools.createTestJavaProcessBuilder( + "-cp", "..", "-Djava.security.policy=file:../policy", "-Djava.security.manager", TEST_NAME, "../" + ARCHIVE_NAME ).directory(userDir.resolve("tmp").toFile()), - new ProcessBuilder( - java, "-cp", basename, + ProcessTools.createTestJavaProcessBuilder( + "-cp", basename, "-Djava.security.policy=file:" + basename + "/policy", "-Djava.security.manager", TEST_NAME, basename + "/" + ARCHIVE_NAME diff --git a/test/jdk/java/net/URLClassLoader/sealing/CheckSealedTest.java b/test/jdk/java/net/URLClassLoader/sealing/CheckSealedTest.java index b733b678871..cb474645e45 100644 --- a/test/jdk/java/net/URLClassLoader/sealing/CheckSealedTest.java +++ b/test/jdk/java/net/URLClassLoader/sealing/CheckSealedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -46,6 +46,8 @@ import java.util.List; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import static jdk.test.lib.process.ProcessTools.createTestJavaProcessBuilder; +import static jdk.test.lib.process.ProcessTools.executeCommand; public class CheckSealedTest { private static final String ARCHIVE_NAME = "b.jar"; @@ -55,31 +57,30 @@ public static void main(String[] args) String baseDir = System.getProperty("user.dir") + File.separator; String javac = JDKToolFinder.getTestJDKTool("javac"); - String java = JDKToolFinder.getTestJDKTool("java"); setup(baseDir); String srcDir = System.getProperty("test.src"); String cp = srcDir + File.separator + "a" + File.pathSeparator + srcDir + File.separator + "b.jar" + File.pathSeparator + "."; + + // Compile + ProcessTools.executeCommand(javac, "-cp", cp, "-d", ".", + srcDir + File.separator + TEST_NAME + ".java"); + List allCMDs = List.of( - // Compile command - new String[]{ - javac, "-cp", cp, "-d", ".", - srcDir + File.separator + TEST_NAME + ".java" - }, // Run test the first time new String[]{ - java, "-cp", cp, TEST_NAME, "1" + "-cp", cp, TEST_NAME, "1" }, // Run test the second time new String[]{ - java, "-cp", cp, TEST_NAME, "2" + "-cp", cp, TEST_NAME, "2" } ); for (String[] cmd : allCMDs) { - ProcessTools.executeCommand(cmd) + executeCommand(createTestJavaProcessBuilder(cmd)) .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(0); diff --git a/test/jdk/java/net/URLConnection/6212146/TestDriver.java b/test/jdk/java/net/URLConnection/6212146/TestDriver.java index d6bffb198de..5f474759031 100644 --- a/test/jdk/java/net/URLConnection/6212146/TestDriver.java +++ b/test/jdk/java/net/URLConnection/6212146/TestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -27,6 +27,7 @@ * @summary URLConnection.connect() fails on JAR Entry it creates * file handler leak * @library /test/lib + * @requires vm.flagless * @build jdk.test.lib.Utils * jdk.test.lib.Asserts * jdk.test.lib.JDKToolFinder diff --git a/test/jdk/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java b/test/jdk/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java index 49b2d7a6b64..b15d5aca8ec 100644 --- a/test/jdk/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java +++ b/test/jdk/java/net/URLConnection/ContentHandlers/ContentHandlersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -21,6 +21,8 @@ * questions. */ +import jdk.test.lib.process.ProcessTools; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -56,6 +58,7 @@ /* * @test * @bug 8064925 + * @library /test/lib * @summary Basic test for ContentHandler. Ensures discovery paths for content * handlers follow a particular order. */ @@ -268,14 +271,10 @@ private static Result java(Map properties, Collection classpath, String classname, String... args) { - String java = getJDKTool("java"); - - List commands = new ArrayList<>(); - commands.add(java); - commands.addAll(properties.entrySet() + List commands = properties.entrySet() .stream() .map(e -> "-D" + e.getKey() + "=" + e.getValue()) - .collect(Collectors.toList())); + .collect(Collectors.toList()); String cp = classpath.stream() .map(Path::toString) @@ -285,7 +284,7 @@ private static Result java(Map properties, commands.add(classname); commands.addAll(Arrays.asList(args)); - return run(new ProcessBuilder(commands)); + return run(ProcessTools.createTestJavaProcessBuilder(commands)); } private static Result run(ProcessBuilder b) { diff --git a/test/jdk/java/net/httpclient/security/Driver.java b/test/jdk/java/net/httpclient/security/Driver.java index 98094a6cdc9..fc3dc4346ff 100644 --- a/test/jdk/java/net/httpclient/security/Driver.java +++ b/test/jdk/java/net/httpclient/security/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -56,6 +56,7 @@ import java.util.List; import java.util.stream.Collectors; import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; /** * Driver for tests @@ -126,12 +127,10 @@ public static void runtest(String policy, String testnum, String addProp) throws String testClassPath = System.getProperty("test.class.path", "?"); String testClasses = System.getProperty("test.classes", "?"); String sep = System.getProperty("file.separator", "?"); - String javaCmd = testJdk + sep + "bin" + sep + "java"; int retval = 10; // 10 is special exit code denoting a bind error // in which case, we retry while (retval == 10) { List cmd = new ArrayList<>(); - cmd.add(javaCmd); cmd.add("-ea"); cmd.add("-esa"); cmd.add("-Dtest.jdk=" + testJdk); @@ -150,7 +149,7 @@ public static void runtest(String policy, String testnum, String addProp) throws cmd.add("Security"); cmd.add(testnum); - ProcessBuilder processBuilder = new ProcessBuilder(cmd) + ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(cmd) .redirectOutput(ProcessBuilder.Redirect.PIPE) .redirectErrorStream(true); diff --git a/test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java b/test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java index d2c635fb9ec..fc62594e032 100644 --- a/test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java +++ b/test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -45,6 +45,8 @@ import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; + +import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.FileUtils; import jdk.test.lib.JDKToolFinder; import static java.lang.String.format; @@ -234,12 +236,8 @@ static void quickFail(Result r) { static Result java(List sysProps, Collection classpath, String classname, String arg) { - String java = getJDKTool("java"); - List commands = new ArrayList<>(); - commands.add(java); - for (String prop : sysProps) - commands.add(prop); + List commands = new ArrayList<>(sysProps); String cp = classpath.stream() .map(Path::toString) @@ -249,7 +247,7 @@ static Result java(List sysProps, Collection classpath, commands.add(classname); commands.add(arg); - return run(new ProcessBuilder(commands)); + return run(ProcessTools.createTestJavaProcessBuilder(commands)); } static Result run(ProcessBuilder pb) { diff --git a/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java index f67a02b3052..f8b72005527 100644 --- a/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java +++ b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -21,13 +21,13 @@ * questions. */ +import jdk.test.lib.process.ProcessTools; import jdk.test.lib.security.SecurityUtils; import javax.net.ssl.*; import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -87,14 +87,13 @@ private static void runServer(String protocol) throws Exception { Process clientProcess = null; try (DTLSServer server = new DTLSServer(protocol)) { List command = List.of( - Path.of(System.getProperty("java.home"), "bin", "java").toString(), "DTLSWontNegotiateV10", // if server is "DTLS" then the client should be v1.0 and vice versa protocol.equals(DTLS) ? DTLSV_1_0 : DTLS, Integer.toString(server.getListeningPortNumber()) ); - ProcessBuilder builder = new ProcessBuilder(command); + ProcessBuilder builder = ProcessTools.createTestJavaProcessBuilder(command); clientProcess = builder.inheritIO().start(); server.run(); System.out.println("Success: DTLSv1.0 connection was not established."); diff --git a/test/jdk/javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java b/test/jdk/javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java index b120f33da94..b22b4f02165 100644 --- a/test/jdk/javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java +++ b/test/jdk/javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -21,17 +21,19 @@ * questions. */ +import jdk.test.lib.process.ProcessTools; + import javax.net.ssl.*; import java.io.IOException; import java.net.Socket; import java.nio.charset.StandardCharsets; -import java.nio.file.Path; import java.security.Security; import java.util.List; /* * @test id=Server * @bug 8301379 + * @library /test/lib * @summary Verify that Java will not negotiate disabled cipher suites when the * other side of the connection requests them. * @@ -42,6 +44,7 @@ /* * @test id=Client * @bug 8301379 + * @library /test/lib * @summary Verify that Java will not negotiate disabled cipher suites when the * other side of the connection requests them. * @@ -61,13 +64,12 @@ public static void main(String [] args) throws Exception { if (args[0].equals("server")) { try (TLSServer server = new TLSServer(useDisabledAlgo)) { List command = List.of( - Path.of(System.getProperty("java.home"), "bin", "java").toString(), "TLSWontNegotiateDisabledCipherAlgos", "client", Boolean.toString(!useDisabledAlgo), Integer.toString(server.getListeningPort()) ); - ProcessBuilder builder = new ProcessBuilder(command); + ProcessBuilder builder = ProcessTools.createTestJavaProcessBuilder(command); Process p = builder.inheritIO().start(); server.run(); p.destroy(); diff --git a/test/jdk/sun/net/www/protocol/jar/GetContentTypeTest.java b/test/jdk/sun/net/www/protocol/jar/GetContentTypeTest.java index 16a59d65dc2..c730b693910 100644 --- a/test/jdk/sun/net/www/protocol/jar/GetContentTypeTest.java +++ b/test/jdk/sun/net/www/protocol/jar/GetContentTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -34,10 +34,10 @@ * GetContentType GetContentTypeTest * @run main/othervm GetContentTypeTest * @summary Test JarURLConnection.getContentType would - * would return default "content/unknown" + * return default "content/unknown" */ -import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import java.io.File; @@ -49,9 +49,9 @@ public static void main(String[] args) throws Throwable { Path resJar = Paths.get(System.getProperty("test.src"), "resource.jar"); Path classes = Paths.get(System.getProperty("test.classes")); - ProcessTools.executeCommand( - JDKToolFinder.getTestJDKTool("java"), - "-cp", resJar + File.pathSeparator + classes, "GetContentType") + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-cp", resJar + File.pathSeparator + classes, "GetContentType"); + new OutputAnalyzer(pb.start()) .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(0); diff --git a/test/jdk/sun/net/www/protocol/jar/jarbug/TestDriver.java b/test/jdk/sun/net/www/protocol/jar/jarbug/TestDriver.java index cb27c554686..19ab2a668d4 100644 --- a/test/jdk/sun/net/www/protocol/jar/jarbug/TestDriver.java +++ b/test/jdk/sun/net/www/protocol/jar/jarbug/TestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -47,6 +47,7 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import jdk.test.lib.JDKToolFinder; import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; @@ -81,14 +82,14 @@ public static void main(String[] args) throws Throwable { CompilerUtils.compile(srcDir.resolve("src").resolve("test"), targetDir); // Run tests - String java = JDKToolFinder.getTestJDKTool("java"); String cp = targetDir.toString() + File.pathSeparator + jarFile; String[] tests = new String[]{"TestBug4361044", "TestBug4523159"}; for (String test : tests) { - ProcessTools.executeCommand(java, "-cp", cp, test) - .outputTo(System.out) - .errorTo(System.out) - .shouldHaveExitValue(0); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("-cp", cp, test); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.out) + .shouldHaveExitValue(0); } } } diff --git a/test/jdk/sun/net/www/protocol/jrt/OtherResourcesTest.java b/test/jdk/sun/net/www/protocol/jrt/OtherResourcesTest.java index 00ec82282e0..0c901f95cc7 100644 --- a/test/jdk/sun/net/www/protocol/jrt/OtherResourcesTest.java +++ b/test/jdk/sun/net/www/protocol/jrt/OtherResourcesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -21,8 +21,8 @@ * questions. */ -import jdk.test.lib.JDKToolFinder; -import static jdk.test.lib.process.ProcessTools.executeCommand; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; /** * @test @@ -39,12 +39,13 @@ public class OtherResourcesTest { public static void main(String[] args) throws Throwable { String classes = System.getProperty("test.classes"); - executeCommand(JDKToolFinder.getTestJDKTool("java"), - "--limit-modules", "java.base", - "-cp", classes, "OtherResources") - .outputTo(System.out) - .errorTo(System.out) - .shouldHaveExitValue(0); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "--limit-modules", "java.base", + "-cp", classes, "OtherResources"); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.out) + .shouldHaveExitValue(0); } } From aa1fe7a1201ed7884c33103af31ca11370224b55 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:58:45 +0000 Subject: [PATCH 112/298] 8326824: Test: remove redundant test in compiler/vectorapi/reshape/utils/TestCastMethods.java Backport-of: 552411f832eb35d739c7978b8c1f8d0dfd4b2161 --- .../jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java index 2c1c765f4bf..61f8316cf51 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java @@ -62,7 +62,6 @@ public class TestCastMethods { makePair(FSPEC128, ISPEC128), makePair(FSPEC64, DSPEC128), makePair(FSPEC128, DSPEC256), - makePair(FSPEC128, ISPEC128), makePair(FSPEC128, SSPEC64), makePair(DSPEC128, FSPEC64), makePair(DSPEC256, FSPEC128), From bb2ddc0818925af2dcb74a32a362fdf8e1a42493 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 17:59:04 +0000 Subject: [PATCH 113/298] 8326948: Force English locale for timeout formatting Backport-of: e772e7817981b7b5c01b95245cf2022372494619 --- test/jdk/java/awt/regtesthelpers/PassFailJFrame.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index 15a914934e7..741cee4d1d7 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -47,6 +47,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -542,7 +543,8 @@ private void updateTime(final long leftTime) { long hours = leftTime / 3_600_000; long minutes = (leftTime - hours * 3_600_000) / 60_000; long seconds = (leftTime - hours * 3_600_000 - minutes * 60_000) / 1_000; - label.setText(String.format("Test timeout: %02d:%02d:%02d", + label.setText(String.format(Locale.ENGLISH, + "Test timeout: %02d:%02d:%02d", hours, minutes, seconds)); } From 660c00a7fc462378db703404c10d5166641d3ca7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 18:00:58 +0000 Subject: [PATCH 114/298] 8319648: java/lang/SecurityManager tests ignore vm flags Backport-of: 437cf354e2d1f7df79fa32265ccf86a0e84257b5 --- .../modules/CustomSecurityManagerTest.java | 4 ++-- test/jdk/java/lang/System/SecurityManagerWarnings.java | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/jdk/java/lang/SecurityManager/modules/CustomSecurityManagerTest.java b/test/jdk/java/lang/SecurityManager/modules/CustomSecurityManagerTest.java index 92b9e44f892..cd9201a3c22 100644 --- a/test/jdk/java/lang/SecurityManager/modules/CustomSecurityManagerTest.java +++ b/test/jdk/java/lang/SecurityManager/modules/CustomSecurityManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -64,7 +64,7 @@ public Object[][] testCases() { @Test(dataProvider = "testCases") public void testProvider(List args) throws Throwable { - ProcessBuilder processBuilder = ProcessTools.createLimitedTestJavaProcessBuilder(args); + ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(args); OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(processBuilder); outputAnalyzer.shouldHaveExitValue(0); } diff --git a/test/jdk/java/lang/System/SecurityManagerWarnings.java b/test/jdk/java/lang/System/SecurityManagerWarnings.java index c3e3e9a8517..6456f69c2f3 100644 --- a/test/jdk/java/lang/System/SecurityManagerWarnings.java +++ b/test/jdk/java/lang/System/SecurityManagerWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -28,7 +28,6 @@ * @library /test/lib */ -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; @@ -51,6 +50,7 @@ public static void main(String args[]) throws Exception { }; """); + System.setProperty("test.noclasspath", "true"); String testClasses = System.getProperty("test.classes"); disallowTest(null, testClasses); @@ -131,13 +131,11 @@ static OutputAnalyzer checkInstallMessage(OutputAnalyzer oa, String cp) { static OutputAnalyzer run(String prop, String cp) throws Exception { ProcessBuilder pb; if (prop == null) { - pb = new ProcessBuilder( - JDKToolFinder.getJDKTool("java"), + pb = ProcessTools.createTestJavaProcessBuilder( "-cp", cp, "SecurityManagerWarnings", "run"); } else { - pb = new ProcessBuilder( - JDKToolFinder.getJDKTool("java"), + pb = ProcessTools.createTestJavaProcessBuilder( "-cp", cp, "-Djava.security.manager=" + prop, "-Djava.security.policy=policy", From c33815ad3c86bd38432f80877c0bc1ac1af15070 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 25 Mar 2024 18:03:02 +0000 Subject: [PATCH 115/298] 8327261: Parsing test for Double/Float succeeds w/o testing all bad cases Backport-of: 9f7094079b6eb6b60b345955dba358a2d5c90931 --- test/jdk/java/lang/Double/ParseDouble.java | 21 +++++++++------------ test/jdk/java/lang/Float/ParseFloat.java | 21 +++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/test/jdk/java/lang/Double/ParseDouble.java b/test/jdk/java/lang/Double/ParseDouble.java index ff4a3b80af3..5ee4cc680e1 100644 --- a/test/jdk/java/lang/Double/ParseDouble.java +++ b/test/jdk/java/lang/Double/ParseDouble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -556,24 +556,21 @@ private static void rudimentaryTest() { */ private static void testParsing(String [] input, boolean exceptionalInput) { - for(int i = 0; i < input.length; i++) { - double d; - + for (String s : input) { try { - d = Double.parseDouble(input[i]); - check(input[i]); - } - catch (NumberFormatException e) { - if (! exceptionalInput) { + Double.parseDouble(s); + check(s); + } catch (NumberFormatException e) { + if (!exceptionalInput) { throw new RuntimeException("Double.parseDouble rejected " + - "good string `" + input[i] + + "good string `" + s + "'."); } - break; + continue; } if (exceptionalInput) { throw new RuntimeException("Double.parseDouble accepted " + - "bad string `" + input[i] + + "bad string `" + s + "'."); } } diff --git a/test/jdk/java/lang/Float/ParseFloat.java b/test/jdk/java/lang/Float/ParseFloat.java index c40a9ea3338..8f9c300b02d 100644 --- a/test/jdk/java/lang/Float/ParseFloat.java +++ b/test/jdk/java/lang/Float/ParseFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, 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 @@ -276,24 +276,21 @@ private static void rudimentaryTest() { */ private static void testParsing(String [] input, boolean exceptionalInput) { - for(int i = 0; i < input.length; i++) { - double d; - + for (String s : input) { try { - d = Float.parseFloat(input[i]); - check(input[i]); - } - catch (NumberFormatException e) { - if (! exceptionalInput) { + Float.parseFloat(s); + check(s); + } catch (NumberFormatException e) { + if (!exceptionalInput) { throw new RuntimeException("Float.parseFloat rejected " + - "good string `" + input[i] + + "good string `" + s + "'."); } - break; + continue; } if (exceptionalInput) { throw new RuntimeException("Float.parseFloat accepted " + - "bad string `" + input[i] + + "bad string `" + s + "'."); } } From a2557bbe1ac3c5231f76df21c1bb6bd4d9840c80 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 26 Mar 2024 08:19:04 +0000 Subject: [PATCH 116/298] 8328948: GHA: Restoring sysroot from cache skips the build after JDK-8326960 Backport-of: 447436e18c754424a62af5135fb3a8973564091d --- .github/workflows/build-cross-compile.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 3928d3dc0cc..1c1aee9061f 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -177,7 +177,7 @@ jobs: echo "Dumping config.log:" && cat config.log && exit 1) - if: steps.create-sysroot.outcome == 'success' + if: steps.create-sysroot.outcome == 'success' || steps.get-cached-sysroot.outputs.cache-hit == 'true' - name: 'Build' id: build @@ -185,4 +185,4 @@ jobs: with: make-target: 'hotspot ${{ inputs.make-arguments }}' platform: linux-${{ matrix.target-cpu }} - if: steps.create-sysroot.outcome == 'success' + if: steps.create-sysroot.outcome == 'success' || steps.get-cached-sysroot.outputs.cache-hit == 'true' From f2a013bd33910a04352d605f811263b55fc02676 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 26 Mar 2024 11:05:42 +0000 Subject: [PATCH 117/298] 8328825: Google CAInterop test failures Backport-of: 70a15c73638f45b9ed629abc0ea2d86a324bf624 --- .../certification/CAInterop.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 0ef37377b1e..c1a0d782cb7 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -207,8 +207,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop globalsigneccrootcar4 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 DEFAULT */ /* @@ -217,8 +216,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar1 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 DEFAULT */ /* @@ -227,8 +225,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar2 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 DEFAULT */ /* @@ -237,8 +234,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar3 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 DEFAULT */ /* @@ -247,8 +243,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar4 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 DEFAULT */ /* From e3f36477d4a8b2831580fde423fdd748f367e93e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 27 Mar 2024 10:02:16 +0000 Subject: [PATCH 118/298] 8280056: gtest/LargePageGtests.java#use-large-pages failed "os.release_one_mapping_multi_commits_vm" Backport-of: 66520be7a752ebade6c88d164bc87c4bfcfce40a --- test/hotspot/gtest/runtime/test_os.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index fb2ab86a7b9..9b0c7d38507 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -504,7 +504,9 @@ TEST_VM(os, release_multi_mappings) { // ...re-reserve the middle stripes. This should work unless release silently failed. address p2 = (address)os::attempt_reserve_memory_at((char*)p_middle_stripes, middle_stripe_len); + ASSERT_EQ(p2, p_middle_stripes); + PRINT_MAPPINGS("C"); // Clean up. Release all mappings. @@ -548,26 +550,29 @@ TEST_VM(os, release_bad_ranges) { TEST_VM(os, release_one_mapping_multi_commits) { // Test that we can release an area consisting of interleaved // committed and uncommitted regions: - const size_t stripe_len = 4 * M; - const int num_stripes = 4; + const size_t stripe_len = os::vm_allocation_granularity(); + const int num_stripes = 6; const size_t total_range_len = stripe_len * num_stripes; // reserve address space... address p = reserve_one_commit_multiple(num_stripes, stripe_len); - ASSERT_NE(p, (address)NULL); PRINT_MAPPINGS("A"); + ASSERT_NE(p, (address)nullptr); - // .. release it... - ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); + // // make things even more difficult by trying to reserve at the border of the region + address border = p + num_stripes * stripe_len; + address p2 = (address)os::attempt_reserve_memory_at((char*)border, stripe_len); PRINT_MAPPINGS("B"); - // re-reserve it. This should work unless release failed. - address p2 = (address)os::attempt_reserve_memory_at((char*)p, total_range_len); - ASSERT_EQ(p2, p); - PRINT_MAPPINGS("C"); + ASSERT_TRUE(p2 == nullptr || p2 == border); ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); - PRINT_MAPPINGS("D"); + PRINT_MAPPINGS("C"); + + if (p2 != nullptr) { + ASSERT_TRUE(os::release_memory((char*)p2, stripe_len)); + PRINT_MAPPINGS("D"); + } } static void test_show_mappings(address start, size_t size) { From 7751996220f2d814f2da7cc1618a6f20f1c5be00 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 28 Mar 2024 07:59:30 +0000 Subject: [PATCH 119/298] 8326661: sun/java2d/cmm/ColorConvertOp/ColConvTest.java assumes profiles were generated by LCMS Backport-of: 1f43fa0f8b0f956b41015e0ebc257e15a11ad99b --- .../jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java index 22e055fbe8e..97ed058ff5a 100644 --- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 6476665 7033534 6830714 8052162 8196572 + * @bug 6476665 7033534 6830714 8052162 8196572 8326661 * @summary Verifies color conversion of Component Color Model based images * @run main ColConvCCMTest */ @@ -59,8 +59,8 @@ public class ColConvCCMTest extends ColConvTest { 2.5, // sRGB (isOpenProfile() ? 45.0 : 10.1), // LINEAR_RGB 10.5, // GRAY - (isOpenProfile() ? 215.0 : 45.5), // PYCC - (isOpenProfile() ? 56.0 : 47.5) // CIEXYZ + (isOpenProfile() ? 215.0 : 64.5), // PYCC + (isOpenProfile() ? 56.0 : 55.5) // CIEXYZ }; final static String [] gldImgNames = { From 0bfb53c878d8222ad9836f9e960d7433ed66a2aa Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 28 Mar 2024 07:59:55 +0000 Subject: [PATCH 120/298] 8323994: gtest runner repeats test name for every single gtest assertion Backport-of: 1aae980c549741cf5fc5ca51f3c299285bafa49d --- test/hotspot/jtreg/gtest/GTestResultParser.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/gtest/GTestResultParser.java b/test/hotspot/jtreg/gtest/GTestResultParser.java index c30ea63e654..ffa98bf29f2 100644 --- a/test/hotspot/jtreg/gtest/GTestResultParser.java +++ b/test/hotspot/jtreg/gtest/GTestResultParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -57,7 +57,10 @@ public GTestResultParser(Path file) { testCase = xmlReader.getAttributeValue("", "name"); break; case "failure": - failedTests.add(testSuite + "::" + testCase); + String failedStr = testSuite + "::" + testCase; + if (!failedTests.contains(failedStr)) { + failedTests.add(failedStr); + } break; default: // ignore From c263bc5ee771a3784fc2044f362592891ba1ca53 Mon Sep 17 00:00:00 2001 From: Elif Aslan Date: Thu, 28 Mar 2024 18:11:31 +0000 Subject: [PATCH 121/298] 8327998: Enable java/lang/ProcessBuilder/JspawnhelperProtocol.java on Mac Backport-of: cc1800fa4de3c1369efd46f5ca967ea82763f5d5 --- test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java index 1949571cca7..d31905ccc63 100644 --- a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java +++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java @@ -25,7 +25,7 @@ /* * @test * @bug 8307990 - * @requires (os.family == "linux") | (os.family == "aix") + * @requires (os.family == "linux") | (os.family == "aix") | (os.family == "mac") * @requires vm.debug * @requires vm.flagless * @library /test/lib From 6791646b9f9673ea36a67e5af7584929dfb16069 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Mon, 1 Apr 2024 01:57:12 +0000 Subject: [PATCH 122/298] 8328812: Update and move siphash license Backport-of: ce7ebaa606f96fdfee66d300b56022d9903b5ae3 --- src/{hotspot => java.base}/share/legal/siphash.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/{hotspot => java.base}/share/legal/siphash.md (98%) diff --git a/src/hotspot/share/legal/siphash.md b/src/java.base/share/legal/siphash.md similarity index 98% rename from src/hotspot/share/legal/siphash.md rename to src/java.base/share/legal/siphash.md index 1583f229e1e..a1183acf2b0 100644 --- a/src/hotspot/share/legal/siphash.md +++ b/src/java.base/share/legal/siphash.md @@ -4,12 +4,12 @@ SipHash reference C implementation ``` - Copyright (c) 2012-2021 Jean-Philippe Aumasson - - Copyright (c) 2012-2014 Daniel J. Bernstein + Copyright (c) 2016 Jean-Philippe Aumasson + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. + You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see From 245de5938d5e29827814681c139c4d4d16262f10 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 1 Apr 2024 16:21:29 +0000 Subject: [PATCH 123/298] 8309752: com/sun/jdi/SetLocalWhileThreadInNative.java fails with virtual test thread factory due to OpaqueFrameException Backport-of: 1612b6dc6e7075e1c0c82d0e92910051c8066fe5 --- test/jdk/ProblemList-Virtual.txt | 1 - .../com/sun/jdi/SetLocalWhileThreadInNative.java | 13 ++++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index d813a57e8f1..6d4ff898551 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -29,7 +29,6 @@ com/sun/jdi/EATests.java#id0 8264699 generic- com/sun/jdi/ExceptionEvents.java 8278470 generic-all com/sun/jdi/RedefineCrossStart.java 8278470 generic-all -com/sun/jdi/SetLocalWhileThreadInNative.java 8285422 generic-all com/sun/jdi/cds/CDSBreakpointTest.java 8307778 generic-all com/sun/jdi/cds/CDSDeleteAllBkptsTest.java 8307778 generic-all com/sun/jdi/cds/CDSFieldWatchpoints.java 8307778 generic-all diff --git a/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java b/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java index 6daa29103e4..c4d8db5b411 100644 --- a/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java +++ b/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java @@ -163,13 +163,20 @@ protected void runTests() Asserts.assertEQ(frame.location().method().toString(), "SetLocalWhileThreadInNativeTarget.dontinline_testMethod()"); List localVars = frame.visibleVariables(); boolean changedLocal = false; + boolean caughtOFE = false; for (LocalVariable lv : localVars) { if (lv.name().equals("zero")) { - frame.setValue(lv, vm().mirrorOf(0)); // triggers deoptimization! - changedLocal = true; + try { + frame.setValue(lv, vm().mirrorOf(0)); // triggers deoptimization! + changedLocal = true; + } catch (OpaqueFrameException e) { + caughtOFE = true; + } } } - Asserts.assertTrue(changedLocal); + boolean isVirtualThread = "Virtual".equals(System.getProperty("main.wrapper")); + Asserts.assertTrue(caughtOFE == isVirtualThread); + Asserts.assertTrue(changedLocal == !isVirtualThread); // signal stop os.write(STOP); From 2800d8bc708f7ccdf32ef64c52f99f40b1459698 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 1 Apr 2024 16:25:08 +0000 Subject: [PATCH 124/298] 8326643: JDK server does not send a dummy change_cipher_spec record after HelloRetryRequest message Backport-of: d44aaa37f98dd383aebbec097427feb1f1c29b74 --- .../classes/sun/security/ssl/ServerHello.java | 11 +- .../net/ssl/TLSv13/EngineOutOfSeqCCS.java | 284 ++++++++++++++++++ 2 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java diff --git a/src/java.base/share/classes/sun/security/ssl/ServerHello.java b/src/java.base/share/classes/sun/security/ssl/ServerHello.java index 904cf59193f..3ec66e0f0f2 100644 --- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -794,6 +794,15 @@ public byte[] produce(ConnectionContext context, hhrm.write(shc.handshakeOutput); shc.handshakeOutput.flush(); + // In TLS1.3 middlebox compatibility mode the server sends a + // dummy change_cipher_spec record immediately after its + // first handshake message. This may either be after + // a ServerHello or a HelloRetryRequest. + // (RFC 8446, Appendix D.4) + shc.conContext.outputRecord.changeWriteCiphers( + SSLWriteCipher.nullTlsWriteCipher(), + (clientHello.sessionId.length() != 0)); + // Stateless, shall we clean up the handshake context as well? shc.handshakeHash.finish(); // forgot about the handshake hash shc.handshakeExtensions.clear(); diff --git a/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java b/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java new file mode 100644 index 00000000000..eca1f94d62e --- /dev/null +++ b/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java @@ -0,0 +1,284 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8326643 + * @summary Test for out-of-sequence change_cipher_spec in TLSv1.3 + * @library /javax/net/ssl/templates + * @run main/othervm EngineOutOfSeqCCS isHRRTest + * @run main/othervm EngineOutOfSeqCCS + */ + +import java.nio.ByteBuffer; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; + +public class EngineOutOfSeqCCS extends SSLEngineTemplate { + + /* + * Enables logging of the SSLEngine operations. + */ + private static final boolean logging = true; + private static final boolean dumpBufs = true; + + // Define a few basic TLS records we might need + private static final int TLS_RECTYPE_CCS = 0x14; + private static final int TLS_RECTYPE_ALERT = 0x15; + private static final int TLS_RECTYPE_HANDSHAKE = 0x16; + private static final int TLS_RECTYPE_APPDATA = 0x17; + + SSLEngineResult clientResult, serverResult; + + public EngineOutOfSeqCCS() throws Exception { + super(); + } + + public static void main(String[] args) throws Exception{ + new EngineOutOfSeqCCS().runDemo(args.length > 0 && + args[0].equals("isHRRTest")); + } + + private void runDemo(boolean isHRRTest) throws Exception { + + if (isHRRTest) { + SSLParameters sslParams = new SSLParameters(); + sslParams.setNamedGroups(new String[] {"secp384r1"}); + serverEngine.setSSLParameters(sslParams); + } + // Client generates Client Hello + clientResult = clientEngine.wrap(clientOut, cTOs); + log("client wrap: ", clientResult); + runDelegatedTasks(clientEngine); + cTOs.flip(); + dumpByteBuffer("CLIENT-TO-SERVER", cTOs); + + // Server consumes Client Hello + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverEngine); + cTOs.compact(); + + // Server generates ServerHello/HelloRetryRequest + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverEngine); + sTOc.flip(); + + dumpByteBuffer("SERVER-TO-CLIENT", sTOc); + + // client consumes ServerHello/HelloRetryRequest + clientResult = clientEngine.unwrap(sTOc, clientIn); + log("client unwrap: ", clientResult); + runDelegatedTasks(clientEngine); + sTOc.compact(); + + // Server generates CCS + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverEngine); + sTOc.flip(); + dumpByteBuffer("SERVER-TO-CLIENT", sTOc); + + if (isTlsMessage(sTOc, TLS_RECTYPE_CCS)) { + System.out.println("=========== CCS found ==========="); + } else { + // In TLS1.3 middlebox compatibility mode the server sends a + // dummy change_cipher_spec record immediately after its + // first handshake message. This may either be after + // a ServerHello or a HelloRetryRequest. + // (RFC 8446, Appendix D.4) + throw new SSLException( + "Server should generate change_cipher_spec record"); + } + clientEngine.closeOutbound(); + serverEngine.closeOutbound(); + } + + /** + * Look at an incoming TLS record and see if it is the desired + * record type, and where appropriate the correct subtype. + * + * @param srcRecord The input TLS record to be evaluated. This + * method will only look at the leading message if multiple + * TLS handshake messages are coalesced into a single record. + * @param reqRecType The requested TLS record type + * @param recParams Zero or more integer sub type fields. For CCS + * and ApplicationData, no params are used. For handshake records, + * one value corresponding to the HandshakeType is required. + * For Alerts, two values corresponding to AlertLevel and + * AlertDescription are necessary. + * + * @return true if the proper handshake message is the first one + * in the input record, false otherwise. + */ + private boolean isTlsMessage(ByteBuffer srcRecord, int reqRecType, + int... recParams) { + boolean foundMsg = false; + + if (srcRecord.hasRemaining()) { + srcRecord.mark(); + + // Grab the fields from the TLS Record + int recordType = Byte.toUnsignedInt(srcRecord.get()); + byte ver_major = srcRecord.get(); + byte ver_minor = srcRecord.get(); + + if (recordType == reqRecType) { + // For any zero-length recParams, making sure the requested + // type is sufficient. + if (recParams.length == 0) { + foundMsg = true; + } else { + switch (recordType) { + case TLS_RECTYPE_CCS: + case TLS_RECTYPE_APPDATA: + // We really shouldn't find ourselves here, but + // if someone asked for these types and had more + // recParams we can ignore them. + foundMsg = true; + break; + case TLS_RECTYPE_ALERT: + // Needs two params, AlertLevel and + //AlertDescription + if (recParams.length != 2) { + throw new RuntimeException( + "Test for Alert requires level and desc."); + } else { + int level = Byte.toUnsignedInt( + srcRecord.get()); + int desc = Byte.toUnsignedInt(srcRecord.get()); + if (level == recParams[0] && + desc == recParams[1]) { + foundMsg = true; + } + } + break; + case TLS_RECTYPE_HANDSHAKE: + // Needs one parameter, HandshakeType + if (recParams.length != 1) { + throw new RuntimeException( + "Test for Handshake requires only HS type"); + } else { + // Go into the first handshake message in the + // record and grab the handshake message header. + // All we need to do is parse out the leading + // byte. + int msgHdr = srcRecord.getInt(); + int msgType = (msgHdr >> 24) & 0x000000FF; + if (msgType == recParams[0]) { + foundMsg = true; + } + } + break; + } + } + } + + srcRecord.reset(); + } + + return foundMsg; + } + + private static String tlsRecType(int type) { + switch (type) { + case 20: + return "Change Cipher Spec"; + case 21: + return "Alert"; + case 22: + return "Handshake"; + case 23: + return "Application Data"; + default: + return ("Unknown (" + type + ")"); + } + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + System.out.println("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + System.out.println(str); + } + } + + /** + * Hex-dumps a ByteBuffer to stdout. + */ + private static void dumpByteBuffer(String header, ByteBuffer bBuf) { + if (!dumpBufs) { + return; + } + + int bufLen = bBuf.remaining(); + if (bufLen > 0) { + bBuf.mark(); + + // We expect the position of the buffer to be at the + // beginning of a TLS record. Get the type, version and length. + int type = Byte.toUnsignedInt(bBuf.get()); + int ver_major = Byte.toUnsignedInt(bBuf.get()); + int ver_minor = Byte.toUnsignedInt(bBuf.get()); + + log("===== " + header + " (" + tlsRecType(type) + " / " + + ver_major + "." + ver_minor + " / " + + bufLen + " bytes) ====="); + bBuf.reset(); + for (int i = 0; i < bufLen; i++) { + if (i != 0 && i % 16 == 0) { + System.out.print("\n"); + } + System.out.format("%02X ", bBuf.get(i)); + } + log("\n==============================================="); + bBuf.reset(); + } + } +} From d17aa5ed0097e3f108657761cfc29b959229e70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Arias=20de=20Reyna?= Date: Tue, 2 Apr 2024 08:40:56 +0000 Subject: [PATCH 125/298] 8319437: NMT should show library names in call stacks Backport-of: e33b6c10f8d3244ec2f4204cd4de404e0e0686eb --- .../share/utilities/nativeCallStack.cpp | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/utilities/nativeCallStack.cpp b/src/hotspot/share/utilities/nativeCallStack.cpp index 0fb0303fb90..3ddf296506c 100644 --- a/src/hotspot/share/utilities/nativeCallStack.cpp +++ b/src/hotspot/share/utilities/nativeCallStack.cpp @@ -82,18 +82,33 @@ void NativeCallStack::print_on(outputStream* out, int indent) const { char buf[1024]; int offset; if (is_empty()) { - for (int index = 0; index < indent; index ++) out->print(" "); + out->fill_to(indent); out->print("[BOOTSTRAP]"); } else { for (int frame = 0; frame < NMT_TrackingStackDepth; frame ++) { pc = get_frame(frame); if (pc == nullptr) break; - // Print indent - for (int index = 0; index < indent; index ++) out->print(" "); + out->fill_to(indent); + out->print("[" PTR_FORMAT "]", p2i(pc)); + // Print function and library; shorten library name to just its last component + // for brevity, and omit it completely for libjvm.so + bool function_printed = false; if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { - out->print("[" PTR_FORMAT "] %s+0x%x", p2i(pc), buf, offset); - } else { - out->print("[" PTR_FORMAT "]", p2i(pc)); + out->print("%s+0x%x", buf, offset); + function_printed = true; + } + if ((!function_printed || !os::address_is_in_vm(pc)) && + os::dll_address_to_library_name(pc, buf, sizeof(buf), &offset)) { + const char* libname = strrchr(buf, os::file_separator()[0]); + if (libname != nullptr) { + libname++; + } else { + libname = buf; + } + out->print(" in %s", libname); + if (!function_printed) { + out->print("+0x%x", offset); + } } // Note: we deliberately omit printing source information here. NativeCallStack::print_on() From f5dfd8be584a19bcb25813c0488eb3dc87367619 Mon Sep 17 00:00:00 2001 From: Elif Aslan Date: Tue, 2 Apr 2024 09:11:30 +0000 Subject: [PATCH 126/298] 8311823: JFR: Uninitialized EventEmitter::_thread_id field Backport-of: 9688ec2d0d9fd830d993454ea093b68b0f85ebe7 --- src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp index c7a3ee959fe..1d40c001c43 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.hpp @@ -44,7 +44,6 @@ class EventEmitter : public CHeapObj { const JfrTicks& _end_time; Thread* _thread; JfrThreadLocal* _jfr_thread_local; - traceid _thread_id; EventEmitter(const JfrTicks& start_time, const JfrTicks& end_time); ~EventEmitter(); From 0bbb8033ab35c59215f09cf5329592dc34b38520 Mon Sep 17 00:00:00 2001 From: Elif Aslan Date: Tue, 2 Apr 2024 09:11:43 +0000 Subject: [PATCH 127/298] 8318727: Enable parallelism in vmTestbase/vm/gc/concurrent tests Backport-of: 29d462a07239a57b83850b9a8662573291fdbdf7 --- .../lp30yp0rp0mr30st300/TEST.properties | 23 ------------------- .../lp30yp0rp0mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp0rp30mr0st300/TEST.properties | 23 ------------------- .../lp30yp0rp30mr30st0t1/TEST.properties | 23 ------------------- .../lp30yp0rp30mr70st0/TEST.properties | 23 ------------------- .../lp30yp0rp30mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp0rp70mr30st0/TEST.properties | 23 ------------------- .../lp30yp0rp70mr30st300t1/TEST.properties | 23 ------------------- .../lp30yp10rp0mr30st300/TEST.properties | 23 ------------------- .../lp30yp10rp0mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp10rp30mr0st300/TEST.properties | 23 ------------------- .../lp30yp10rp30mr30st0t1/TEST.properties | 23 ------------------- .../lp30yp10rp30mr70st0/TEST.properties | 23 ------------------- .../lp30yp10rp30mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp10rp70mr30st0/TEST.properties | 23 ------------------- .../lp30yp10rp70mr30st300t1/TEST.properties | 23 ------------------- .../lp30yp25rp0mr30st300/TEST.properties | 23 ------------------- .../lp30yp25rp0mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp25rp30mr0st300/TEST.properties | 23 ------------------- .../lp30yp25rp30mr30st0t1/TEST.properties | 23 ------------------- .../lp30yp25rp30mr70st0/TEST.properties | 23 ------------------- .../lp30yp25rp30mr70st300t1/TEST.properties | 23 ------------------- .../lp30yp25rp70mr30st0/TEST.properties | 23 ------------------- .../lp30yp25rp70mr30st300t1/TEST.properties | 23 ------------------- .../lp50yp0rp0mr30st300/TEST.properties | 23 ------------------- .../lp50yp0rp0mr70st300t1/TEST.properties | 23 ------------------- .../lp50yp0rp30mr0st300/TEST.properties | 23 ------------------- .../lp50yp0rp30mr30st0t1/TEST.properties | 23 ------------------- .../lp50yp0rp30mr70st0/TEST.properties | 23 ------------------- .../lp50yp0rp30mr70st300t1/TEST.properties | 23 ------------------- .../lp50yp0rp70mr30st0/TEST.properties | 23 ------------------- .../lp50yp0rp70mr30st300t1/TEST.properties | 23 ------------------- .../lp50yp10rp0mr30st300/TEST.properties | 23 ------------------- .../lp50yp10rp0mr70st300t1/TEST.properties | 23 ------------------- .../lp50yp10rp30mr0st300/TEST.properties | 23 ------------------- .../lp50yp10rp30mr30st0t1/TEST.properties | 23 ------------------- .../lp50yp10rp30mr70st0/TEST.properties | 23 ------------------- .../lp50yp10rp30mr70st300t1/TEST.properties | 23 ------------------- .../lp50yp10rp70mr30st0/TEST.properties | 23 ------------------- .../lp50yp10rp70mr30st300t1/TEST.properties | 23 ------------------- .../lp60yp0rp30mr0st300/TEST.properties | 23 ------------------- 41 files changed, 943 deletions(-) delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. From 4c7b1d93d9d2b283571bb2b9affb0fc3e42e0a75 Mon Sep 17 00:00:00 2001 From: Taizo Kurashige <103394724+kurashige23@users.noreply.github.com> Date: Tue, 2 Apr 2024 09:13:22 +0000 Subject: [PATCH 128/298] 8313710: jcmd: typo in the documentation of JFR.start and JFR.dump Backport-of: 16d917a85f9311611a14a63f1e53afae970efc73 --- .../jdk/jfr/internal/dcmd/DCmdDump.java | 84 +++++------ .../jdk/jfr/internal/dcmd/DCmdStart.java | 142 +++++++++--------- 2 files changed, 113 insertions(+), 113 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java index 596bed97d7a..57a04093c00 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java @@ -201,59 +201,59 @@ public String[] printHelp() { Options: - begin (Optional) Specify the time from which recording data will be included - in the dump file. The format is specified as local time. - (STRING, no default value) + begin (Optional) Specify the time from which recording data will be + included in the dump file. The format is specified as local time. + (STRING, no default value) - end (Optional) Specify the time to which recording data will be included - in the dump file. The format is specified as local time. - (STRING, no default value) + end (Optional) Specify the time to which recording data will be included + in the dump file. The format is specified as local time. + (STRING, no default value) - Note: For both begin and end, the time must be in a format that can - be read by any of these methods: + Note: For both begin and end, the time must be in a format that can + be read by any of these methods: - java.time.LocalTime::parse(String), - java.time.LocalDateTime::parse(String) - java.time.Instant::parse(String) + java.time.LocalTime::parse(String), + java.time.LocalDateTime::parse(String) + java.time.Instant::parse(String) - For example, "13:20:15", "2020-03-17T09:00:00" or - "2020-03-17T09:00:00Z". + For example, "13:20:15", "2020-03-17T09:00:00" or + "2020-03-17T09:00:00Z". - Note: begin and end times correspond to the timestamps found within - the recorded information in the flight recording data. + Note: begin and end times correspond to the timestamps found within + the recorded information in the flight recording data. - Another option is to use a time relative to the current time that is - specified by a negative integer followed by "s", "m" or "h". - For example, "-12h", "-15m" or "-30s" + Another option is to use a time relative to the current time that is + specified by a negative integer followed by "s", "m" or "h". + For example, "-12h", "-15m" or "-30s" - filename (Optional) Name of the file to which the flight recording data is - dumped. If no filename is given, a filename is generated from the PID - and the current date. The filename may also be a directory in which - case, the filename is generated from the PID and the current date in - the specified directory. (STRING, no default value) + filename (Optional) Name of the file to which the flight recording data is + dumped. If no filename is given, a filename is generated from the PID + and the current date. The filename may also be a directory in which + case, the filename is generated from the PID and the current date in + the specified directory. (STRING, no default value) - Note: If a filename is given, '%%p' in the filename will be - replaced by the PID, and '%%t' will be replaced by the time in - 'yyyy_MM_dd_HH_mm_ss' format. + Note: If a filename is given, '%%p' in the filename will be + replaced by the PID, and '%%t' will be replaced by the time in + 'yyyy_MM_dd_HH_mm_ss' format. - maxage (Optional) Length of time for dumping the flight recording data to a - file. (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for - hours, no default value) + maxage (Optional) Length of time for dumping the flight recording data to a + file. (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for + hours, no default value) - maxsize (Optional) Maximum size for the amount of data to dump from a flight - recording in bytes if one of the following suffixes is not used: - 'm' or 'M' for megabytes OR 'g' or 'G' for gigabytes. - (STRING, no default value) + maxsize (Optional) Maximum size for the amount of data to dump from a flight + recording in bytes if one of the following suffixes is not used: + 'm' or 'M' for megabytes OR 'g' or 'G' for gigabytes. + (STRING, no default value) - name (Optional) Name of the recording. If no name is given, data from all - recordings is dumped. (STRING, no default value) + name (Optional) Name of the recording. If no name is given, data from all + recordings is dumped. (STRING, no default value) - path-to-gc-root (Optional) Flag for saving the path to garbage collection (GC) roots - at the time the recording data is dumped. The path information is - useful for finding memory leaks but collecting it can cause the - application to pause for a short period of time. Turn on this flag - only when you have an application that you suspect has a memory - leak. (BOOLEAN, false) + path-to-gc-roots (Optional) Flag for saving the path to garbage collection (GC) roots + at the time the recording data is dumped. The path information is + useful for finding memory leaks but collecting it can cause the + application to pause for a short period of time. Turn on this flag + only when you have an application that you suspect has a memory + leak. (BOOLEAN, false) Options must be specified using the or = syntax. @@ -265,7 +265,7 @@ public String[] printHelp() { $ jcmd JFR.dump name=1 filename=%s $ jcmd JFR.dump maxage=1h $ jcmd JFR.dump maxage=1h maxsize=50M - $ jcmd JFR.dump fillename=leaks.jfr path-to-gc-root=true + $ jcmd JFR.dump filename=leaks.jfr path-to-gc-roots=true $ jcmd JFR.dump begin=13:15 $ jcmd JFR.dump begin=13:15 end=21:30:00 $ jcmd JFR.dump end=18:00 maxage=10m diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java index b8e66d8d3cb..781ceff4648 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java @@ -317,82 +317,82 @@ private boolean hasJDKEvents(Map settings) { @Override public String[] printHelp() { - // 0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890 + // 0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890 return """ Syntax : JFR.start [options] Options: - delay (Optional) Length of time to wait before starting to record - (INTEGER followed by 's' for seconds 'm' for minutes or h' for - hours, 0s) - - disk (Optional) Flag for also writing the data to disk while recording - (BOOLEAN, true) - - dumponexit (Optional) Flag for writing the recording to disk when the Java - Virtual Machine (JVM) shuts down. If set to 'true' and no value - is given for filename, the recording is written to a file in the - directory where the process was started. The file name is a - system-generated name that contains the process ID, the recording - ID and the current time stamp. (For example: - id-1-2021_09_14_09_00.jfr) (BOOLEAN, false) - - duration (Optional) Length of time to record. Note that 0s means forever - (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for - hours, 0s) - - filename (Optional) Name of the file to which the flight recording data is - written when the recording is stopped. If no filename is given, a - filename is generated from the PID and the current date and is - placed in the directory where the process was started. The - filename may also be a directory in which case, the filename is - generated from the PID and the current date in the specified - directory. (STRING, no default value) - - Note: If a filename is given, '%%p' in the filename will be - replaced by the PID, and '%%t' will be replaced by the time in - 'yyyy_MM_dd_HH_mm_ss' format. - - maxage (Optional) Maximum time to keep the recorded data on disk. This - parameter is valid only when the disk parameter is set to true. - Note 0s means forever. (INTEGER followed by 's' for seconds 'm' - for minutes or 'h' for hours, 0s) - - maxsize (Optional) Maximum size of the data to keep on disk in bytes if - one of the following suffixes is not used: 'm' or 'M' for - megabytes OR 'g' or 'G' for gigabytes. This parameter is valid - only when the disk parameter is set to 'true'. The value must not - be less than the value for the maxchunksize parameter set with - the JFR.configure command. (STRING, 0 (no max size)) - - name (Optional) Name of the recording. If no name is provided, a name - is generated. Make note of the generated name that is shown in - the response to the command so that you can use it with other - commands. (STRING, system-generated default name) - - path-to-gc-root (Optional) Flag for saving the path to garbage collection (GC) - roots at the end of a recording. The path information is useful - for finding memory leaks but collecting it is time consuming. - Turn on this flag only when you have an application that you - suspect has a memory leak. If the settings parameter is set to - 'profile', then the information collected includes the stack - trace from where the potential leaking object was allocated. - (BOOLEAN, false) - - settings (Optional) Name of the settings file that identifies which events - to record. To specify more than one file, use the settings - parameter repeatedly. Include the path if the file is not in - JAVA-HOME/lib/jfr. The following profiles are included with the - JDK in the JAVA-HOME/lib/jfr directory: 'default.jfc': collects a - predefined set of information with low overhead, so it has minimal - impact on performance and can be used with recordings that run - continuously; 'profile.jfc': Provides more data than the - 'default.jfc' profile, but with more overhead and impact on - performance. Use this configuration for short periods of time - when more information is needed. Use none to start a recording - without a predefined configuration file. (STRING, - JAVA-HOME/lib/jfr/default.jfc) + delay (Optional) Length of time to wait before starting to record + (INTEGER followed by 's' for seconds 'm' for minutes or h' for + hours, 0s) + + disk (Optional) Flag for also writing the data to disk while recording + (BOOLEAN, true) + + dumponexit (Optional) Flag for writing the recording to disk when the Java + Virtual Machine (JVM) shuts down. If set to 'true' and no value + is given for filename, the recording is written to a file in the + directory where the process was started. The file name is a + system-generated name that contains the process ID, the recording + ID and the current time stamp. (For example: + id-1-2021_09_14_09_00.jfr) (BOOLEAN, false) + + duration (Optional) Length of time to record. Note that 0s means forever + (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for + hours, 0s) + + filename (Optional) Name of the file to which the flight recording data is + written when the recording is stopped. If no filename is given, a + filename is generated from the PID and the current date and is + placed in the directory where the process was started. The + filename may also be a directory in which case, the filename is + generated from the PID and the current date in the specified + directory. (STRING, no default value) + + Note: If a filename is given, '%%p' in the filename will be + replaced by the PID, and '%%t' will be replaced by the time in + 'yyyy_MM_dd_HH_mm_ss' format. + + maxage (Optional) Maximum time to keep the recorded data on disk. This + parameter is valid only when the disk parameter is set to true. + Note 0s means forever. (INTEGER followed by 's' for seconds 'm' + for minutes or 'h' for hours, 0s) + + maxsize (Optional) Maximum size of the data to keep on disk in bytes if + one of the following suffixes is not used: 'm' or 'M' for + megabytes OR 'g' or 'G' for gigabytes. This parameter is valid + only when the disk parameter is set to 'true'. The value must not + be less than the value for the maxchunksize parameter set with + the JFR.configure command. (STRING, 0 (no max size)) + + name (Optional) Name of the recording. If no name is provided, a name + is generated. Make note of the generated name that is shown in + the response to the command so that you can use it with other + commands. (STRING, system-generated default name) + + path-to-gc-roots (Optional) Flag for saving the path to garbage collection (GC) + roots at the end of a recording. The path information is useful + for finding memory leaks but collecting it is time consuming. + Turn on this flag only when you have an application that you + suspect has a memory leak. If the settings parameter is set to + 'profile', then the information collected includes the stack + trace from where the potential leaking object was allocated. + (BOOLEAN, false) + + settings (Optional) Name of the settings file that identifies which events + to record. To specify more than one file, use the settings + parameter repeatedly. Include the path if the file is not in + JAVA-HOME/lib/jfr. The following profiles are included with the + JDK in the JAVA-HOME/lib/jfr directory: 'default.jfc': collects a + predefined set of information with low overhead, so it has minimal + impact on performance and can be used with recordings that run + continuously; 'profile.jfc': Provides more data than the + 'default.jfc' profile, but with more overhead and impact on + performance. Use this configuration for short periods of time + when more information is needed. Use none to start a recording + without a predefined configuration file. (STRING, + JAVA-HOME/lib/jfr/default.jfc) Event settings and .jfc options can also be specified using the following syntax: From 342ae64964a82fd12abdf736dbefa83371c7f762 Mon Sep 17 00:00:00 2001 From: Long Yang Date: Wed, 3 Apr 2024 01:27:52 +0000 Subject: [PATCH 129/298] 8319876: Reduce memory consumption of VM_ThreadDump::doit Reviewed-by: phh Backport-of: 8ec6b8de3bb3d7aeebdcb45d761b18cce3bab75e --- src/hotspot/share/runtime/vmOperations.cpp | 2 -- src/hotspot/share/services/threadService.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/vmOperations.cpp b/src/hotspot/share/runtime/vmOperations.cpp index 04ed1d5f66d..b5651940346 100644 --- a/src/hotspot/share/runtime/vmOperations.cpp +++ b/src/hotspot/share/runtime/vmOperations.cpp @@ -230,7 +230,6 @@ VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, _result = result; _num_threads = 0; // 0 indicates all threads _threads = nullptr; - _result = result; _max_depth = max_depth; _with_locked_monitors = with_locked_monitors; _with_locked_synchronizers = with_locked_synchronizers; @@ -245,7 +244,6 @@ VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, _result = result; _num_threads = num_threads; _threads = threads; - _result = result; _max_depth = max_depth; _with_locked_monitors = with_locked_monitors; _with_locked_synchronizers = with_locked_synchronizers; diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp index e95c832894f..6865982aa8e 100644 --- a/src/hotspot/share/services/threadService.cpp +++ b/src/hotspot/share/services/threadService.cpp @@ -696,7 +696,7 @@ void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth, ObjectMonitorsView* RegisterMap::UpdateMap::include, RegisterMap::ProcessFrames::include, RegisterMap::WalkContinuation::skip); - + ResourceMark rm; // If full, we want to print both vthread and carrier frames vframe* start_vf = !full && _thread->is_vthread_mounted() ? _thread->carrier_last_java_vframe(®_map) From 9e6fb8287ad670ffd5583d3de04e320ca827a58d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 3 Apr 2024 06:50:39 +0000 Subject: [PATCH 130/298] 8328592: hprof tests fail with -XX:-CompactStrings Backport-of: bb3e84bd1fd8217fcb319de8a0716e44359e3423 --- .../jdk/test/lib/hprof/model/JavaObject.java | 9 +++-- .../test/lib/hprof/model/JavaValueArray.java | 35 +++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/test/lib/jdk/test/lib/hprof/model/JavaObject.java b/test/lib/jdk/test/lib/hprof/model/JavaObject.java index 54b156c1f01..e7f93e01a36 100644 --- a/test/lib/jdk/test/lib/hprof/model/JavaObject.java +++ b/test/lib/jdk/test/lib/hprof/model/JavaObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -190,9 +190,14 @@ public String describeReferenceTo(JavaThing target, Snapshot ss) { public String toString() { if (getClazz().isString()) { + JavaThing coder = getField("coder"); + boolean compact = false; + if (coder instanceof JavaByte) { + compact = ((JavaByte)coder).value == 0; + } JavaThing value = getField("value"); if (value instanceof JavaValueArray) { - return ((JavaValueArray)value).valueAsString(); + return ((JavaValueArray)value).valueAsString(compact); } else { return "null"; } diff --git a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java index e6b4c7960c6..0779a0aaaa4 100644 --- a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java +++ b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -33,6 +33,7 @@ package jdk.test.lib.hprof.model; import java.io.IOException; +import java.nio.ByteOrder; import java.util.Objects; /** @@ -350,15 +351,37 @@ public String valueString(boolean bigLimit) { return result.toString(); } + private static final int STRING_HI_BYTE_SHIFT; + private static final int STRING_LO_BYTE_SHIFT; + static { + if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { + STRING_HI_BYTE_SHIFT = 8; + STRING_LO_BYTE_SHIFT = 0; + } else { + STRING_HI_BYTE_SHIFT = 0; + STRING_LO_BYTE_SHIFT = 8; + } + } + // Tries to represent the value as string (used by JavaObject.toString). - public String valueAsString() { + public String valueAsString(boolean compact) { if (getElementType() == 'B') { JavaThing[] things = getValue(); - byte[] bytes = new byte[things.length]; - for (int i = 0; i < things.length; i++) { - bytes[i] = ((JavaByte)things[i]).value; + if (compact) { + byte[] bytes = new byte[things.length]; + for (int i = 0; i < things.length; i++) { + bytes[i] = ((JavaByte)things[i]).value; + } + return new String(bytes); + } else { + char[] chars = new char[things.length / 2]; + for (int i = 0; i < things.length; i += 2) { + int b1 = ((JavaByte)things[i]).value << STRING_HI_BYTE_SHIFT; + int b2 = ((JavaByte)things[i + 1]).value << STRING_LO_BYTE_SHIFT; + chars[i / 2] = (char)(b1 | b2); + } + return new String(chars); } - return new String(bytes); } // fallback return valueString(); From 80cf08aa0b1b9f5d5bd19e1b6a88f6725b233f30 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 08:58:07 +0000 Subject: [PATCH 131/298] 8294985: SSLEngine throws IAE during parsing of X500Principal Backport-of: 80edd5c298f21c5e5be3a0c2bb63129e76e0334f --- .../ssl/CertificateAuthoritiesExtension.java | 29 ++- .../sun/security/ssl/CertificateRequest.java | 57 ++++- .../ssl/SSLEngineImpl/TestBadDNForPeerCA.java | 179 +++++++++++++ .../SSLEngineImpl/TestBadDNForPeerCA12.java | 239 ++++++++++++++++++ 4 files changed, 486 insertions(+), 18 deletions(-) create mode 100644 test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java create mode 100644 test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java b/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java index f759aac5479..43bac16f0ea 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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,8 +122,11 @@ private static List getEncodedAuthorities( return authorities; } + // This method will throw IllegalArgumentException if the + // X500Principal cannot be parsed. X500Principal[] getAuthorities() { X500Principal[] principals = new X500Principal[authorities.size()]; + int i = 0; for (byte[] encoded : authorities) { principals[i++] = new X500Principal(encoded); @@ -138,8 +141,12 @@ public String toString() { "\"certificate authorities\": '['\n{0}']'", Locale.ENGLISH); StringBuilder builder = new StringBuilder(512); for (byte[] encoded : authorities) { - X500Principal principal = new X500Principal(encoded); - builder.append(principal.toString()); + try { + X500Principal principal = new X500Principal(encoded); + builder.append(principal.toString()); + } catch (IllegalArgumentException iae) { + builder.append("unparseable distinguished name: " + iae); + } builder.append("\n"); } Object[] messageFields = { @@ -277,7 +284,13 @@ public void consume(ConnectionContext context, new CertificateAuthoritiesSpec(shc, buffer); // Update the context. - shc.peerSupportedAuthorities = spec.getAuthorities(); + try { + shc.peerSupportedAuthorities = spec.getAuthorities(); + } catch (IllegalArgumentException iae) { + shc.conContext.fatal(Alert.DECODE_ERROR, "The distinguished " + + "names of the peer's certificate authorities could " + + "not be parsed", iae); + } shc.handshakeExtensions.put( SSLExtension.CH_CERTIFICATE_AUTHORITIES, spec); @@ -398,7 +411,13 @@ public void consume(ConnectionContext context, new CertificateAuthoritiesSpec(chc, buffer); // Update the context. - chc.peerSupportedAuthorities = spec.getAuthorities(); + try { + chc.peerSupportedAuthorities = spec.getAuthorities(); + } catch (IllegalArgumentException iae) { + chc.conContext.fatal(Alert.DECODE_ERROR, "The distinguished " + + "names of the peer's certificate authorities could " + + "not be parsed", iae); + } chc.handshakeExtensions.put( SSLExtension.CR_CERTIFICATE_AUTHORITIES, spec); diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java index 4c3822593ef..f7ca92633ab 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -198,9 +198,12 @@ String[] getKeyTypes() { return ClientCertificateType.getKeyTypes(types); } + // This method will throw IllegalArgumentException if the + // X500Principal cannot be parsed. X500Principal[] getAuthorities() { X500Principal[] principals = new X500Principal[authorities.size()]; int i = 0; + for (byte[] encoded : authorities) { principals[i++] = new X500Principal(encoded); } @@ -254,8 +257,12 @@ public String toString() { List authorityNames = new ArrayList<>(authorities.size()); for (byte[] encoded : authorities) { - X500Principal principal = new X500Principal(encoded); - authorityNames.add(principal.toString()); + try { + X500Principal principal = new X500Principal(encoded); + authorityNames.add(principal.toString()); + } catch (IllegalArgumentException iae) { + authorityNames.add("unparseable distinguished name: " + iae); + } } Object[] messageFields = { typeNames, @@ -370,12 +377,23 @@ public void consume(ConnectionContext context, X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); String clientAlias = null; - if (chc.conContext.transport instanceof SSLSocketImpl) { - clientAlias = km.chooseClientAlias(crm.getKeyTypes(), - crm.getAuthorities(), (SSLSocket)chc.conContext.transport); - } else if (chc.conContext.transport instanceof SSLEngineImpl) { - clientAlias = km.chooseEngineClientAlias(crm.getKeyTypes(), - crm.getAuthorities(), (SSLEngine)chc.conContext.transport); + + try { + if (chc.conContext.transport instanceof SSLSocketImpl) { + clientAlias = km.chooseClientAlias(crm.getKeyTypes(), + crm.getAuthorities(), + (SSLSocket) chc.conContext.transport); + } else if (chc.conContext.transport instanceof SSLEngineImpl) { + clientAlias = + km.chooseEngineClientAlias(crm.getKeyTypes(), + crm.getAuthorities(), + (SSLEngine) chc.conContext.transport); + } + } catch (IllegalArgumentException iae) { + chc.conContext.fatal(Alert.DECODE_ERROR, + "The distinguished names of the peer's " + + "certificate authorities could not be parsed", + iae); } @@ -512,9 +530,12 @@ String[] getKeyTypes() { return ClientCertificateType.getKeyTypes(types); } + // This method will throw IllegalArgumentException if the + // X500Principal cannot be parsed. X500Principal[] getAuthorities() { X500Principal[] principals = new X500Principal[authorities.size()]; int i = 0; + for (byte[] encoded : authorities) { principals[i++] = new X500Principal(encoded); } @@ -579,8 +600,13 @@ public String toString() { List authorityNames = new ArrayList<>(authorities.size()); for (byte[] encoded : authorities) { - X500Principal principal = new X500Principal(encoded); - authorityNames.add(principal.toString()); + try { + X500Principal principal = new X500Principal(encoded); + authorityNames.add(principal.toString()); + } catch (IllegalArgumentException iae) { + authorityNames.add("unparseable distinguished name: " + + iae); + } } Object[] messageFields = { typeNames, @@ -717,8 +743,13 @@ public void consume(ConnectionContext context, chc.peerRequestedSignatureSchemes = sss; chc.peerRequestedCertSignSchemes = sss; // use the same schemes chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss); - chc.peerSupportedAuthorities = crm.getAuthorities(); - + try { + chc.peerSupportedAuthorities = crm.getAuthorities(); + } catch (IllegalArgumentException iae) { + chc.conContext.fatal(Alert.DECODE_ERROR, "The " + + "distinguished names of the peer's certificate " + + "authorities could not be parsed", iae); + } // For TLS 1.2, we no longer use the certificate_types field // from the CertificateRequest message to directly determine // the SSLPossession. Instead, the choosePossession method diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java new file mode 100644 index 00000000000..06e2aa94b35 --- /dev/null +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8294985 + * @library /test/lib + * @summary SSLEngine throws IAE during parsing of X500Principal + * @run main/othervm TestBadDNForPeerCA + * @run main/othervm -Djavax.net.debug=all TestBadDNForPeerCA + */ + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.TrustManagerFactory; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.security.KeyStore; +import java.util.Base64; + + +public class TestBadDNForPeerCA { + + private static final String proto = "TLSv1.3"; + + private final SSLContext sslc; + + private SSLEngine serverEngine; // server Engine + private ByteBuffer serverIn; // read side of serverEngine + + private ByteBuffer cTOs; // "reliable" transport client->server + + private static final String keyStoreFile = + System.getProperty("test.src", "./") + + "/../../../../javax/net/ssl/etc/keystore"; + + // the following ClientHello contains a certificate with an + // invalid/unparseable distinguished name + private static final byte[] payload = Base64.getDecoder().decode( + "FgMDAcsBAAHHAwPbDfeUCIStPzVIfXuGgCu56dSJOJ6xeus1W44frG5tciDEcBfYt" + + "/PN/6MFCGojEVcmPw21mVyjYInMo0UozIn4NwBiEwITARMDwCzAK8ypwDDMqMAvA" + + "J/MqgCjAJ4AosAkwCjAI8AnAGsAagBnAEDALsAywC3AMcAmCgAFKsApJcDAFMAJw" + + "BMAOQA4ADMAMsAFwA/ABMAOAJ0AnAA9ADwANgAvAP8BAAEcAAUABQEAAAAAAAoAF" + + "gAUAB0AFwAYABkAHgEAAQEBAgEDAQQACwACAQAAEQAJAAcCAAQAAAAAABcAAAAjA" + + "AAADQAsACoEAwUDBgMIBwgICAQIBQgGCAkICggLBAEFAQYBBAIDAwMBAwICAwIBA" + + "gIAKwAFBAMEAwMALQACAQEAMgAsACoEAwUDBgMIBwgICAQIBQgGCAkICggLBAEFA" + + "QYBBAIDAwMBAwICAwIBAgIALwBrAGkAHQAAAAARACAAZMUAADkwsiaOwcsWAwAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAtAAAAAAAAAAEAADAAAAA="); + + /* + * The following is to set up the keystores. + */ + private static final String passwd = "passphrase"; + + /* + * Main entry point for this demo. + */ + public static void main(String[] args) throws Exception { + + TestBadDNForPeerCA test = new TestBadDNForPeerCA(); + + try { + test.runTest(); + throw new Exception( + "TEST FAILED: Didn't generate any exception"); + } catch (SSLHandshakeException she) { + System.out.println("TEST PASSED: Caught expected exception"); + } + } + + /* + * Create an initialized SSLContext to use for this demo. + */ + + public TestBadDNForPeerCA() throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = passwd.toCharArray(); + + ks.load(new FileInputStream(keyStoreFile), passphrase); + ts.load(new FileInputStream(keyStoreFile), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance(proto); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + + private void runTest() throws Exception { + + createSSLEngines(); + createBuffers(); + + cTOs = ByteBuffer.wrap(payload); + + System.out.println("injecting client hello"); + + for (int i = 0; i < 10; i++) { //retry if survived + SSLEngineResult serverResult = serverEngine.unwrap(cTOs, serverIn); + System.out.println("server unwrap: " + serverResult); + runDelegatedTasks(serverResult, serverEngine); + } + } + + private void createSSLEngines() throws Exception { + + serverEngine = sslc.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(true); + + } + + + private void createBuffers() { + + serverIn = ByteBuffer.allocateDirect(65536); + + cTOs = ByteBuffer.allocateDirect(65536); + + } + + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + System.out.println("\trunning delegated task..."); + runnable.run(); + } + + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception("handshake shouldn't need additional " + + "tasks"); + } + System.out.println("\tnew HandshakeStatus: " + hsStatus); + } + } + + +} diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java new file mode 100644 index 00000000000..701620a7502 --- /dev/null +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8294985 + * @library /test/lib + * @summary SSLEngine throws IAE during parsing of X500Principal + * @run main/othervm TestBadDNForPeerCA12 + * @run main/othervm -Djavax.net.debug=all TestBadDNForPeerCA12 + */ + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.TrustManagerFactory; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.security.KeyStore; +import java.util.Base64; + +public class TestBadDNForPeerCA12 { + + // Test was originally written for TLSv1.2 + private static final String proto = "TLSv1.2"; + + private final SSLContext sslc; + + protected SSLEngine clientEngine; // client Engine + protected SSLEngine serverEngine; // server Engine + protected ByteBuffer clientOut; // write side of clientEngine + protected ByteBuffer serverOut; // write side of serverEngine + protected ByteBuffer clientIn; // read side of clientEngine + protected ByteBuffer serverIn; // read side of serverEngine + private ByteBuffer cTOs; // "reliable" transport client->server + protected ByteBuffer sTOc; // "reliable" transport server->client + + private static final String keyStoreFile = + System.getProperty("test.src", "./") + + "/../../../../javax/net/ssl/etc/keystore"; + + // this contains a server response with invalid DNs + private static final byte[] serverPayload = Base64.getDecoder().decode( + "FgMDBhICAABVAwPORrwPxSL0DOnCC+cCvQcXxeU1ugjN5XyT0r9qOrlT0iD4I0BgFq" + + "2Hbt7a9cGreNkhniEEhgQIuxa2Ur21VJr9/AA1AAANABcAAAAjAAD/AQABAAsAA1UAA1" + + "IAA08wggNLMIICMwIEVzmbhzANBgkqhkiG9w0BAQsFADBqMQswCQYDVQQGEwJVUzELMA" + + "kGA1UECAwCQ0ExEjAQBgNVBAcMCUN1cGVydGlubzEOMAwGA1UECgwFRHVtbXkxDjAMBg" + + "NVBAsMBUR1bW15MRowGAYDVQQDDBFkdW1teS5leGFtcGxlLmNvbTAeFw0xNjA1MTYxMD" + + "A2MzhaFw0yNjA1MTYxMDA2MzhaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMB" + + "AGA1UEBwwJQ3VwZXJ0aW5vMQ4wDAYDVQQKDAVEdW1teTEOMAwGA1UECwwFRHVtbXkxGj" + + "AYBgNVBAMMEWR1bW15LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMI" + + "IBCgKCAQEAyRtAPlvIbvGfI5ZXN4jBu0dU96b8smVcAdxYnDPylnvmsYGdmYC2C6ddT7" + + "7I9Nlk6BhNmkz6pCGsXLZnUOL+9XOGVWlw5kHDVEGUjeza5BhpZW0G0q00QthZcRuF/F" + + "UkUGzmUuaxgm59VqwxP7dfMERG4gRRXjclMpLm23CShWBhFfooOsiPSFgDtmY4H/LkTU" + + "EbaYuxKRfRKhMKm6GBjCVY7iS9iga728dJ+6BTNAGpKITXI35B+Xf7vpTbc+Zub9vL2f" + + "czcChQvGTZedCaAFi3NWJXR/UTeuv/vte8jJ1YscHSSi2k0P5k3gi9PCmve/sjLrBuh+" + + "D466e/B/swowIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBZFaKJtN/1RkCVev7ZmYEwww" + + "42kE5RpJt7Es2zoxqEGaNx0TA5D6XnEB1XjFUQOgOG7SbUl4NfLpJejuZiQzaX27+7Pu" + + "1FK24SIz61sINpyVtb8flA52mIjH26HzpwSAGmTjFQ7m9Josj/25IqAaRM0AWuPLcwTf" + + "B9zRx3me1LxxrzGhtyZDn1Jhlv0aLS79g33Kuj1HAYMvw7UGan372ufmGiv+g5UYeVvP" + + "Yw3jeahJkSIh96Bb05aJpaogaoE5e+gQanR7E36WGGaicjfN1gIHSOyzZBibcTUhaplS" + + "Q06DfK6UjGmHcVi8X5wD+9NWWiGrlUHcOwKueQOaptTaaXDQACWANAAQIAKgQDBQMGAw" + + "gHCAgIBAgFCAYICQgKCAsEAQUBBgEEAgMDAwEDAgIDAgECAgImAGwwajELMAkRA1UEBh" + + "MCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlDdXBlcnRpbm8xDjAMBgNVBAoTBUR1bW" + + "15MQ4wDAYDVQQLEwVEdW1teTEaMBgGA1UEAxMRZHVtbXkuZXhhbXBsZS5jb20AbDBqMQ" + + "swCREDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUN1cGVydGlubzEOMAwGA1" + + "UECgwFRHVtbXkxDjAMBgNVBAsMBUR1bW15MRowGAYDVQQDDBFkdW1teS5leGFtcGxlLm" + + "NvbQBsMGoxCzAJEQNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJQ3VwZXJ0aW" + + "5vMQ4wDAYDVQQKDAVEdW1teTEOMAwGA1UECwwFRHVtbXkxGjAYBgNVBAMMEWR1bW15Lm" + + "V4YW1wbGUuY29tAGwwajELMAkRA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEw" + + "lDdXBlcnRpbm8xDjAMBgNVBAoTBUR1bW15MQ4wDAYDVQQLEwVEdW1teTEaMBgGA1UEAx" + + "MRZHVtbXkuZXhhbXBsZS5jb20AbDBqMQswCREDVQQGEwJVUzELMAkGA1UECBMCQ0ExEj" + + "AQBgNVBAcTCUN1cGVydGlubzEOMAwGA1UEChMFRHVtbXkxDjAMBgNVBAsTBUR1bW15MR" + + "owGAYDVQQDExFkdW1teS5leGFtcGxlLmNvbQ4AAAA=" + ); + + /* + * The following is to set up the keystores. + */ + private static final String passwd = "passphrase"; + + /* + * Main entry point for this demo. + */ + public static void main(String[] args) throws Exception { + + TestBadDNForPeerCA12 test = new TestBadDNForPeerCA12(); + + try { + test.runTest(); + throw new Exception( + "TEST FAILED: Didn't generate any exception"); + } catch (SSLHandshakeException she) { + System.out.println("TEST PASSED: Caught expected exception"); + } + } + + /* + * Create an initialized SSLContext to use for this demo. + */ + + public TestBadDNForPeerCA12() throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = passwd.toCharArray(); + + ks.load(new FileInputStream(keyStoreFile), passphrase); + ts.load(new FileInputStream(keyStoreFile), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance(proto); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + + private void runTest() throws Exception { + + createSSLEngines(); + createBuffers(); + + /* + * the following was used to generate the serverPayload value + */ + // ignore output + /*SSLEngineResult clientResult = clientEngine.wrap(clientOut, cTOs); + runDelegatedTasks(clientResult, clientEngine); + cTOs.flip(); + + // ignore output + SSLEngineResult serverResult = serverEngine.unwrap(cTOs, serverIn); + runDelegatedTasks(serverResult, serverEngine); + // server hello, cert material, etc + SSLEngineResult serverWrapResult = serverEngine.wrap(serverOut, sTOc); + runDelegatedTasks(serverWrapResult, serverEngine); + sTOc.flip(); + ByteBuffer sTOcBuff = sTOc.asReadOnlyBuffer(); + byte[] serverContents = new byte[sTOcBuff.remaining()]; + sTOcBuff.get(serverContents); + System.out.println("sw: " + Base64.getEncoder().encodeToString + (serverContents));*/ + + System.out.println("sending client hello"); + SSLEngineResult clientResult = clientEngine.wrap(clientOut, cTOs); + runDelegatedTasks(clientResult, clientEngine); + + cTOs.flip(); + + sTOc = ByteBuffer.wrap(serverPayload); + + SSLEngineResult clientHelloResult = clientEngine.unwrap(sTOc, clientIn); + System.out.println("client unwrap: " + clientHelloResult); + runDelegatedTasks(clientHelloResult, clientEngine); + + SSLEngineResult clientExGen = clientEngine.wrap(clientIn, cTOs); + runDelegatedTasks(clientExGen, clientEngine); + + } + + private void createSSLEngines() { + clientEngine = sslc.createSSLEngine(); + clientEngine.setEnabledProtocols(new String[] {proto}); + clientEngine.setUseClientMode(true); + clientEngine.setEnabledCipherSuites(new String[] + {"TLS_RSA_WITH_AES_256_CBC_SHA"}); + + serverEngine = sslc.createSSLEngine(); + serverEngine.setEnabledProtocols(new String[] {proto}); + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(true); + serverEngine.setEnabledCipherSuites(new String[] + {"TLS_RSA_WITH_AES_256_CBC_SHA"}); + } + + private void createBuffers() { + cTOs = ByteBuffer.allocateDirect(65536); + + clientIn = ByteBuffer.allocateDirect(65536); + + clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes()); + + sTOc = ByteBuffer.allocateDirect(65536); + + serverOut = ByteBuffer.wrap("Hi Client, I'm Server".getBytes()); + + serverIn = ByteBuffer.allocateDirect(65536); + } + + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + System.out.println("\trunning delegated task..."); + runnable.run(); + } + + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception("handshake shouldn't need additional " + + "tasks"); + } + System.out.println("\tnew HandshakeStatus: " + hsStatus); + } + } +} From fa5cc58822262976daff6bf489ce000dddc3654f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:00:18 +0000 Subject: [PATCH 132/298] 8315605: G1: Add number of nmethods in code roots scanning statistics Backport-of: 7ef059a75cdd2e96421a165ea1dd8391381bd7b5 --- src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp | 4 +++ src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp | 4 +++ src/hotspot/share/gc/g1/g1RemSet.cpp | 32 +++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp index 5fc8b54df0d..2639f9ea166 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp @@ -123,6 +123,10 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : _gc_par_phases[MergeLB]->create_thread_work_items("Dirty Cards:", MergeLBDirtyCards); _gc_par_phases[MergeLB]->create_thread_work_items("Skipped Cards:", MergeLBSkippedCards); + _gc_par_phases[CodeRoots]->create_thread_work_items("Scanned Nmethods", CodeRootsScannedNMethods); + + _gc_par_phases[OptCodeRoots]->create_thread_work_items("Scanned Nmethods", CodeRootsScannedNMethods); + _gc_par_phases[MergePSS]->create_thread_work_items("Copied Bytes", MergePSSCopiedBytes); _gc_par_phases[MergePSS]->create_thread_work_items("LAB Waste", MergePSSLABWasteBytes); _gc_par_phases[MergePSS]->create_thread_work_items("LAB Undo Waste", MergePSSLABUndoWasteBytes); diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp index d06341e3ece..5b2b5714dff 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp @@ -134,6 +134,10 @@ class G1GCPhaseTimes : public CHeapObj { MergeLBSkippedCards }; + enum GCCodeRootsWorkItems { + CodeRootsScannedNMethods + }; + enum GCMergePSSWorkItems { MergePSSCopiedBytes, MergePSSLABSize, diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index b29125037b7..49d1fac634a 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -757,6 +757,25 @@ void G1RemSet::scan_heap_roots(G1ParScanThreadState* pss, p->record_or_add_thread_work_item(scan_phase, worker_id, cl.heap_roots_found(), G1GCPhaseTimes::ScanHRFoundRoots); } +// Wrapper around a CodeBlobClosure to count the number of code blobs scanned. +class G1ScanAndCountCodeBlobClosure : public CodeBlobClosure { + CodeBlobClosure* _cl; + size_t _count; + +public: + G1ScanAndCountCodeBlobClosure(CodeBlobClosure* cl) : _cl(cl), _count(0) { + } + + void do_code_blob(CodeBlob* cb) override { + _cl->do_code_blob(cb); + _count++; + } + + size_t count() const { + return _count; + } +}; + // Heap region closure to be applied to all regions in the current collection set // increment to fix up non-card related roots. class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { @@ -768,6 +787,8 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { uint _worker_id; + size_t _code_roots_scanned; + size_t _opt_roots_scanned; size_t _opt_refs_scanned; size_t _opt_refs_memory_used; @@ -798,6 +819,7 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { _scan_phase(scan_phase), _code_roots_phase(code_roots_phase), _worker_id(worker_id), + _code_roots_scanned(0), _opt_roots_scanned(0), _opt_refs_scanned(0), _opt_refs_memory_used(0), @@ -822,8 +844,12 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { if (_scan_state->claim_collection_set_region(region_idx)) { EventGCPhaseParallel event; G1EvacPhaseWithTrimTimeTracker timer(_pss, _code_root_scan_time, _code_trim_partially_time); + G1ScanAndCountCodeBlobClosure cl(_pss->closures()->weak_codeblobs()); + // Scan the code root list attached to the current region - r->code_roots_do(_pss->closures()->weak_codeblobs()); + r->code_roots_do(&cl); + + _code_roots_scanned = cl.count(); event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_code_roots_phase)); } @@ -834,6 +860,8 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { Tickspan code_root_scan_time() const { return _code_root_scan_time; } Tickspan code_root_trim_partially_time() const { return _code_trim_partially_time; } + size_t code_roots_scanned() const { return _code_roots_scanned; } + Tickspan rem_set_opt_root_scan_time() const { return _rem_set_opt_root_scan_time; } Tickspan rem_set_opt_trim_partially_time() const { return _rem_set_opt_trim_partially_time; } @@ -856,6 +884,8 @@ void G1RemSet::scan_collection_set_regions(G1ParScanThreadState* pss, p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_trim_partially_time().seconds()); p->record_or_add_time_secs(coderoots_phase, worker_id, cl.code_root_scan_time().seconds()); + p->record_or_add_thread_work_item(coderoots_phase, worker_id, cl.code_roots_scanned(), G1GCPhaseTimes::CodeRootsScannedNMethods); + p->add_time_secs(objcopy_phase, worker_id, cl.code_root_trim_partially_time().seconds()); // At this time we record some metrics only for the evacuations after the initial one. From 8d3151f098c319517d65ecb0fd9c38a51593c38b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:08:52 +0000 Subject: [PATCH 133/298] 8316002: Remove unnecessary seen_dead_loader in ClassLoaderDataGraph::do_unloading Backport-of: 50158f393e0b077b22886f44624ff23e65dedeb8 --- src/hotspot/share/classfile/classLoaderDataGraph.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index 5645ab4aafe..a5c43cbb406 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -494,7 +494,6 @@ bool ClassLoaderDataGraph::do_unloading() { assert_locked_or_safepoint(ClassLoaderDataGraph_lock); ClassLoaderData* prev = nullptr; - bool seen_dead_loader = false; uint loaders_processed = 0; uint loaders_removed = 0; @@ -505,7 +504,6 @@ bool ClassLoaderDataGraph::do_unloading() { } else { // Found dead CLD. loaders_removed++; - seen_dead_loader = true; data->unload(); // Move dead CLD to unloading list. @@ -523,7 +521,7 @@ bool ClassLoaderDataGraph::do_unloading() { log_debug(class, loader, data)("do_unloading: loaders processed %u, loaders removed %u", loaders_processed, loaders_removed); - return seen_dead_loader; + return loaders_removed != 0; } // There's at least one dead class loader. Purge refererences of healthy module From 618a7baa1f0361b43d003b090d635166fa67e187 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:11:38 +0000 Subject: [PATCH 134/298] 8315998: Remove dead ClassLoaderDataGraphKlassIteratorStatic Backport-of: 347beb21aa856cebdcf4407eac59f1cad46376c1 --- .../share/classfile/classLoaderData.cpp | 6 -- .../share/classfile/classLoaderDataGraph.cpp | 79 ------------------- .../share/classfile/classLoaderDataGraph.hpp | 5 -- .../share/interpreter/invocationCounter.cpp | 4 - .../share/interpreter/invocationCounter.hpp | 1 - 5 files changed, 95 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 282a025c31d..ca6b58d6530 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -558,9 +558,6 @@ void ClassLoaderData::initialize_holder(Handle loader_or_mirror) { void ClassLoaderData::remove_class(Klass* scratch_class) { assert_locked_or_safepoint(ClassLoaderDataGraph_lock); - // Adjust global class iterator. - ClassLoaderDataGraph::adjust_saved_class(scratch_class); - Klass* prev = nullptr; for (Klass* k = _klasses; k != nullptr; k = k->next_link()) { if (k == scratch_class) { @@ -620,9 +617,6 @@ void ClassLoaderData::unload() { if (_jmethod_ids != nullptr) { Method::clear_jmethod_ids(this); } - - // Clean up global class iterator for compiler - ClassLoaderDataGraph::adjust_saved_class(this); } ModuleEntryTable* ClassLoaderData::modules() { diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index a5c43cbb406..ded67718929 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -80,85 +80,6 @@ void ClassLoaderDataGraph::verify_claimed_marks_cleared(int claim) { #endif } -// Class iterator used by the compiler. It gets some number of classes at -// a safepoint to decay invocation counters on the methods. -class ClassLoaderDataGraphKlassIteratorStatic { - ClassLoaderData* _current_loader_data; - Klass* _current_class_entry; - public: - - ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(nullptr), _current_class_entry(nullptr) {} - - InstanceKlass* try_get_next_class() { - assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); - size_t max_classes = ClassLoaderDataGraph::num_instance_classes(); - assert(max_classes > 0, "should not be called with no instance classes"); - for (size_t i = 0; i < max_classes; ) { - - if (_current_class_entry != nullptr) { - Klass* k = _current_class_entry; - _current_class_entry = _current_class_entry->next_link(); - - if (k->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(k); - i++; // count all instance classes found - // Not yet loaded classes are counted in max_classes - // but only return loaded classes. - if (ik->is_loaded()) { - return ik; - } - } - } else { - // Go to next CLD - if (_current_loader_data != nullptr) { - _current_loader_data = _current_loader_data->next(); - } - // Start at the beginning - if (_current_loader_data == nullptr) { - _current_loader_data = ClassLoaderDataGraph::_head; - } - - _current_class_entry = _current_loader_data->klasses(); - } - } - // Should never be reached unless all instance classes have failed or are not fully loaded. - // Caller handles null. - return nullptr; - } - - // If the current class for the static iterator is a class being unloaded or - // deallocated, adjust the current class. - void adjust_saved_class(ClassLoaderData* cld) { - if (_current_loader_data == cld) { - _current_loader_data = cld->next(); - if (_current_loader_data != nullptr) { - _current_class_entry = _current_loader_data->klasses(); - } // else try_get_next_class will start at the head - } - } - - void adjust_saved_class(Klass* klass) { - if (_current_class_entry == klass) { - _current_class_entry = klass->next_link(); - } - } -}; - -static ClassLoaderDataGraphKlassIteratorStatic static_klass_iterator; - -InstanceKlass* ClassLoaderDataGraph::try_get_next_class() { - assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); - return static_klass_iterator.try_get_next_class(); -} - -void ClassLoaderDataGraph::adjust_saved_class(ClassLoaderData* cld) { - return static_klass_iterator.adjust_saved_class(cld); -} - -void ClassLoaderDataGraph::adjust_saved_class(Klass* klass) { - return static_klass_iterator.adjust_saved_class(klass); -} - void ClassLoaderDataGraph::clean_deallocate_lists(bool walk_previous_versions) { assert(SafepointSynchronize::is_at_safepoint(), "must only be called at safepoint"); uint loaders_processed = 0; diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp index c27a03ec671..ae502b6d30d 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp @@ -97,11 +97,6 @@ class ClassLoaderDataGraph : public AllStatic { // Called from VMOperation static void walk_metadata_and_clean_metaspaces(); - // VM_CounterDecay iteration support - static InstanceKlass* try_get_next_class(); - static void adjust_saved_class(ClassLoaderData* cld); - static void adjust_saved_class(Klass* klass); - static void verify_dictionary(); static void print_dictionary(outputStream* st); static void print_table_statistics(outputStream* st); diff --git a/src/hotspot/share/interpreter/invocationCounter.cpp b/src/hotspot/share/interpreter/invocationCounter.cpp index 965369dc167..fecad2c2f1a 100644 --- a/src/hotspot/share/interpreter/invocationCounter.cpp +++ b/src/hotspot/share/interpreter/invocationCounter.cpp @@ -59,10 +59,6 @@ void InvocationCounter::reset() { update(0); } -void InvocationCounter::decay() { - update(count() >> 1); -} - void InvocationCounter::print() { uint counter = raw_counter(); tty->print_cr("invocation count: up = %d, limit = %d, carry = %s", diff --git a/src/hotspot/share/interpreter/invocationCounter.hpp b/src/hotspot/share/interpreter/invocationCounter.hpp index 3732ed28d48..381d4e9efa8 100644 --- a/src/hotspot/share/interpreter/invocationCounter.hpp +++ b/src/hotspot/share/interpreter/invocationCounter.hpp @@ -60,7 +60,6 @@ class InvocationCounter { // Manipulation void reset(); void init(); - void decay(); // decay counter (divide by two) void set_carry_on_overflow(); void set(uint count); void increment() { _counter += count_increment; } From 92b237c461d610b6ce3876ba0333bb3285042f40 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:26:28 +0000 Subject: [PATCH 135/298] 8315485: (fs) Move java/nio/file/Path/Misc.java tests into java/nio/file/Path/PathOps.java Reviewed-by: lucy Backport-of: 8dfde28b289cbb53173f0ab759156088bbaf74f1 --- test/jdk/java/nio/file/Path/Misc.java | 88 ------------------------ test/jdk/java/nio/file/Path/PathOps.java | 63 ++++++++++++++++- 2 files changed, 61 insertions(+), 90 deletions(-) delete mode 100644 test/jdk/java/nio/file/Path/Misc.java diff --git a/test/jdk/java/nio/file/Path/Misc.java b/test/jdk/java/nio/file/Path/Misc.java deleted file mode 100644 index 550f4588f20..00000000000 --- a/test/jdk/java/nio/file/Path/Misc.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* @test - * @bug 4313887 6838333 7029979 - * @summary Unit test for miscellenous java.nio.file.Path methods - * @library .. /test/lib - * @build jdk.test.lib.Platform - * @run main Misc - */ - -import java.io.*; -import java.nio.file.*; - -import jdk.test.lib.Platform; - -public class Misc { - public static void main(String[] args) throws IOException { - Path dir = TestUtil.createTemporaryDirectory(); - try { - // equals and hashCode methods - testEqualsAndHashCode(); - - // toFile method - testToFile(dir); - } finally { - TestUtil.removeAll(dir); - } - } - - /** - * Exercise equals and hashCode methods - */ - static void testEqualsAndHashCode() { - Path thisFile = Paths.get("this"); - Path thatFile = Paths.get("that"); - - assertTrue(thisFile.equals(thisFile)); - assertTrue(!thisFile.equals(thatFile)); - - assertTrue(!thisFile.equals(null)); - assertTrue(!thisFile.equals(new Object())); - - Path likeThis = Paths.get("This"); - if (Platform.isWindows()) { - // case insensitive - assertTrue(thisFile.equals(likeThis)); - assertTrue(thisFile.hashCode() == likeThis.hashCode()); - } else { - // case senstive - assertTrue(!thisFile.equals(likeThis)); - } - } - - /** - * Exercise toFile method - */ - static void testToFile(Path dir) throws IOException { - File d = dir.toFile(); - assertTrue(d.toString().equals(dir.toString())); - assertTrue(d.toPath().equals(dir)); - } - - static void assertTrue(boolean okay) { - if (!okay) - throw new RuntimeException("Assertion Failed"); - } -} diff --git a/test/jdk/java/nio/file/Path/PathOps.java b/test/jdk/java/nio/file/Path/PathOps.java index aa37ddb84ac..07a59a8c928 100644 --- a/test/jdk/java/nio/file/Path/PathOps.java +++ b/test/jdk/java/nio/file/Path/PathOps.java @@ -22,15 +22,22 @@ */ /* @test - * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449 8254876 8298478 + * @bug 4313887 6838333 6925932 7006126 7029979 8037945 8072495 8140449 + * 8254876 8298478 * @summary Unit test for java.nio.file.Path path operations + * @library .. /test/lib + * @build jdk.test.lib.Platform + * @run main PathOps */ +import java.io.File; import java.nio.file.FileSystems; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import jdk.test.lib.Platform; + public class PathOps { static final java.io.PrintStream out = System.out; @@ -217,6 +224,34 @@ PathOps normalize(String expected) { return this; } + PathOps equals(String other) { + out.format("test equals %s\n", other); + checkPath(); + + Path that = Path.of(other); + check(that, path.toString()); + check(path.hashCode() == that.hashCode(), true); + + return this; + } + + PathOps notEquals(Object other) { + out.format("test not equals %s\n", other); + checkPath(); + check(path.equals(other), false); + + return this; + } + + PathOps toFile() { + out.println("check toFile"); + checkPath(); + File file = path.toFile(); + check(file.toString(), path.toString()); + check(file.toPath().equals(path), true); + return this; + } + PathOps string(String expected) { out.println("check string representation"); checkPath(); @@ -1393,6 +1428,18 @@ static void doWindowsTests() { .parent(null) .name(null); + // equals + test("this") + .equals("this") + .notEquals(Path.of("that")) + .notEquals(null) + .notEquals(new Object()) + .equals(Path.of("This")); + + // toFile + test("C:\\foo\\bar\\gus") + .toFile(); + // invalid test(":\\foo") .invalid(); @@ -2045,6 +2092,18 @@ static void doUnixTests() { test("/foo/bar/gus/../..") .normalize("/foo"); + // equals + test("this") + .equals("this") + .notEquals(Path.of("that")) + .notEquals(null) + .notEquals(new Object()) + .notEquals(Path.of("This")); + + // toFile + test("/foo/bar/gus") + .toFile(); + // invalid test("foo\u0000bar") .invalid(); @@ -2122,7 +2181,7 @@ public static void main(String[] args) { // operating system specific String osname = System.getProperty("os.name"); - if (osname.startsWith("Windows")) { + if (Platform.isWindows()) { doWindowsTests(); } else { doUnixTests(); From 7c5ff9aac5d84588493e18968b0d5bbd93980d2d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:28:57 +0000 Subject: [PATCH 136/298] 8316670: Remove effectively unused nmethodBucket::_count Backport-of: 837783c2d333627bfcbef00fc67024aff847bd9f --- src/hotspot/share/code/dependencyContext.cpp | 48 +++++++------------- src/hotspot/share/code/dependencyContext.hpp | 12 +---- 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/src/hotspot/share/code/dependencyContext.cpp b/src/hotspot/share/code/dependencyContext.cpp index 904b0927014..a6697ba366a 100644 --- a/src/hotspot/share/code/dependencyContext.cpp +++ b/src/hotspot/share/code/dependencyContext.cpp @@ -70,36 +70,30 @@ void DependencyContext::init() { void DependencyContext::mark_dependent_nmethods(DeoptimizationScope* deopt_scope, DepChange& changes) { for (nmethodBucket* b = dependencies_not_unloading(); b != nullptr; b = b->next_not_unloading()) { nmethod* nm = b->get_nmethod(); - if (b->count() > 0) { - if (nm->is_marked_for_deoptimization()) { - deopt_scope->dependent(nm); - } else if (nm->check_dependency_on(changes)) { - LogTarget(Info, dependencies) lt; - if (lt.is_enabled()) { - ResourceMark rm; - LogStream ls(<); - ls.print_cr("Marked for deoptimization"); - changes.print_on(&ls); - nm->print_on(&ls); - nm->print_dependencies_on(&ls); - } - deopt_scope->mark(nm, !changes.is_call_site_change()); + if (nm->is_marked_for_deoptimization()) { + deopt_scope->dependent(nm); + } else if (nm->check_dependency_on(changes)) { + LogTarget(Info, dependencies) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(<); + ls.print_cr("Marked for deoptimization"); + changes.print_on(&ls); + nm->print_on(&ls); + nm->print_dependencies_on(&ls); } + deopt_scope->mark(nm, !changes.is_call_site_change()); } } } // // Add an nmethod to the dependency context. -// It's possible that an nmethod has multiple dependencies on a klass -// so a count is kept for each bucket to guarantee that creation and -// deletion of dependencies is consistent. // void DependencyContext::add_dependent_nmethod(nmethod* nm) { assert_lock_strong(CodeCache_lock); for (nmethodBucket* b = dependencies_not_unloading(); b != nullptr; b = b->next_not_unloading()) { if (nm == b->get_nmethod()) { - b->increment(); return; } } @@ -194,11 +188,9 @@ void DependencyContext::remove_and_mark_for_deoptimization_all_dependents(Deopti set_dependencies(nullptr); while (b != nullptr) { nmethod* nm = b->get_nmethod(); - if (b->count() > 0) { - // Also count already (concurrently) marked nmethods to make sure - // deoptimization is triggered before execution in this thread continues. - deopt_scope->mark(nm); - } + // Also count already (concurrently) marked nmethods to make sure + // deoptimization is triggered before execution in this thread continues. + deopt_scope->mark(nm); b = release_and_get_next_not_unloading(b); } } @@ -208,7 +200,7 @@ void DependencyContext::print_dependent_nmethods(bool verbose) { int idx = 0; for (nmethodBucket* b = dependencies_not_unloading(); b != nullptr; b = b->next_not_unloading()) { nmethod* nm = b->get_nmethod(); - tty->print("[%d] count=%d { ", idx++, b->count()); + tty->print("[%d] { ", idx++); if (!verbose) { nm->print_on(tty, "nmethod"); tty->print_cr(" } "); @@ -224,20 +216,12 @@ void DependencyContext::print_dependent_nmethods(bool verbose) { bool DependencyContext::is_dependent_nmethod(nmethod* nm) { for (nmethodBucket* b = dependencies_not_unloading(); b != nullptr; b = b->next_not_unloading()) { if (nm == b->get_nmethod()) { -#ifdef ASSERT - int count = b->count(); - assert(count >= 0, "count shouldn't be negative: %d", count); -#endif return true; } } return false; } -int nmethodBucket::decrement() { - return Atomic::sub(&_count, 1); -} - // We use a monotonically increasing epoch counter to track the last epoch a given // dependency context was cleaned. GC threads claim cleanup tasks by performing // a CAS on this value. diff --git a/src/hotspot/share/code/dependencyContext.hpp b/src/hotspot/share/code/dependencyContext.hpp index 972a593f82e..630311c2e1e 100644 --- a/src/hotspot/share/code/dependencyContext.hpp +++ b/src/hotspot/share/code/dependencyContext.hpp @@ -39,27 +39,19 @@ class DepChange; // nmethodBucket is used to record dependent nmethods for // deoptimization. nmethod dependencies are actually // pairs but we really only care about the klass part for purposes of -// finding nmethods which might need to be deoptimized. Instead of -// recording the method, a count of how many times a particular nmethod -// was recorded is kept. This ensures that any recording errors are -// noticed since an nmethod should be removed as many times are it's -// added. +// finding nmethods which might need to be deoptimized. // class nmethodBucket: public CHeapObj { friend class VMStructs; private: nmethod* _nmethod; - volatile int _count; nmethodBucket* volatile _next; nmethodBucket* volatile _purge_list_next; public: nmethodBucket(nmethod* nmethod, nmethodBucket* next) : - _nmethod(nmethod), _count(1), _next(next), _purge_list_next(nullptr) {} + _nmethod(nmethod), _next(next), _purge_list_next(nullptr) {} - int count() { return _count; } - int increment() { _count += 1; return _count; } - int decrement(); nmethodBucket* next(); nmethodBucket* next_not_unloading(); void set_next(nmethodBucket* b); From 32ab4a2ab630da19197c827215210f623f015145 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:30:21 +0000 Subject: [PATCH 137/298] 8316669: ImmutableOopMapSet destructor not called Backport-of: 3d6e775d7135919519a9748036cd20b6c130bb42 --- src/hotspot/share/code/codeBlob.cpp | 7 ++++--- src/hotspot/share/compiler/oopMap.cpp | 3 +++ src/hotspot/share/compiler/oopMap.hpp | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index afb807065ab..a384edc936f 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -174,8 +174,10 @@ void RuntimeBlob::free(RuntimeBlob* blob) { } void CodeBlob::flush() { - FREE_C_HEAP_ARRAY(unsigned char, _oop_maps); - _oop_maps = nullptr; + if (_oop_maps != nullptr) { + delete _oop_maps; + _oop_maps = nullptr; + } NOT_PRODUCT(_asm_remarks.clear()); NOT_PRODUCT(_dbg_strings.clear()); } @@ -190,7 +192,6 @@ void CodeBlob::set_oop_maps(OopMapSet* p) { } } - void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const char* name2) { // Do not hold the CodeCache lock during name formatting. assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub"); diff --git a/src/hotspot/share/compiler/oopMap.cpp b/src/hotspot/share/compiler/oopMap.cpp index 58e9daa43a5..ede9f91025f 100644 --- a/src/hotspot/share/compiler/oopMap.cpp +++ b/src/hotspot/share/compiler/oopMap.cpp @@ -871,6 +871,9 @@ ImmutableOopMapSet* ImmutableOopMapSet::build_from(const OopMapSet* oopmap_set) return builder.build(); } +void ImmutableOopMapSet::operator delete(void* p) { + FREE_C_HEAP_ARRAY(unsigned char, p); +} //------------------------------DerivedPointerTable--------------------------- diff --git a/src/hotspot/share/compiler/oopMap.hpp b/src/hotspot/share/compiler/oopMap.hpp index 4b20464f69c..146637f3654 100644 --- a/src/hotspot/share/compiler/oopMap.hpp +++ b/src/hotspot/share/compiler/oopMap.hpp @@ -334,7 +334,10 @@ class ImmutableOopMapSet { address data() const { return (address) this + sizeof(*this) + sizeof(ImmutableOopMapPair) * _count; } public: + void operator delete(void* p); + ImmutableOopMapSet(const OopMapSet* oopmap_set, int size) : _count(oopmap_set->size()), _size(size) {} + ~ImmutableOopMapSet() = default; ImmutableOopMap* oopmap_at_offset(int offset) const { assert(offset >= 0 && offset < _size, "must be within boundaries"); From 08396870958bdf66f6d20bd80512109cd6246589 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:40:16 +0000 Subject: [PATCH 138/298] 8317235: Remove Access API use in nmethod class Backport-of: c47a0ce3f03daf7a4ec0c0c8b8626bb662836936 --- src/hotspot/share/code/nmethod.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 86df9db21cc..ce516b8aef1 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1700,7 +1700,7 @@ class IsUnloadingState: public AllStatic { }; bool nmethod::is_unloading() { - uint8_t state = RawAccess::load(&_is_unloading_state); + uint8_t state = Atomic::load(&_is_unloading_state); bool state_is_unloading = IsUnloadingState::is_unloading(state); if (state_is_unloading) { return true; @@ -1736,7 +1736,7 @@ bool nmethod::is_unloading() { void nmethod::clear_unloading_state() { uint8_t state = IsUnloadingState::create(false, CodeCache::unloading_cycle()); - RawAccess::store(&_is_unloading_state, state); + Atomic::store(&_is_unloading_state, state); } From c094d7e42f8b9eeddadab5e22ab2e258fc2f2514 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:45:32 +0000 Subject: [PATCH 139/298] 8317677: Specialize Vtablestubs::entry_for() for VtableBlob Backport-of: 1082c0e767a5060d1969edc5ef16f9974e799960 --- src/hotspot/share/code/compiledIC.cpp | 13 ++++++------- src/hotspot/share/code/vtableStubs.cpp | 7 +++++++ src/hotspot/share/code/vtableStubs.hpp | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/code/compiledIC.cpp b/src/hotspot/share/code/compiledIC.cpp index c6294ff5627..b966b580984 100644 --- a/src/hotspot/share/code/compiledIC.cpp +++ b/src/hotspot/share/code/compiledIC.cpp @@ -561,15 +561,14 @@ void CompiledIC::compute_monomorphic_entry(const methodHandle& method, bool CompiledIC::is_icholder_entry(address entry) { CodeBlob* cb = CodeCache::find_blob(entry); - if (cb != nullptr && cb->is_adapter_blob()) { - return true; + if (cb == nullptr) { + return false; } - // itable stubs also use CompiledICHolder - if (cb != nullptr && cb->is_vtable_blob()) { - VtableStub* s = VtableStubs::entry_point(entry); - return (s != nullptr) && s->is_itable_stub(); + if (cb->is_adapter_blob()) { + return true; + } else if (cb->is_vtable_blob()) { + return VtableStubs::is_icholder_entry(entry); } - return false; } diff --git a/src/hotspot/share/code/vtableStubs.cpp b/src/hotspot/share/code/vtableStubs.cpp index 934f805eefc..3c07bdba733 100644 --- a/src/hotspot/share/code/vtableStubs.cpp +++ b/src/hotspot/share/code/vtableStubs.cpp @@ -284,6 +284,13 @@ VtableStub* VtableStubs::entry_point(address pc) { return (s == stub) ? s : nullptr; } +bool VtableStubs::is_icholder_entry(address pc) { + assert(contains(pc), "must contain all vtable blobs"); + VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); + // itable stubs use CompiledICHolder. + return stub->is_itable_stub(); +} + bool VtableStubs::contains(address pc) { // simple solution for now - we may want to use // a faster way if this function is called often diff --git a/src/hotspot/share/code/vtableStubs.hpp b/src/hotspot/share/code/vtableStubs.hpp index bd037e62cce..a2bb24f34ce 100644 --- a/src/hotspot/share/code/vtableStubs.hpp +++ b/src/hotspot/share/code/vtableStubs.hpp @@ -105,6 +105,7 @@ class VtableStubs : AllStatic { static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); } static VtableStub* entry_point(address pc); // vtable stub entry point for a pc + static bool is_icholder_entry(address pc); // is the blob containing pc (which must be a vtable blob) an icholder? static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or nullptr static int number_of_vtable_stubs() { return _number_of_vtable_stubs; } From d2c6be94255d6f46820c8af437987a008d11a123 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:46:34 +0000 Subject: [PATCH 140/298] 8317350: Move code cache purging out of CodeCache::UnloadingScope Backport-of: bd3bc2c6181668b5856732666dc251136b7fbb99 --- src/hotspot/share/code/codeCache.cpp | 1 - src/hotspot/share/code/codeCache.hpp | 5 +---- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 9 +++++--- src/hotspot/share/gc/g1/g1FullCollector.cpp | 11 ++++++---- .../share/gc/parallel/psParallelCompact.cpp | 21 ++++++++++++------- src/hotspot/share/gc/serial/genMarkSweep.cpp | 21 ++++++++++++------- .../share/gc/shenandoah/shenandoahHeap.cpp | 20 +++++++++++------- 7 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 3bc1db70251..7808c86a92c 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1036,7 +1036,6 @@ CodeCache::UnloadingScope::UnloadingScope(BoolObjectClosure* is_alive) CodeCache::UnloadingScope::~UnloadingScope() { IsUnloadingBehaviour::set_current(_saved_behaviour); DependencyContext::cleaning_end(); - CodeCache::flush_unlinked_nmethods(); } void CodeCache::verify_oops() { diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 8abc4043ae6..459df9b19f0 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -179,10 +179,7 @@ class CodeCache : AllStatic { // GC support static void verify_oops(); - // If any oops are not marked this method unloads (i.e., breaks root links - // to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading" - // to "true" iff some code got unloaded. - // "unloading_occurred" controls whether metadata should be cleaned because of class unloading. + // Scope object managing code cache unloading behavior. class UnloadingScope: StackObj { ClosureIsUnloadingBehaviour _is_unloading_behaviour; IsUnloadingBehaviour* _saved_behaviour; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 248a5043777..23454ddffba 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1684,9 +1684,12 @@ void G1ConcurrentMark::weak_refs_work() { // Unload Klasses, String, Code Cache, etc. if (ClassUnloadingWithConcurrentMark) { GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm); - CodeCache::UnloadingScope scope(&g1_is_alive); - bool purged_classes = SystemDictionary::do_unloading(_gc_timer_cm); - _g1h->complete_cleaning(purged_classes); + { + CodeCache::UnloadingScope scope(&g1_is_alive); + bool unloading_occurred = SystemDictionary::do_unloading(_gc_timer_cm); + _g1h->complete_cleaning(unloading_occurred); + } + CodeCache::flush_unlinked_nmethods(); } } diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 4381d515c6a..f225937a49f 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -319,10 +319,13 @@ void G1FullCollector::phase1_mark_live_objects() { // Class unloading and cleanup. if (ClassUnloading) { GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer()); - CodeCache::UnloadingScope unloading_scope(&_is_alive); - // Unload classes and purge the SystemDictionary. - bool purged_class = SystemDictionary::do_unloading(scope()->timer()); - _heap->complete_cleaning(purged_class); + { + CodeCache::UnloadingScope unloading_scope(&_is_alive); + // Unload classes and purge the SystemDictionary. + bool unloading_occurred = SystemDictionary::do_unloading(scope()->timer()); + _heap->complete_cleaning(unloading_occurred); + } + CodeCache::flush_unlinked_nmethods(); } { diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 64b2c0475f4..cf6471fd818 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -2052,19 +2052,26 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer); - CodeCache::UnloadingScope scope(is_alive_closure()); - // Follow system dictionary roots and unload classes. - bool purged_class = SystemDictionary::do_unloading(&_gc_timer); + bool unloading_occurred; + { + CodeCache::UnloadingScope scope(is_alive_closure()); + + // Follow system dictionary roots and unload classes. + unloading_occurred = SystemDictionary::do_unloading(&_gc_timer); + + // Unload nmethods. + CodeCache::do_unloading(unloading_occurred); + } - // Unload nmethods. - CodeCache::do_unloading(purged_class); + // Release unloaded nmethods's memory. + CodeCache::flush_unlinked_nmethods(); // Prune dead klasses from subklass/sibling/implementor lists. - Klass::clean_weak_klass_links(purged_class); + Klass::clean_weak_klass_links(unloading_occurred); // Clean JVMCI metadata handles. - JVMCI_ONLY(JVMCI::do_unloading(purged_class)); + JVMCI_ONLY(JVMCI::do_unloading(unloading_occurred)); } { diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp index 07c5396bc86..fec80327f12 100644 --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp @@ -195,19 +195,26 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", gc_timer()); - CodeCache::UnloadingScope scope(&is_alive); - // Unload classes and purge the SystemDictionary. - bool purged_class = SystemDictionary::do_unloading(gc_timer()); + bool unloading_occurred; + { + CodeCache::UnloadingScope scope(&is_alive); - // Unload nmethods. - CodeCache::do_unloading(purged_class); + // Unload classes and purge the SystemDictionary. + unloading_occurred = SystemDictionary::do_unloading(gc_timer()); + + // Unload nmethods. + CodeCache::do_unloading(unloading_occurred); + } + + // Release unloaded nmethod's memory. + CodeCache::flush_unlinked_nmethods(); // Prune dead klasses from subklass/sibling/implementor lists. - Klass::clean_weak_klass_links(purged_class); + Klass::clean_weak_klass_links(unloading_occurred); // Clean JVMCI metadata handles. - JVMCI_ONLY(JVMCI::do_unloading(purged_class)); + JVMCI_ONLY(JVMCI::do_unloading(unloading_occurred)); } { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 71f1747a760..a1a5e8dbddd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1773,14 +1773,18 @@ void ShenandoahHeap::stw_unload_classes(bool full_gc) { ShenandoahPhaseTimings::full_gc_purge_class_unload : ShenandoahPhaseTimings::degen_gc_purge_class_unload; ShenandoahIsAliveSelector is_alive; - CodeCache::UnloadingScope scope(is_alive.is_alive_closure()); - ShenandoahGCPhase gc_phase(phase); - ShenandoahGCWorkerPhase worker_phase(phase); - bool purged_class = SystemDictionary::do_unloading(gc_timer()); - - uint num_workers = _workers->active_workers(); - ShenandoahClassUnloadingTask unlink_task(phase, num_workers, purged_class); - _workers->run_task(&unlink_task); + { + CodeCache::UnloadingScope scope(is_alive.is_alive_closure()); + ShenandoahGCPhase gc_phase(phase); + ShenandoahGCWorkerPhase worker_phase(phase); + bool unloading_occurred = SystemDictionary::do_unloading(gc_timer()); + + uint num_workers = _workers->active_workers(); + ShenandoahClassUnloadingTask unlink_task(phase, num_workers, unloading_occurred); + _workers->run_task(&unlink_task); + } + // Release unloaded nmethods's memory. + CodeCache::flush_unlinked_nmethods(); } { From 620250b8e609ec38e8cfff7dcf677d9a796ed8e4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 3 Apr 2024 09:48:18 +0000 Subject: [PATCH 141/298] 8317965: TestLoadLibraryDeadlock.java fails with "Unable to load native library.: expected true, was false" 8319265: TestLoadLibraryDeadlock.java fails on windows-x64 "Unable to load b.jar" Backport-of: 5207443b360cfe3ee9c53ece55da3464c13f6a9f --- .../LoadLibraryDeadlock.java | 21 +++- .../TestLoadLibraryDeadlock.java | 115 ++++-------------- 2 files changed, 45 insertions(+), 91 deletions(-) diff --git a/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/LoadLibraryDeadlock.java b/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/LoadLibraryDeadlock.java index 42ecd372aec..4c615b74d1c 100644 --- a/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/LoadLibraryDeadlock.java +++ b/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/LoadLibraryDeadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, BELLSOFT. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,16 +33,19 @@ * triggered from JNI. */ import java.lang.*; +import java.net.URISyntaxException; public class LoadLibraryDeadlock { public static void main(String[] args) { + System.out.println("LoadLibraryDeadlock test started"); Thread t1 = new Thread() { public void run() { try { // an instance of unsigned class that loads a native library Class c1 = Class.forName("Class1"); Object o = c1.newInstance(); + System.out.println("Class1 loaded from " + getLocation(c1)); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { @@ -56,7 +59,7 @@ public void run() { try { // load a class from a signed jar, which locks the JarFile Class c2 = Class.forName("p.Class2"); - System.out.println("Signed jar loaded."); + System.out.println("Class2 loaded from " + getLocation(c2)); } catch (ClassNotFoundException e) { System.out.println("Class Class2 not found."); throw new RuntimeException(e); @@ -68,7 +71,19 @@ public void run() { try { t1.join(); t2.join(); - } catch (InterruptedException ignore) { + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + } + + private static String getLocation(Class c) { + var pd = c.getProtectionDomain(); + var cs = pd != null ? pd.getCodeSource() : null; + try { + // same format as returned by TestLoadLibraryDeadlock::getLocation + return cs != null ? cs.getLocation().toURI().getPath() : null; + } catch (URISyntaxException ex) { + throw new RuntimeException(ex); } } } diff --git a/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/TestLoadLibraryDeadlock.java b/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/TestLoadLibraryDeadlock.java index 65a485b34a3..7f4438b42ce 100644 --- a/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/TestLoadLibraryDeadlock.java +++ b/test/jdk/java/lang/ClassLoader/loadLibraryDeadlock/TestLoadLibraryDeadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, BELLSOFT. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,13 +38,14 @@ import jdk.test.lib.util.FileUtils; import java.lang.ProcessBuilder; -import java.lang.Process; +import java.nio.file.Path; import java.nio.file.Paths; import java.io.*; import java.util.*; -import java.util.concurrent.*; import java.util.spi.ToolProvider; +import static jdk.test.lib.process.ProcessTools.*; + public class TestLoadLibraryDeadlock { private static final ToolProvider JAR = ToolProvider.findFirst("jar") @@ -108,53 +109,6 @@ private static OutputAnalyzer signJar(String jarToSign) throws Throwable { ); } - private static Process runJavaCommand(String... command) throws Throwable { - String java = JDKToolFinder.getJDKTool("java"); - List commands = new ArrayList<>(); - Collections.addAll(commands, java); - Collections.addAll(commands, command); - System.out.println("COMMAND: " + String.join(" ", commands)); - return new ProcessBuilder(commands.toArray(new String[0])) - .redirectErrorStream(true) - .directory(new File(testClassPath)) - .start(); - } - - private static OutputAnalyzer jcmd(long pid, String command) throws Throwable { - String jcmd = JDKToolFinder.getJDKTool("jcmd"); - return runCommandInTestClassPath(jcmd, - String.valueOf(pid), - command - ); - } - - private static String readAvailable(final InputStream is) throws Throwable { - final List list = Collections.synchronizedList(new ArrayList()); - ExecutorService executor = Executors.newFixedThreadPool(2); - Future future = executor.submit(new Callable() { - public String call() { - String result = new String(); - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - try { - while(true) { - String s = reader.readLine(); - if (s.length() > 0) { - list.add(s); - result += s + "\n"; - } - } - } catch (IOException ignore) {} - return result; - } - }); - try { - return future.get(1000, TimeUnit.MILLISECONDS); - } catch (Exception ignoreAll) { - future.cancel(true); - return String.join("\n", list); - } - } - private final static long countLines(OutputAnalyzer output, String string) { return output.asLines() .stream() @@ -162,22 +116,17 @@ private final static long countLines(OutputAnalyzer output, String string) { .count(); } - private final static void dump(OutputAnalyzer output) { - output.asLines() - .stream() - .forEach(s -> System.out.println(s)); - } - public static void main(String[] args) throws Throwable { genKey() .shouldHaveExitValue(0); - FileUtils.deleteFileIfExistsWithRetry( - Paths.get(testClassPath, "a.jar")); - FileUtils.deleteFileIfExistsWithRetry( - Paths.get(testClassPath, "b.jar")); - FileUtils.deleteFileIfExistsWithRetry( - Paths.get(testClassPath, "c.jar")); + Path aJar = Path.of(testClassPath, "a.jar"); + Path bJar = Path.of(testClassPath, "b.jar"); + Path cJar = Path.of(testClassPath, "c.jar"); + + FileUtils.deleteFileIfExistsWithRetry(aJar); + FileUtils.deleteFileIfExistsWithRetry(bJar); + FileUtils.deleteFileIfExistsWithRetry(cJar); createJar("a.jar", "LoadLibraryDeadlock.class", @@ -194,24 +143,13 @@ public static void main(String[] args) throws Throwable { .shouldHaveExitValue(0); // load trigger class - Process process = runJavaCommand("-cp", - "a.jar" + classPathSeparator + - "b.jar" + classPathSeparator + - "c.jar", + OutputAnalyzer outputAnalyzer = executeCommand(createTestJavaProcessBuilder("-cp", + aJar.toString() + classPathSeparator + + bJar.toString() + classPathSeparator + + cJar.toString(), "-Djava.library.path=" + testLibraryPath, - "LoadLibraryDeadlock"); - - // wait for a while to grab some output - process.waitFor(5, TimeUnit.SECONDS); - - // dump available output - String output = readAvailable(process.getInputStream()); - OutputAnalyzer outputAnalyzer = new OutputAnalyzer(output); - dump(outputAnalyzer); - - // if the process is still running, get the thread dump - OutputAnalyzer outputAnalyzerJcmd = jcmd(process.pid(), "Thread.print"); - dump(outputAnalyzerJcmd); + "LoadLibraryDeadlock")); + outputAnalyzer.shouldHaveExitValue(0); Asserts.assertTrue( countLines(outputAnalyzer, "Java-level deadlock") == 0, @@ -231,19 +169,20 @@ public static void main(String[] args) throws Throwable { "Unable to load native library."); Asserts.assertTrue( - countLines(outputAnalyzer, "Signed jar loaded.") > 0, - "Unable to load signed jar."); + countLines(outputAnalyzer, "Class1 loaded from " + toLocationString(bJar)) > 0, + "Unable to load " + toLocationString(bJar)); + + Asserts.assertTrue( + countLines(outputAnalyzer, "Class2 loaded from " + toLocationString(cJar)) > 0, + "Unable to load signed " + toLocationString(cJar)); Asserts.assertTrue( countLines(outputAnalyzer, "Signed jar loaded from native library.") > 0, "Unable to load signed jar from native library."); + } - if (!process.waitFor(5, TimeUnit.SECONDS)) { - // if the process is still frozen, fail the test even though - // the "deadlock" text hasn't been found - process.destroyForcibly(); - Asserts.assertTrue(process.waitFor() == 0, - "Process frozen."); - } + private static String toLocationString(Path path) { + // same format as returned by LoadLibraryDeadlock::getLocation + return path.toUri().getPath(); } } From 78e35ea113bed4a5f66225836c887a45696bbf44 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Wed, 3 Apr 2024 12:08:11 +0000 Subject: [PATCH 142/298] 8185862: AWT Assertion Failure in ::GetDIBits(hBMDC, hBM, 0, 1, 0, gpBitmapInfo, 0) 'awt_Win32GraphicsDevice.cpp', at line 185 Backport-of: dcca5daaf7f51c6579369c6ba3430a3d7962dbf2 --- .../classes/java/awt/GraphicsEnvironment.java | 4 +- .../classes/sun/awt/PlatformGraphicsInfo.java | 32 ++++++-- .../sun/awt/Win32GraphicsEnvironment.java | 15 +--- .../windows/native/libawt/windows/Devices.cpp | 81 +++++++++++-------- .../windows/native/libawt/windows/Devices.h | 4 +- .../windows/awt_PlatformGraphicsInfo.cpp | 37 +++++++++ .../windows/awt_Win32GraphicsDevice.cpp | 4 +- .../libawt/windows/awt_Win32GraphicsEnv.cpp | 4 +- .../HangDuringStaticInitialization.java | 3 +- 9 files changed, 124 insertions(+), 60 deletions(-) create mode 100644 src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp diff --git a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java index 0265142aee3..2e89aa6f672 100644 --- a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java +++ b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, 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 @@ -23,7 +23,6 @@ * questions. */ - package java.awt; import java.awt.image.BufferedImage; @@ -36,7 +35,6 @@ import sun.font.FontManagerFactory; import sun.java2d.HeadlessGraphicsEnvironment; import sun.java2d.SunGraphicsEnvironment; -import sun.security.action.GetPropertyAction; /** * diff --git a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java index 02527d4f207..4644a2e5f46 100644 --- a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java +++ b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -28,20 +28,41 @@ import java.awt.GraphicsEnvironment; import java.awt.Toolkit; +import sun.awt.windows.WToolkit; + public class PlatformGraphicsInfo { + private static final boolean hasDisplays; + + static { + loadAWTLibrary(); + hasDisplays = hasDisplays0(); + } + + @SuppressWarnings("removal") + private static void loadAWTLibrary() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); + } + + private static native boolean hasDisplays0(); + public static GraphicsEnvironment createGE() { return new Win32GraphicsEnvironment(); } public static Toolkit createToolkit() { - return new sun.awt.windows.WToolkit(); + return new WToolkit(); } public static boolean getDefaultHeadlessProperty() { - // On Windows, we assume we can always create headful apps. - // Here is where we can add code that would actually check. - return false; + // If we don't find usable displays, we run headless. + return !hasDisplays; } /* @@ -54,5 +75,4 @@ public static String getDefaultHeadlessMessage() { "\nThe application does not have desktop access,\n" + "but this program performed an operation which requires it."; } - } diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java index 04b3f7b77d7..cb7ab363cdf 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -60,7 +60,8 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment { WToolkit.loadLibraries(); // setup flags before initializing native layer WindowsFlags.initFlags(); - initDisplayWrapper(); + + initDisplay(); // Install correct surface manager factory. SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory()); @@ -82,20 +83,12 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment { } /** - * Initializes native components of the graphics environment. This + * Initializes native components of the graphics environment. This * includes everything from the native GraphicsDevice elements to * the DirectX rendering layer. */ private static native void initDisplay(); - private static boolean displayInitialized; // = false; - public static void initDisplayWrapper() { - if (!displayInitialized) { - displayInitialized = true; - initDisplay(); - } - } - public Win32GraphicsEnvironment() { } diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.cpp b/src/java.desktop/windows/native/libawt/windows/Devices.cpp index f36914e4606..e275cb77a57 100644 --- a/src/java.desktop/windows/native/libawt/windows/Devices.cpp +++ b/src/java.desktop/windows/native/libawt/windows/Devices.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -85,60 +85,75 @@ #include "Trace.h" #include "D3DPipelineManager.h" +typedef struct { + int monitorCounter; + int monitorLimit; + HMONITOR* hmpMonitors; +} MonitorData; -/* Some helper functions (from awt_MMStub.h/cpp) */ -int g_nMonitorCounter; -int g_nMonitorLimit; -HMONITOR* g_hmpMonitors; +// Only monitors where CreateDC does not fail are valid +static BOOL IsValidMonitor(HMONITOR hMon) +{ + MONITORINFOEX mieInfo; + memset((void*)(&mieInfo), 0, sizeof(MONITORINFOEX)); + mieInfo.cbSize = sizeof(MONITORINFOEX); + if (!::GetMonitorInfo(hMon, (LPMONITORINFOEX)(&mieInfo))) { + J2dTraceLn1(J2D_TRACE_INFO, "Devices::IsValidMonitor: GetMonitorInfo failed for monitor with handle %p", hMon); + return FALSE; + } + + HDC hDC = CreateDC(mieInfo.szDevice, NULL, NULL, NULL); + if (NULL == hDC) { + J2dTraceLn2(J2D_TRACE_INFO, "Devices::IsValidMonitor: CreateDC failed for monitor with handle %p, device: %S", hMon, mieInfo.szDevice); + return FALSE; + } + + ::DeleteDC(hDC); + return TRUE; +} // Callback for CountMonitors below -BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP) +static BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorCounter) { - g_nMonitorCounter ++; + if (IsValidMonitor(hMon)) { + (*((int *)lpMonitorCounter))++; + } + return TRUE; } int WINAPI CountMonitors(void) { - g_nMonitorCounter = 0; - ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, 0L); - return g_nMonitorCounter; - + int monitorCounter = 0; + ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, (LPARAM)&monitorCounter); + return monitorCounter; } // Callback for CollectMonitors below -BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP) +static BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorData) { - - if ((g_nMonitorCounter < g_nMonitorLimit) && (NULL != g_hmpMonitors)) { - g_hmpMonitors[g_nMonitorCounter] = hMon; - g_nMonitorCounter ++; + MonitorData* pMonitorData = (MonitorData *)lpMonitorData; + if ((pMonitorData->monitorCounter < pMonitorData->monitorLimit) && (IsValidMonitor(hMon))) { + pMonitorData->hmpMonitors[pMonitorData->monitorCounter] = hMon; + pMonitorData->monitorCounter++; } return TRUE; } -int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum) +static int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum) { - int retCode = 0; - if (NULL != hmpMonitors) { - - g_nMonitorCounter = 0; - g_nMonitorLimit = nNum; - g_hmpMonitors = hmpMonitors; - - ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, 0L); - - retCode = g_nMonitorCounter; - - g_nMonitorCounter = 0; - g_nMonitorLimit = 0; - g_hmpMonitors = NULL; - + MonitorData monitorData; + monitorData.monitorCounter = 0; + monitorData.monitorLimit = nNum; + monitorData.hmpMonitors = hmpMonitors; + ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, (LPARAM)&monitorData); + return monitorData.monitorCounter; + } else { + return 0; } - return retCode; } BOOL WINAPI MonitorBounds(HMONITOR hmMonitor, RECT* rpBounds) diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.h b/src/java.desktop/windows/native/libawt/windows/Devices.h index b6fd56a777f..0972ef1414e 100644 --- a/src/java.desktop/windows/native/libawt/windows/Devices.h +++ b/src/java.desktop/windows/native/libawt/windows/Devices.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -74,4 +74,6 @@ static CriticalSection arrayLock; BOOL WINAPI MonitorBounds (HMONITOR, RECT*); +int WINAPI CountMonitors (void); + #endif // _DEVICES_H_ diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp new file mode 100644 index 00000000000..638cd100b1f --- /dev/null +++ b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 SAP SE. 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. + */ + +#include +#include "Devices.h" + +/* + * Class: sun_awt_PlatformGraphicsInfo + * Method: hasDisplays0 + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL +Java_sun_awt_PlatformGraphicsInfo_hasDisplays0(JNIEnv *env, jclass thisClass) { + return CountMonitors() > 0 ? JNI_TRUE : JNI_FALSE; +} diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp index 1e9b492161f..14820028fef 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -180,7 +180,9 @@ void AwtWin32GraphicsDevice::Initialize() } gpBitmapInfo->bmiHeader.biBitCount = 0; HDC hBMDC = this->GetDC(); + VERIFY(hBMDC != NULL); HBITMAP hBM = ::CreateCompatibleBitmap(hBMDC, 1, 1); + VERIFY(hBM != NULL); VERIFY(::GetDIBits(hBMDC, hBM, 0, 1, NULL, gpBitmapInfo, DIB_RGB_COLORS)); if (colorData->bitsperpixel > 8) { diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp index 6c949b564e9..9991427c75e 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -36,10 +36,8 @@ BOOL DWMIsCompositionEnabled(); void initScreens(JNIEnv *env) { - if (!Devices::UpdateInstance(env)) { JNU_ThrowInternalError(env, "Could not update the devices array."); - return; } } diff --git a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java index fc820a32fa1..d6666d21309 100644 --- a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java +++ b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -33,7 +33,6 @@ /** * @test * @bug 8189604 8208702 - * @requires !vm.debug | os.family != "windows" * @run main/othervm -Djava.awt.headless=false HangDuringStaticInitialization * @run main/othervm -Djava.awt.headless=true HangDuringStaticInitialization */ From fbc5871c084bd90f926358d1f49dfeaee06e1a52 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 4 Apr 2024 16:08:27 +0000 Subject: [PATCH 143/298] 8328638: Fallback option for POST-only OCSP requests 8329213: Better validation for com.sun.security.ocsp.useget option Reviewed-by: serb Backport-of: 614db2ea9e10346475eef34629eab54878aa482d --- .../security/action/GetPropertyAction.java | 34 ++++++++++++++ .../sun/security/provider/certpath/OCSP.java | 35 +++++++++++++- .../OCSP/GetAndPostTests.java | 6 ++- .../testlibrary/SimpleOCSPServer.java | 11 ++++- .../certification/CAInterop.java | 47 +++++++++++++++++++ 5 files changed, 128 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java index 7b1757e46a0..ef04103db2e 100644 --- a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java +++ b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java @@ -27,6 +27,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Locale; import java.util.Properties; import sun.security.util.Debug; @@ -223,4 +224,37 @@ public static int privilegedGetTimeoutProp(String prop, int def, Debug dbg) { return def; } } + + /** + * Convenience method for fetching System property values that are booleans. + * + * @param prop the name of the System property + * @param def a default value + * @param dbg a Debug object, if null no debug messages will be sent + * + * @return a boolean value corresponding to the value in the System property. + * If the property value is neither "true" or "false", the default value + * will be returned. + */ + public static boolean privilegedGetBooleanProp(String prop, boolean def, Debug dbg) { + String rawPropVal = privilegedGetProperty(prop, ""); + if ("".equals(rawPropVal)) { + return def; + } + + String lower = rawPropVal.toLowerCase(Locale.ROOT); + if ("true".equals(lower)) { + return true; + } else if ("false".equals(lower)) { + return false; + } else { + if (dbg != null) { + dbg.println("Warning: Unexpected value for " + prop + + ": " + rawPropVal + + ". Using default value: " + def); + } + return def; + } + } + } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java index a21635afa97..6f1f7b6ad73 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -85,6 +85,28 @@ public final class OCSP { private static final int READ_TIMEOUT = initializeTimeout( "com.sun.security.ocsp.readtimeout", DEFAULT_READ_TIMEOUT); + /** + * Boolean value indicating whether OCSP client can use GET for OCSP + * requests. There is an ambiguity in RFC recommendations. + * + * RFC 5019 says a stronger thing, "MUST": + * "When sending requests that are less than or equal to 255 bytes in + * total (after encoding) including the scheme and delimiters (http://), + * server name and base64-encoded OCSPRequest structure, clients MUST + * use the GET method (to enable OCSP response caching)." + * + * RFC 6960 says a weaker thing, "MAY": + * "HTTP-based OCSP requests can use either the GET or the POST method to + * submit their requests. To enable HTTP caching, small requests (that + * after encoding are less than 255 bytes) MAY be submitted using GET." + * + * For performance reasons, we default to stronger behavior. But this + * option also allows to fallback to weaker behavior in case of compatibility + * problems. + */ + private static final boolean USE_GET = initializeBoolean( + "com.sun.security.ocsp.useget", true); + /** * Initialize the timeout length by getting the OCSP timeout * system property. If the property has not been set, or if its @@ -99,6 +121,15 @@ private static int initializeTimeout(String prop, int def) { return timeoutVal; } + private static boolean initializeBoolean(String prop, boolean def) { + boolean value = + GetPropertyAction.privilegedGetBooleanProp(prop, def, debug); + if (debug != null) { + debug.println(prop + " set to " + value); + } + return value; + } + private OCSP() {} /** @@ -186,7 +217,7 @@ public static byte[] getOCSPBytes(List certIds, URI responderURI, encodedGetReq.append(URLEncoder.encode( Base64.getEncoder().encodeToString(bytes), UTF_8)); - if (encodedGetReq.length() <= 255) { + if (USE_GET && encodedGetReq.length() <= 255) { url = new URI(encodedGetReq.toString()).toURL(); con = (HttpURLConnection)url.openConnection(); con.setConnectTimeout(CONNECT_TIMEOUT); diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java index f8e1ae751b6..478e94572bc 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8179503 + * @bug 8179503 8328638 * @summary Java should support GET OCSP calls * @library /javax/net/ssl/templates /java/security/testlibrary * @build SimpleOCSPServer @@ -31,6 +31,8 @@ * java.base/sun.security.provider.certpath * java.base/sun.security.x509 * @run main/othervm GetAndPostTests + * @run main/othervm -Dcom.sun.security.ocsp.useget=false GetAndPostTests + * @run main/othervm -Dcom.sun.security.ocsp.useget=foo GetAndPostTests */ import java.io.ByteArrayInputStream; diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java index e4b06a26504..afbd239fb4c 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -704,6 +704,9 @@ public CRLReason getRevocationReason() { * responses. */ private class OcspHandler implements Runnable { + private final boolean USE_GET = + !System.getProperty("com.sun.security.ocsp.useget", "").equals("false"); + private final Socket sock; InetSocketAddress peerSockAddr; @@ -876,6 +879,12 @@ private LocalOcspRequest parseHttpOcspPost(InputStream inStream) // Okay, make sure we got what we needed from the header, then // read the remaining OCSP Request bytes if (properContentType && length >= 0) { + if (USE_GET && length <= 255) { + // Received a small POST request. Check that our client code properly + // handled the relevant flag. We expect small GET requests, unless + // explicitly disabled. + throw new IOException("Should have received small GET, not POST."); + } byte[] ocspBytes = new byte[length]; inStream.read(ocspBytes); return new LocalOcspRequest(ocspBytes); diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index c1a0d782cb7..0b832366286 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -30,6 +30,9 @@ * @run main/othervm -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca OCSP * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false + * CAInterop actalisauthenticationrootca OCSP + * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca CRL */ @@ -40,6 +43,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca1 CRL */ @@ -50,6 +54,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca2 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca2 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca2 CRL */ @@ -60,6 +65,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca3 CRL */ @@ -70,6 +76,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca4 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca4 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca4 CRL */ @@ -80,6 +87,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass2ca OCSP * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca CRL */ @@ -90,6 +98,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass3ca OCSP * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca CRL */ @@ -100,6 +109,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodorsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodorsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop comodorsaca CRL */ @@ -110,6 +120,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodoeccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodoeccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop comodoeccca CRL */ @@ -120,6 +131,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrustrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrustrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop usertrustrsaca CRL */ @@ -130,6 +142,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrusteccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrusteccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop usertrusteccca CRL */ @@ -140,6 +153,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx1 DEFAULT */ /* @@ -149,6 +163,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx2 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx2 DEFAULT */ /* @@ -158,6 +173,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignrootcar6 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignrootcar6 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignrootcar6 CRL */ @@ -168,6 +184,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcaec1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcaec1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcaec1 CRL */ @@ -178,6 +195,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcag4 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcag4 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcag4 CRL */ @@ -188,6 +206,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop godaddyrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop godaddyrootg2ca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop godaddyrootg2ca CRL */ @@ -198,6 +217,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop starfieldrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop starfieldrootg2ca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop starfieldrootg2ca CRL */ @@ -208,6 +228,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigneccrootcar4 DEFAULT */ /* @@ -217,6 +238,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar1 DEFAULT */ /* @@ -226,6 +248,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar2 DEFAULT */ /* @@ -235,6 +258,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar3 DEFAULT */ /* @@ -243,6 +267,7 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar4 DEFAULT * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 DEFAULT */ @@ -253,6 +278,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftecc2017 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftecc2017 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftecc2017 CRL */ @@ -263,6 +289,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftrsa2017 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftrsa2017 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftrsa2017 CRL */ @@ -273,6 +300,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca1g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca1g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca1g3 CRL */ @@ -283,6 +311,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca2g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca2g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca2g3 CRL */ @@ -293,6 +322,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca3g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca3g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL */ @@ -303,6 +333,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlseccrootg5 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL */ @@ -313,6 +344,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlsrsarootg5 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL */ @@ -323,6 +355,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootrsaca CRL */ @@ -333,6 +366,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootevrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootevrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootevrsaca CRL */ @@ -343,6 +377,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrooteccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrooteccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrooteccca CRL */ @@ -353,6 +388,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliasonerarootcav1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliasonerarootcav1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop teliasonerarootcav1 CRL */ @@ -363,6 +399,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop twcaglobalrootca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop twcaglobalrootca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop twcaglobalrootca CRL */ @@ -373,6 +410,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certignarootca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certignarootca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop certignarootca CRL */ @@ -383,6 +421,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustcommercialca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustcommercialca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustcommercialca CRL */ @@ -393,6 +432,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustnetworkingca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustnetworkingca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustnetworkingca CRL */ @@ -403,6 +443,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumca CRL */ @@ -413,6 +454,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumeccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumeccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumeccca CRL */ @@ -423,6 +465,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliarootcav2 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliarootcav2 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop teliarootcav2 CRL */ @@ -433,6 +476,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsignrootcag1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsignrootcag1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop emsignrootcag1 CRL */ @@ -443,6 +487,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsigneccrootcag3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsigneccrootcag3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL */ @@ -453,6 +498,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyrootr1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyrootr1 DEFAULT */ /* @@ -462,6 +508,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyroote1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyroote1 DEFAULT */ /** From 74dcc30d5fd7e37e37f87216ce5a60c76ee94e82 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 4 Apr 2024 20:49:48 +0000 Subject: [PATCH 144/298] 8288936: Wrong lock ordering writing G1HeapRegionTypeChange JFR event Backport-of: 0eb0997ae4f81314b764241e69dae5c698dbb6c6 --- src/hotspot/share/runtime/mutexLocker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index ea46300d145..e62b29a328c 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -292,8 +292,8 @@ void mutex_init() { } #if INCLUDE_JFR - MUTEX_DEFN(JfrBuffer_lock , PaddedMutex , nosafepoint); - MUTEX_DEFN(JfrMsg_lock , PaddedMonitor, nosafepoint-3); + MUTEX_DEFN(JfrBuffer_lock , PaddedMutex , event); + MUTEX_DEFN(JfrMsg_lock , PaddedMonitor, event); MUTEX_DEFN(JfrStacktrace_lock , PaddedMutex , stackwatermark-1); MUTEX_DEFN(JfrThreadSampler_lock , PaddedMonitor, nosafepoint); #endif From 702d337294f405e8962c9fcd1823cd358035c372 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 4 Apr 2024 20:53:40 +0000 Subject: [PATCH 145/298] 8304839: Move TestScaffold.main() to the separate class DebugeeWrapper Backport-of: ee9776fa23e2287b704d4f1a55179e83516d1e4c --- test/jdk/com/sun/jdi/ClassesByName2Test.java | 6 +- test/jdk/com/sun/jdi/DebuggeeWrapper.java | 123 ++++++++++++++++++ test/jdk/com/sun/jdi/DeferredStepTest.java | 4 +- test/jdk/com/sun/jdi/EATests.java | 2 +- .../jdk/com/sun/jdi/ForceEarlyReturnTest.java | 2 +- test/jdk/com/sun/jdi/InterruptHangTest.java | 2 +- test/jdk/com/sun/jdi/InvokeHangTest.java | 4 +- test/jdk/com/sun/jdi/JdbLockTest.java | 2 +- test/jdk/com/sun/jdi/JdbStopThreadidTest.java | 6 +- test/jdk/com/sun/jdi/MonitorEventTest.java | 2 +- .../jdk/com/sun/jdi/MultiBreakpointsTest.java | 2 +- test/jdk/com/sun/jdi/PopAsynchronousTest.java | 2 +- test/jdk/com/sun/jdi/PopFramesTest.java | 3 +- test/jdk/com/sun/jdi/ResumeOneThreadTest.java | 4 +- .../sun/jdi/SetLocalWhileThreadInNative.java | 2 +- test/jdk/com/sun/jdi/SimulResumerTest.java | 4 +- test/jdk/com/sun/jdi/TestScaffold.java | 100 ++------------ .../jdk/com/sun/jdi/ThreadMemoryLeakTest.java | 5 +- test/jdk/com/sun/jdi/TwoThreadsTest.java | 4 +- 19 files changed, 158 insertions(+), 121 deletions(-) create mode 100644 test/jdk/com/sun/jdi/DebuggeeWrapper.java diff --git a/test/jdk/com/sun/jdi/ClassesByName2Test.java b/test/jdk/com/sun/jdi/ClassesByName2Test.java index 72d50f61096..acc186e7225 100644 --- a/test/jdk/com/sun/jdi/ClassesByName2Test.java +++ b/test/jdk/com/sun/jdi/ClassesByName2Test.java @@ -50,12 +50,12 @@ public static void main(String[] args){ System.out.println("Howdy!"); try { - Thread zero = TestScaffold.newThread (() -> { + Thread zero = DebuggeeWrapper.newThread (() -> { System.setProperty("java.awt.headless", "true"); java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); }, "ZERO"); - Thread one = TestScaffold.newThread (() -> { + Thread one = DebuggeeWrapper.newThread (() -> { try { java.security.KeyPairGenerator keyGen = java.security.KeyPairGenerator.getInstance("DSA", "SUN"); @@ -64,7 +64,7 @@ public static void main(String[] args){ } }, "ONE"); - Thread two = TestScaffold.newThread (() -> { + Thread two = DebuggeeWrapper.newThread (() -> { try { String s = String.format("%02x", 0xff); } catch (Exception e) { diff --git a/test/jdk/com/sun/jdi/DebuggeeWrapper.java b/test/jdk/com/sun/jdi/DebuggeeWrapper.java new file mode 100644 index 00000000000..4904e3a394d --- /dev/null +++ b/test/jdk/com/sun/jdi/DebuggeeWrapper.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023, 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.lang.reflect.InvocationTargetException; +import java.util.concurrent.ThreadFactory; + +public class DebuggeeWrapper { + + public static String PROPERTY_NAME = "main.wrapper"; + + private static final String OLD_MAIN_THREAD_NAME = "old-m-a-i-n"; + + private static ThreadFactory threadFactory = r -> new Thread(r); + + private static final String wrapperName = System.getProperty(PROPERTY_NAME); + + public static String getWrapperName() { + return wrapperName; + } + + public static boolean isVirtual() { + return "Virtual".equals(wrapperName); + } + + public static Thread newThread(Runnable task) { + return threadFactory.newThread(task); + } + + public static Thread newThread(Runnable task, String name) { + Thread t = newThread(task); + t.setName(name); + return t; + } + + public static void main(String[] args) throws Throwable { + String className = args[0]; + String[] classArgs = new String[args.length - 1]; + System.arraycopy(args, 1, classArgs, 0, args.length - 1); + Class c = Class.forName(className); + java.lang.reflect.Method mainMethod = c.getMethod("main", new Class[] { String[].class }); + mainMethod.setAccessible(true); + + if (isVirtual()) { + threadFactory = Thread.ofVirtual().factory(); + MainThreadGroup tg = new MainThreadGroup(); + Thread vthread = Thread.ofVirtual().unstarted(() -> { + try { + mainMethod.invoke(null, new Object[] { classArgs }); + } catch (InvocationTargetException e) { + tg.uncaughtThrowable = e.getCause(); + } catch (Throwable error) { + tg.uncaughtThrowable = error; + } + }); + Thread.currentThread().setName(OLD_MAIN_THREAD_NAME); + vthread.setName("main"); + vthread.start(); + vthread.join(); + if (tg.uncaughtThrowable != null) { + // Note we cant just rethrow tg.uncaughtThrowable because there are tests + // that track ExceptionEvents, and they will complain about the extra + // exception. So instead mimic what happens when the main thread exits + // with an exception. + System.out.println("Uncaught Exception: " + tg.uncaughtThrowable); + tg.uncaughtThrowable.printStackTrace(System.out); + System.exit(1); + } + } else if (getWrapperName().equals("Kernel")) { + MainThreadGroup tg = new MainThreadGroup(); + Thread t = new Thread(tg, () -> { + try { + mainMethod.invoke(null, new Object[] { classArgs }); + } catch (InvocationTargetException e) { + tg.uncaughtThrowable = e.getCause(); + } catch (Throwable error) { + tg.uncaughtThrowable = error; + } + }); + t.start(); + t.join(); + if (tg.uncaughtThrowable != null) { + throw new RuntimeException(tg.uncaughtThrowable); + } + } else { + mainMethod.invoke(null, new Object[] { classArgs }); + } + } + + static class MainThreadGroup extends ThreadGroup { + MainThreadGroup() { + super("MainThreadGroup"); + } + + public void uncaughtException(Thread t, Throwable e) { + if (e instanceof ThreadDeath) { + return; + } + e.printStackTrace(System.err); + uncaughtThrowable = e; + } + Throwable uncaughtThrowable = null; + } +} \ No newline at end of file diff --git a/test/jdk/com/sun/jdi/DeferredStepTest.java b/test/jdk/com/sun/jdi/DeferredStepTest.java index 53829715f2f..c9a5bfc2433 100644 --- a/test/jdk/com/sun/jdi/DeferredStepTest.java +++ b/test/jdk/com/sun/jdi/DeferredStepTest.java @@ -74,8 +74,8 @@ public static void main(String argv[]) { jj1 obj1 = new jj1(); jj2 obj2 = new jj2(); - Thread thread1 = TestScaffold.newThread(obj1, "jj1"); - Thread thread2 = TestScaffold.newThread(obj2, "jj2"); + Thread thread1 = DebuggeeWrapper.newThread(obj1, "jj1"); + Thread thread2 = DebuggeeWrapper.newThread(obj2, "jj2"); thread1.start(); thread2.start(); // Threads might be deamon threads, so wait here for them to complete. diff --git a/test/jdk/com/sun/jdi/EATests.java b/test/jdk/com/sun/jdi/EATests.java index 2cdb4a85dfb..41a38c334a2 100644 --- a/test/jdk/com/sun/jdi/EATests.java +++ b/test/jdk/com/sun/jdi/EATests.java @@ -888,7 +888,7 @@ public void run() { public static void staticSetUp() { inflatedLock = new XYVal(1, 1); synchronized (inflatedLock) { - inflatorThread = TestScaffold.newThread(() -> { + inflatorThread = DebuggeeWrapper.newThread(() -> { synchronized (inflatedLock) { inflatedLockIsPermanentlyInflated = true; inflatedLock.notify(); // main thread diff --git a/test/jdk/com/sun/jdi/ForceEarlyReturnTest.java b/test/jdk/com/sun/jdi/ForceEarlyReturnTest.java index 97b3db044d3..d9c21b12057 100644 --- a/test/jdk/com/sun/jdi/ForceEarlyReturnTest.java +++ b/test/jdk/com/sun/jdi/ForceEarlyReturnTest.java @@ -169,7 +169,7 @@ public void printStack(ThreadReference thread, String msg) throws Exception { protected void runTests() throws Exception { BreakpointEvent bpe = startTo("ForceEarlyReturnTestTarg", "loopOrSleep", "()V"); ThreadReference mainThread = bpe.thread(); - boolean is_vthread_mode = "Virtual".equals(System.getProperty("main.wrapper")); + boolean is_vthread_mode = DebuggeeWrapper.isVirtual(); // Resume main thread until it is in Thread.sleep() or the infinite loop. mainThread.resume(); diff --git a/test/jdk/com/sun/jdi/InterruptHangTest.java b/test/jdk/com/sun/jdi/InterruptHangTest.java index 9600c03cd1d..e2c238eee49 100644 --- a/test/jdk/com/sun/jdi/InterruptHangTest.java +++ b/test/jdk/com/sun/jdi/InterruptHangTest.java @@ -47,7 +47,7 @@ class InterruptHangTarg { public static void main(String[] args){ int answer = 0; System.out.println("Howdy!"); - Thread interruptorThread = TestScaffold.newThread(new Interruptor(Thread.currentThread())); + Thread interruptorThread = DebuggeeWrapper.newThread(new Interruptor(Thread.currentThread())); synchronized(sync) { interruptorThread.start(); diff --git a/test/jdk/com/sun/jdi/InvokeHangTest.java b/test/jdk/com/sun/jdi/InvokeHangTest.java index 5fc58cace5a..83b92b68747 100644 --- a/test/jdk/com/sun/jdi/InvokeHangTest.java +++ b/test/jdk/com/sun/jdi/InvokeHangTest.java @@ -54,8 +54,8 @@ class InvokeHangTarg implements Runnable { public static void main(String[] args) { System.out.println("Howdy!"); - Thread t1 = TestScaffold.newThread(new InvokeHangTarg(), name1); - Thread t2 = TestScaffold.newThread(new InvokeHangTarg(), name2); + Thread t1 = DebuggeeWrapper.newThread(new InvokeHangTarg(), name1); + Thread t2 = DebuggeeWrapper.newThread(new InvokeHangTarg(), name2); t1.start(); t2.start(); diff --git a/test/jdk/com/sun/jdi/JdbLockTest.java b/test/jdk/com/sun/jdi/JdbLockTest.java index ef6c49210e6..fb6c363db77 100644 --- a/test/jdk/com/sun/jdi/JdbLockTest.java +++ b/test/jdk/com/sun/jdi/JdbLockTest.java @@ -39,7 +39,7 @@ class JdbLockTestTarg { static String jj = "jj"; public static void main(String args[]) { synchronized(jj) { - Thread xx = TestScaffold.newThread(new Sleeper()); + Thread xx = DebuggeeWrapper.newThread(new Sleeper()); xx.start(); // Give the sleeper a chance to run and get to // the synchronized statement. diff --git a/test/jdk/com/sun/jdi/JdbStopThreadidTest.java b/test/jdk/com/sun/jdi/JdbStopThreadidTest.java index cbed0b14563..5109cfab475 100644 --- a/test/jdk/com/sun/jdi/JdbStopThreadidTest.java +++ b/test/jdk/com/sun/jdi/JdbStopThreadidTest.java @@ -51,9 +51,9 @@ private static void test() { MyTask myTask1 = test.new MyTask(); MyTask myTask2 = test.new MyTask(); MyTask myTask3 = test.new MyTask(); - Thread myThread1 = TestScaffold.newThread(myTask1, "MYTHREAD-1"); - Thread myThread2 = TestScaffold.newThread(myTask2, "MYTHREAD-2"); - Thread myThread3 = TestScaffold.newThread(myTask3, "MYTHREAD-3"); + Thread myThread1 = DebuggeeWrapper.newThread(myTask1, "MYTHREAD-1"); + Thread myThread2 = DebuggeeWrapper.newThread(myTask2, "MYTHREAD-2"); + Thread myThread3 = DebuggeeWrapper.newThread(myTask3, "MYTHREAD-3"); synchronized (lockObj) { myThread1.start(); diff --git a/test/jdk/com/sun/jdi/MonitorEventTest.java b/test/jdk/com/sun/jdi/MonitorEventTest.java index 66e65937230..0e0db49ff33 100644 --- a/test/jdk/com/sun/jdi/MonitorEventTest.java +++ b/test/jdk/com/sun/jdi/MonitorEventTest.java @@ -61,7 +61,7 @@ public static void main(String[] args){ endingMonitor = new Object(); startingMonitor = new Object(); - Thread t1 = TestScaffold.newThread(new MyTask()); + Thread t1 = DebuggeeWrapper.newThread(new MyTask()); foo(); aboutEnterLock = false; diff --git a/test/jdk/com/sun/jdi/MultiBreakpointsTest.java b/test/jdk/com/sun/jdi/MultiBreakpointsTest.java index aa5a622679b..6304aef96b9 100644 --- a/test/jdk/com/sun/jdi/MultiBreakpointsTest.java +++ b/test/jdk/com/sun/jdi/MultiBreakpointsTest.java @@ -143,7 +143,7 @@ Thread console(final int num, final int nhits) { // //final String threadName = "DebuggeeThread: " + num; final String threadName = "" + num; - Thread thrd = TestScaffold.newThread(() -> { + Thread thrd = DebuggeeWrapper.newThread(() -> { synchronized( isr ) { boolean done = false; try { diff --git a/test/jdk/com/sun/jdi/PopAsynchronousTest.java b/test/jdk/com/sun/jdi/PopAsynchronousTest.java index 4431bfc60c6..e689a8a61d9 100644 --- a/test/jdk/com/sun/jdi/PopAsynchronousTest.java +++ b/test/jdk/com/sun/jdi/PopAsynchronousTest.java @@ -186,7 +186,7 @@ protected void runTests() throws Exception { /* * start popping wildly away */ - TestScaffold.newThread(new HarassThread()).start(); + DebuggeeWrapper.newThread(new HarassThread()).start(); /* * resume the target listening for events diff --git a/test/jdk/com/sun/jdi/PopFramesTest.java b/test/jdk/com/sun/jdi/PopFramesTest.java index 9dcfb48b41f..992e0e2a3bc 100644 --- a/test/jdk/com/sun/jdi/PopFramesTest.java +++ b/test/jdk/com/sun/jdi/PopFramesTest.java @@ -318,8 +318,7 @@ protected void runTests() throws Exception { * works. So you have an unmounted virtual thread with no native frames, which * results in OpaqueFrameException being thrown. */ - String mainWrapper = System.getProperty("main.wrapper"); - if ("Virtual".equals(mainWrapper)) { + if (DebuggeeWrapper.isVirtual()) { expected_exception = OpaqueFrameException.class; } else { expected_exception = NativeMethodException.class; diff --git a/test/jdk/com/sun/jdi/ResumeOneThreadTest.java b/test/jdk/com/sun/jdi/ResumeOneThreadTest.java index 8b724aba30c..77a96c2a487 100644 --- a/test/jdk/com/sun/jdi/ResumeOneThreadTest.java +++ b/test/jdk/com/sun/jdi/ResumeOneThreadTest.java @@ -43,8 +43,8 @@ class ResumeOneThreadTarg implements Runnable { public static void main(String[] args) { System.out.println(" Debuggee: Howdy!"); - Thread t1 = TestScaffold.newThread(new ResumeOneThreadTarg(), name1); - Thread t2 = TestScaffold.newThread(new ResumeOneThreadTarg(), name2); + Thread t1 = DebuggeeWrapper.newThread(new ResumeOneThreadTarg(), name1); + Thread t2 = DebuggeeWrapper.newThread(new ResumeOneThreadTarg(), name2); t1.start(); t2.start(); // We must block until these threads exit. Otherwise for virtual threads diff --git a/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java b/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java index c4d8db5b411..6607e519efe 100644 --- a/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java +++ b/test/jdk/com/sun/jdi/SetLocalWhileThreadInNative.java @@ -174,7 +174,7 @@ protected void runTests() } } } - boolean isVirtualThread = "Virtual".equals(System.getProperty("main.wrapper")); + boolean isVirtualThread = DebuggeeWrapper.isVirtual(); Asserts.assertTrue(caughtOFE == isVirtualThread); Asserts.assertTrue(changedLocal == !isVirtualThread); diff --git a/test/jdk/com/sun/jdi/SimulResumerTest.java b/test/jdk/com/sun/jdi/SimulResumerTest.java index 89fbb625f42..92cf4ba9ab5 100644 --- a/test/jdk/com/sun/jdi/SimulResumerTest.java +++ b/test/jdk/com/sun/jdi/SimulResumerTest.java @@ -50,8 +50,8 @@ class SimulResumerTarg implements Runnable { static int count = 10000; public static void main(String[] args) { System.out.println("Howdy!"); - Thread t1 = TestScaffold.newThread(new SimulResumerTarg(), name1); - Thread t2 = TestScaffold.newThread(new SimulResumerTarg(), name2); + Thread t1 = DebuggeeWrapper.newThread(new SimulResumerTarg(), name1); + Thread t2 = DebuggeeWrapper.newThread(new SimulResumerTarg(), name2); t1.start(); t2.start(); diff --git a/test/jdk/com/sun/jdi/TestScaffold.java b/test/jdk/com/sun/jdi/TestScaffold.java index 831dac0247e..b4b30855acc 100644 --- a/test/jdk/com/sun/jdi/TestScaffold.java +++ b/test/jdk/com/sun/jdi/TestScaffold.java @@ -24,10 +24,9 @@ import com.sun.jdi.*; import com.sun.jdi.request.*; import com.sun.jdi.event.*; -import java.lang.reflect.InvocationTargetException; import java.util.*; import java.io.*; -import java.util.concurrent.ThreadFactory; + /** * Framework used by all JDI regression tests @@ -67,7 +66,6 @@ abstract public class TestScaffold extends TargetAdapter { final String[] args; protected boolean testFailed = false; protected long startTime; - public static final String OLD_MAIN_THREAD_NAME = "old-m-a-i-n"; static private class ArgInfo { String targetVMArgs = ""; @@ -513,8 +511,8 @@ private ArgInfo parseArgs(String args[]) { // argInfo.targetAppCommandLine : Frames2Targ // argInfo.targetVMArgs : -Xss4M // The result with wrapper enabled: - // argInfo.targetAppCommandLine : TestScaffold Virtual Frames2Targ - // argInfo.targetVMArgs : -Xss4M + // argInfo.targetAppCommandLine : DebuggeeWrapper Frames2Targ + // argInfo.targetVMArgs : -Xss4M -Dmain.wrapper=Virtual boolean classNameParsed = false; for (int i = 0; i < args.length; i++) { String arg = args[i].trim(); @@ -549,12 +547,12 @@ private ArgInfo parseArgs(String args[]) { } } - // Need to change args to run wrapper using command like 'TestScaffold Virtual ' - String mainWrapper = System.getProperty("main.wrapper"); + // Need to change args to run wrapper using command like 'DebuggeeWrapper ' + // and set property 'main.wrapper' so test could use DebuggeeWrapper.isVirtual() method + String mainWrapper = DebuggeeWrapper.getWrapperName(); if (mainWrapper != null && !argInfo.targetAppCommandLine.isEmpty()) { - argInfo.targetVMArgs += "-Dmain.wrapper=" + mainWrapper; - argInfo.targetAppCommandLine = TestScaffold.class.getName() + ' ' - + mainWrapper + ' ' + argInfo.targetAppCommandLine; + argInfo.targetVMArgs += "-D" + DebuggeeWrapper.PROPERTY_NAME + "=" + mainWrapper; + argInfo.targetAppCommandLine = DebuggeeWrapper.class.getName() + ' ' + argInfo.targetAppCommandLine; } else if ("true".equals(System.getProperty("test.enable.preview"))) { // the test specified @enablePreview. argInfo.targetVMArgs += "--enable-preview "; @@ -1044,86 +1042,4 @@ public void shutdown(String message) { vmDisconnected = true; } - private static ThreadFactory threadFactory = r -> new Thread(r); - - public static void main(String[] args) throws Throwable { - String wrapper = args[0]; - String className = args[1]; - String[] classArgs = new String[args.length - 2]; - System.arraycopy(args, 2, classArgs, 0, args.length - 2); - Class c = Class.forName(className); - java.lang.reflect.Method mainMethod = c.getMethod("main", new Class[] { String[].class }); - mainMethod.setAccessible(true); - - if (wrapper.equals("Virtual")) { - threadFactory = Thread.ofVirtual().factory(); - MainThreadGroup tg = new MainThreadGroup(); - // TODO fix to set virtual scheduler group when become available - Thread vthread = Thread.ofVirtual().unstarted(() -> { - try { - mainMethod.invoke(null, new Object[] { classArgs }); - } catch (InvocationTargetException e) { - tg.uncaughtThrowable = e.getCause(); - } catch (Throwable error) { - tg.uncaughtThrowable = error; - } - }); - Thread.currentThread().setName(OLD_MAIN_THREAD_NAME); - vthread.setName("main"); - vthread.start(); - vthread.join(); - if (tg.uncaughtThrowable != null) { - // Note we cant just rethrow tg.uncaughtThrowable because there are tests - // that track ExceptionEvents, and they will complain about the extra - // exception. So instead mimic what happens when the main thread exits - // with an exception. - System.out.println("Uncaught Exception: " + tg.uncaughtThrowable); - tg.uncaughtThrowable.printStackTrace(System.out); - System.exit(1); - } - } else if (wrapper.equals("Kernel")) { - MainThreadGroup tg = new MainThreadGroup(); - Thread t = new Thread(tg, () -> { - try { - mainMethod.invoke(null, new Object[] { classArgs }); - } catch (InvocationTargetException e) { - tg.uncaughtThrowable = e.getCause(); - } catch (Throwable error) { - tg.uncaughtThrowable = error; - } - }); - t.start(); - t.join(); - if (tg.uncaughtThrowable != null) { - throw new RuntimeException(tg.uncaughtThrowable); - } - } else { - mainMethod.invoke(null, new Object[] { classArgs }); - } - } - - static class MainThreadGroup extends ThreadGroup { - MainThreadGroup() { - super("MainThreadGroup"); - } - - public void uncaughtException(Thread t, Throwable e) { - if (e instanceof ThreadDeath) { - return; - } - e.printStackTrace(System.err); - uncaughtThrowable = e; - } - Throwable uncaughtThrowable = null; - } - - public static Thread newThread(Runnable task) { - return threadFactory.newThread(task); - } - - public static Thread newThread(Runnable task, String name) { - Thread t = newThread(task); - t.setName(name); - return t; - } } diff --git a/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java b/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java index bdb3d131c6b..cb2264a66eb 100644 --- a/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java +++ b/test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java @@ -58,19 +58,18 @@ public static void main(String[] args) throws InterruptedException { while (System.currentTimeMillis() - startTime < 100 * 1000) { iterations++; semaphore.acquire(); - TestScaffold.newThread(() -> { + DebuggeeWrapper.newThread(() -> { adder.increment(); long sum = adder.sum(); if ((sum % 1000) == 0) { System.out.println("Progress: " + sum); } try { - String mainWrapper = System.getProperty("main.wrapper"); // Virtual thread creation tends to overwhelm the debugger, // leading to high memory use for all the unprocessed events // that get queued up, so we need to slow it down a bit more // than we do for platform threads to avoid getting OOME. - long timeToSleep = "Virtual".equals(mainWrapper) ? 100 : 50; + long timeToSleep = DebuggeeWrapper.isVirtual() ? 100 : 50; Thread.sleep(timeToSleep); } catch (InterruptedException e) { diff --git a/test/jdk/com/sun/jdi/TwoThreadsTest.java b/test/jdk/com/sun/jdi/TwoThreadsTest.java index 64b0aa19eef..e38783f3ea6 100644 --- a/test/jdk/com/sun/jdi/TwoThreadsTest.java +++ b/test/jdk/com/sun/jdi/TwoThreadsTest.java @@ -50,8 +50,8 @@ class TwoThreadsTarg implements Runnable { public static void main(String[] args) { System.out.println("Howdy!"); - Thread t1 = TestScaffold.newThread(new TwoThreadsTarg(), name1); - Thread t2 = TestScaffold.newThread(new TwoThreadsTarg(), name2); + Thread t1 = DebuggeeWrapper.newThread(new TwoThreadsTarg(), name1); + Thread t2 = DebuggeeWrapper.newThread(new TwoThreadsTarg(), name2); t1.start(); t2.start(); From 1563c54a7f0a5cac7a56b945da468b6687dcd0a6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 4 Apr 2024 20:55:16 +0000 Subject: [PATCH 146/298] 8319153: Fix: Class is a raw type in ProcessTools Backport-of: 1c2ea1d27b1895dca3b30073e3516978083dc70a --- test/lib/jdk/test/lib/process/ProcessTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index f4d42a2aef4..9423825048c 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -920,7 +920,7 @@ public static void main(String[] args) throws Throwable { String className = args[1]; String[] classArgs = new String[args.length - 2]; System.arraycopy(args, 2, classArgs, 0, args.length - 2); - Class c = Class.forName(className); + Class c = Class.forName(className); Method mainMethod = c.getMethod("main", new Class[] { String[].class }); mainMethod.setAccessible(true); From c05f3bf4a4d8180d11abf055a9456eade963d64a Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 5 Apr 2024 06:44:49 +0000 Subject: [PATCH 147/298] 8328776: [AIX] remove checked_vmgetinfo, use vmgetinfo directly Backport-of: cf9b5a71bd66a51147d0dbf9ecf4038101a1e191 --- src/hotspot/os/aix/os_aix.cpp | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 5ae890ca7ee..f4140b8bde4 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -320,27 +320,14 @@ static char cpu_arch[] = "ppc64"; #error Add appropriate cpu_arch setting #endif -// Wrap the function "vmgetinfo" which is not available on older OS releases. -static int checked_vmgetinfo(void *out, int command, int arg) { - if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) { - guarantee(false, "cannot call vmgetinfo on AS/400 older than V6R1"); - } - return ::vmgetinfo(out, command, arg); -} - // Given an address, returns the size of the page backing that address. size_t os::Aix::query_pagesize(void* addr) { - - if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) { - // AS/400 older than V6R1: no vmgetinfo here, default to 4K - return 4*K; - } - vm_page_info pi; pi.addr = (uint64_t)addr; - if (checked_vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) { + if (::vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) { return pi.pagesize; } else { + trcVerbose("vmgetinfo(VM_PAGE_INFO) failed (errno: %d)", errno); assert(false, "vmgetinfo failed to retrieve page size"); return 4*K; } @@ -442,7 +429,7 @@ static void query_multipage_support() { { const int MAX_PAGE_SIZES = 4; psize_t sizes[MAX_PAGE_SIZES]; - const int num_psizes = checked_vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES); + const int num_psizes = ::vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES); if (num_psizes == -1) { trcVerbose("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)", errno); trcVerbose("disabling multipage support."); From bdf57475efa84c96e6ccbdbb4355d5d2d0939930 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 5 Apr 2024 06:47:31 +0000 Subject: [PATCH 148/298] 8328709: AIX os::get_summary_cpu_info support Power 10 Backport-of: b235682a18653ab16f2d9b03b1e55698a91273b7 --- src/hotspot/os/aix/os_aix.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index f4140b8bde4..8efb8c8f259 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -137,7 +137,7 @@ extern "C" int getargs(procsinfo*, int, char*, int); #define ERROR_MP_VMGETINFO_FAILED 102 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 -// excerpts from systemcfg.h that might be missing on older os levels +// excerpts from sys/systemcfg.h that might be missing on older os levels #ifndef PV_7 #define PV_7 0x200000 /* Power PC 7 */ #endif @@ -156,7 +156,12 @@ extern "C" int getargs(procsinfo*, int, char*, int); #ifndef PV_9_Compat #define PV_9_Compat 0x408000 /* Power PC 9 */ #endif - +#ifndef PV_10 + #define PV_10 0x500000 /* Power PC 10 */ +#endif +#ifndef PV_10_Compat + #define PV_10_Compat 0x508000 /* Power PC 10 */ +#endif static address resolve_function_descriptor_to_code_pointer(address p); @@ -1304,6 +1309,9 @@ void os::print_memory_info(outputStream* st) { void os::get_summary_cpu_info(char* buf, size_t buflen) { // read _system_configuration.version switch (_system_configuration.version) { + case PV_10: + strncpy(buf, "Power PC 10", buflen); + break; case PV_9: strncpy(buf, "Power PC 9", buflen); break; @@ -1343,6 +1351,9 @@ void os::get_summary_cpu_info(char* buf, size_t buflen) { case PV_9_Compat: strncpy(buf, "PV_9_Compat", buflen); break; + case PV_10_Compat: + strncpy(buf, "PV_10_Compat", buflen); + break; default: strncpy(buf, "unknown", buflen); } From b80fb5e6d4c5fa5bd0df31ae2d52bd872880c16e Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 5 Apr 2024 06:50:18 +0000 Subject: [PATCH 149/298] 8327468: Do not restart close if errno is EINTR [macOS/linux] Backport-of: 481c866df87c693a90a1da20e131e5654b084ddd --- src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c | 3 +-- src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c index c96a45d8fd7..52dce9e883c 100644 --- a/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c @@ -198,9 +198,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close (JNIEnv *env, jclass cls, jint fd) { - int res; shutdown(fd, SHUT_RDWR); - RESTARTABLE(close(fd), res); + close(fd); } /* diff --git a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c index d20a6f012f2..9c0ed2a817b 100644 --- a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c @@ -200,9 +200,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close (JNIEnv *env, jclass cls, jint fd) { - int res; shutdown(fd, SHUT_RDWR); - RESTARTABLE(close(fd), res); + close(fd); } /* @@ -294,8 +293,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_createAttachFile } RESTARTABLE(chown(_path, geteuid(), getegid()), rc); - - RESTARTABLE(close(fd), rc); + close(fd); /* release p here */ if (isCopy) { From ccaa6d7ebf7fb1352858a2f26470d8d35bcff5a8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 5 Apr 2024 19:08:31 +0000 Subject: [PATCH 150/298] 8303773: Replace "main.wrapper" with "test.thread.factory" property in test code Backport-of: 89987dbf8789f166fe24e7facf5b8cc9a3c292c2 --- .../jdb/monitor/monitor001/monitor001.java | 4 +-- .../jdb/threads/threads003/threads003.java | 4 +-- .../unmonitor/unmonitor001/unmonitor001.java | 4 +-- .../jdi/StackFrame/_bounds_/bounds002.java | 4 +-- .../threads/threads001.java | 12 +++---- .../nsk/jdi/ThreadReference/stop/stop001.java | 2 +- .../jdi/ThreadReference/stop/stop001a.java | 2 +- .../nsk/jdi/ThreadReference/stop/stop002.java | 2 +- .../jdi/ThreadReference/stop/stop002t.java | 2 +- .../ThreadStartEvent/thread/thread001.java | 4 +-- .../vmTestbase/nsk/share/MainWrapper.java | 2 +- .../vmTestbase/nsk/share/jdb/Launcher.java | 6 ++-- .../vmTestbase/nsk/share/jdi/Binder.java | 6 ++-- .../vmTestbase/nsk/share/jdi/Debugee.java | 4 +-- .../nsk/share/jdi/JDIThreadFactory.java | 2 +- .../nsk/share/jpda/DebugeeBinder.java | 4 +-- .../nsk/share/runner/RunParams.java | 4 +-- test/jdk/com/sun/jdi/DebuggeeWrapper.java | 12 +++---- test/jdk/com/sun/jdi/TestScaffold.java | 10 +++--- .../src/share/classes/Virtual.java | 2 +- .../jdk/test/lib/process/ProcessTools.java | 33 +++++++++---------- 21 files changed, 62 insertions(+), 63 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java index e3486a81b82..1fd1f8c328b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -152,7 +152,7 @@ private boolean checkCommands(String[] reply) { // check 'threads', searching for "java.lang.Thread" followed by the main thread name. v.add("java.lang.Thread"); - if (System.getProperty("main.wrapper") != null) { + if (System.getProperty("test.thread.factory") != null) { v.add(nsk.share.MainWrapper.OLD_MAIN_THREAD_NAME); } else { v.add("main"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java index e9caa83388c..4332eb69cf9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -90,7 +90,7 @@ protected void runCases() { int count; Vector v; String[] threads; - boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); if (!vthreadMode) { // This test is only meant to be run in vthread mode. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java index 3d53fc159ca..7d98824be73 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -186,7 +186,7 @@ private boolean checkCommands(String[] reply) { // check 'threads', searching for "java.lang.Thread" followed by the main thread name. v.add("java.lang.Thread"); - if (System.getProperty("main.wrapper") != null) { + if (System.getProperty("test.thread.factory") != null) { v.add(nsk.share.MainWrapper.OLD_MAIN_THREAD_NAME); } else { v.add("main"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/_bounds_/bounds002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/_bounds_/bounds002.java index 16308834cba..b4971ee03a2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/_bounds_/bounds002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/_bounds_/bounds002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -191,7 +191,7 @@ private void execTest() { complain("Unexpected " + e); exitStatus = Consts.TEST_FAILED; } - boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); display("vthreadMode: " + vthreadMode + ", isTopmostFrame: " + isTopmostFrame); try { stackFrame.setValue(var, null); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadGroupReference/threads/threads001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadGroupReference/threads/threads001.java index 09124c038e8..d8b773faf4d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadGroupReference/threads/threads001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadGroupReference/threads/threads001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -134,8 +134,8 @@ private static void log3(String message) { private int runThis (String argv[], PrintStream out) { Debugee debuggee; - boolean usingWrapper = System.getProperty("main.wrapper") != null; - boolean usingVThreadWrapper = "Virtual".equals(System.getProperty("main.wrapper")); + boolean usingTTF = System.getProperty("test.thread.factory") != null; + boolean usingVirtualTTF = "Virtual".equals(System.getProperty("test.thread.factory")); argsHandler = new ArgumentHandler(argv); logHandler = new Log(out, argsHandler); @@ -253,10 +253,10 @@ private int runThis (String argv[], PrintStream out) { * the "VirtualThreads" ThreadGroup, and threfore do not show up in group1. */ int expectedNumThreads; - if (usingVThreadWrapper) { + if (usingVirtualTTF) { expectedNumThreads = 1; } else { - expectedNumThreads = usingWrapper ? 3 : 2; + expectedNumThreads = usingTTF ? 3 : 2; } if (threads.size() < expectedNumThreads) { log3("ERROR: threads.size() < 2 for group1 : " + threads.size() ); @@ -277,7 +277,7 @@ private int runThis (String argv[], PrintStream out) { if (s1.equals("Thread2")) nThread2 += 1; } - if (nMain != 1 && !usingVThreadWrapper) { + if (nMain != 1 && !usingVirtualTTF) { log3("ERROR: # of 'main' threads != 1 : " + nMain); expresult = 1; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001.java index dd451dc3007..5c04f30145c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001.java @@ -69,7 +69,7 @@ public class stop001 { static final int PASSED = 0; static final int FAILED = 2; static final int PASS_BASE = 95; - static final boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + static final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); //----------------------------------------------------- templete parameters static final String diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001a.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001a.java index 9fb5a61113f..bd0136e55e2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001a.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop001a.java @@ -189,7 +189,7 @@ public Threadstop001a(String threadName) { public static Object lockingObject2 = new Object(); - static final boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + static final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); private int i1 = 0, i2 = 10; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java index 55788e323b1..de8ee1df617 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java @@ -75,7 +75,7 @@ public class stop002 { static final String COMMAND_GO = "go"; static final String COMMAND_QUIT = "quit"; - static final boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + static final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); private ArgumentHandler argHandler; private Log log; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java index 0b544905cb4..694485e608e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java @@ -38,7 +38,7 @@ public class stop002t { volatile boolean stopLooping1 = false; volatile boolean stopLooping2 = false; volatile static int testNumReady = 0; - static final boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + static final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); public static void main(String args[]) { System.exit(run(args) + Consts.JCK_STATUS_BASE); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001.java index 34c05b6cd04..0ec0b83b304 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -251,7 +251,7 @@ public void run() { // debug agent has already generated the THREAD_START event for the // original "main", so we end up with two THREAD_START events for "main". // We need to allow for this. - if ((System.getProperty("main.wrapper") != null) && + if ((System.getProperty("test.thread.factory") != null) && checkedThreads[i][0].equals("main") && checkedThreads[i][1].equals("1")) { checkedThreads[i][1] = "2"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/MainWrapper.java b/test/hotspot/jtreg/vmTestbase/nsk/share/MainWrapper.java index c24ca5e813e..b84c975ffaa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/MainWrapper.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/MainWrapper.java @@ -47,7 +47,7 @@ public static void main(String[] args) throws Throwable { finalizableObject.registerCleanup(); // Some tests use this property to understand if virtual threads are used - System.setProperty("main.wrapper", wrapperName); + System.setProperty("test.thread.factory", wrapperName); Runnable task = () -> { try { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java index 3df8b11027d..0db3a6f718e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java @@ -163,7 +163,7 @@ private String[] makeJdbCmdLine (String classToExecute) { args.add(jdbExecPath.trim()); if (argumentHandler.isLaunchingConnector()) { - boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); if (vthreadMode) { /* Some tests need more carrier threads than the default provided. */ args.add("-R-Djdk.virtualThreadScheduler.parallelism=15"); @@ -230,8 +230,8 @@ private String[] makeJdbCmdLine (String classToExecute) { if (argumentHandler.verbose()) { cmdline += " -verbose"; } - if (System.getProperty("main.wrapper") != null) { - cmdline = MainWrapper.class.getName() + " " + System.getProperty("main.wrapper") + " " + cmdline; + if (System.getProperty("test.thread.factory") != null) { + cmdline = MainWrapper.class.getName() + " " + System.getProperty("test.thread.factory") + " " + cmdline; } connect.append(",main=" + cmdline.trim()); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java index 46a115bbb4c..8897d07459c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java @@ -708,8 +708,8 @@ private Map setupLaunchingConnector(LaunchingConnecto String cmdline = classToExecute + " " + ArgumentHandler.joinArguments(rawArgs, quote); - if(System.getProperty("main.wrapper") != null) { - cmdline = MainWrapper.class.getName() + " " + System.getProperty("main.wrapper") + " " + cmdline; + if (System.getProperty("test.thread.factory") != null) { + cmdline = MainWrapper.class.getName() + " " + System.getProperty("test.thread.factory") + " " + cmdline; } arg = (Connector.StringArgument) arguments.get("main"); @@ -749,7 +749,7 @@ private Map setupLaunchingConnector(LaunchingConnecto vmArgs = vmUserArgs; } - boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper")); + boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); if (vthreadMode) { /* Some tests need more carrier threads than the default provided. */ vmArgs += " -Djdk.virtualThreadScheduler.parallelism=15"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java index 81b15af1cac..dd6c8a1b82d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -251,7 +251,7 @@ public ThreadReference threadByNameOrThrow(String name) throws JDITestRuntimeExc if (thread.name().equals(name)) return thread; } - if ("Virtual".equals(System.getProperty("main.wrapper"))) { + if ("Virtual".equals(System.getProperty("test.thread.factory"))) { return null; } throw new JDITestRuntimeException("** Thread IS NOT found ** : " + name); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIThreadFactory.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIThreadFactory.java index 08b36dd55a1..4d8802ba1d2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIThreadFactory.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIThreadFactory.java @@ -31,7 +31,7 @@ public class JDIThreadFactory { - private static ThreadFactory threadFactory = "Virtual".equals(System.getProperty("main.wrapper")) + private static ThreadFactory threadFactory = "Virtual".equals(System.getProperty("test.thread.factory")) ? virtualThreadFactory() : platformThreadFactory(); public static Thread newThread(NamedTask task) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java index 79192149409..89a048a17cb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java @@ -350,9 +350,9 @@ public String[] makeCommandLineArgs(String classToExecute, String transportAddre args.add(jdwpArgs); - if(System.getProperty("main.wrapper") != null) { + if (System.getProperty("test.thread.factory") != null) { args.add(MainWrapper.class.getName()); - args.add(System.getProperty("main.wrapper")); + args.add(System.getProperty("test.thread.factory")); } if (classToExecute != null) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/runner/RunParams.java b/test/hotspot/jtreg/vmTestbase/nsk/share/runner/RunParams.java index a0bc096802c..e627816a6fc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/runner/RunParams.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/runner/RunParams.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, 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 @@ -225,7 +225,7 @@ else if (args[i].equals("-iterations")) iterations = Integer.parseInt(args[++i]); } // Allow to force using vthreads using wrapper property - if(System.getProperty("main.wrapper") != null && System.getProperty("main.wrapper").equals("Virtual")) { + if ("Virtual".equals(System.getProperty("test.thread.factory"))) { useVirtualThreads = true; } printConfig(System.out); diff --git a/test/jdk/com/sun/jdi/DebuggeeWrapper.java b/test/jdk/com/sun/jdi/DebuggeeWrapper.java index 4904e3a394d..58563fb225a 100644 --- a/test/jdk/com/sun/jdi/DebuggeeWrapper.java +++ b/test/jdk/com/sun/jdi/DebuggeeWrapper.java @@ -26,20 +26,20 @@ public class DebuggeeWrapper { - public static String PROPERTY_NAME = "main.wrapper"; + public static String PROPERTY_NAME = "test.thread.factory"; private static final String OLD_MAIN_THREAD_NAME = "old-m-a-i-n"; private static ThreadFactory threadFactory = r -> new Thread(r); - private static final String wrapperName = System.getProperty(PROPERTY_NAME); + private static final String testThreadFactoryName = System.getProperty(PROPERTY_NAME); - public static String getWrapperName() { - return wrapperName; + public static String getTestThreadFactoryName() { + return testThreadFactoryName; } public static boolean isVirtual() { - return "Virtual".equals(wrapperName); + return "Virtual".equals(testThreadFactoryName); } public static Thread newThread(Runnable task) { @@ -85,7 +85,7 @@ public static void main(String[] args) throws Throwable { tg.uncaughtThrowable.printStackTrace(System.out); System.exit(1); } - } else if (getWrapperName().equals("Kernel")) { + } else if (getTestThreadFactoryName().equals("Kernel")) { MainThreadGroup tg = new MainThreadGroup(); Thread t = new Thread(tg, () -> { try { diff --git a/test/jdk/com/sun/jdi/TestScaffold.java b/test/jdk/com/sun/jdi/TestScaffold.java index b4b30855acc..e410ae2c76d 100644 --- a/test/jdk/com/sun/jdi/TestScaffold.java +++ b/test/jdk/com/sun/jdi/TestScaffold.java @@ -512,7 +512,7 @@ private ArgInfo parseArgs(String args[]) { // argInfo.targetVMArgs : -Xss4M // The result with wrapper enabled: // argInfo.targetAppCommandLine : DebuggeeWrapper Frames2Targ - // argInfo.targetVMArgs : -Xss4M -Dmain.wrapper=Virtual + // argInfo.targetVMArgs : -Xss4M -Dtest.thread.factory=Virtual boolean classNameParsed = false; for (int i = 0; i < args.length; i++) { String arg = args[i].trim(); @@ -548,10 +548,10 @@ private ArgInfo parseArgs(String args[]) { } // Need to change args to run wrapper using command like 'DebuggeeWrapper ' - // and set property 'main.wrapper' so test could use DebuggeeWrapper.isVirtual() method - String mainWrapper = DebuggeeWrapper.getWrapperName(); - if (mainWrapper != null && !argInfo.targetAppCommandLine.isEmpty()) { - argInfo.targetVMArgs += "-D" + DebuggeeWrapper.PROPERTY_NAME + "=" + mainWrapper; + // and set property 'test.thread.factory' so test could use DebuggeeWrapper.isVirtual() method + String testThreadFactoryName = DebuggeeWrapper.getTestThreadFactoryName(); + if (testThreadFactoryName != null && !argInfo.targetAppCommandLine.isEmpty()) { + argInfo.targetVMArgs += "-D" + DebuggeeWrapper.PROPERTY_NAME + "=" + testThreadFactoryName; argInfo.targetAppCommandLine = DebuggeeWrapper.class.getName() + ' ' + argInfo.targetAppCommandLine; } else if ("true".equals(System.getProperty("test.enable.preview"))) { // the test specified @enablePreview. diff --git a/test/jtreg_test_thread_factory/src/share/classes/Virtual.java b/test/jtreg_test_thread_factory/src/share/classes/Virtual.java index 80b0b59fa1a..174e36bf65a 100644 --- a/test/jtreg_test_thread_factory/src/share/classes/Virtual.java +++ b/test/jtreg_test_thread_factory/src/share/classes/Virtual.java @@ -28,7 +28,7 @@ public class Virtual implements ThreadFactory { static { // This property is used by ProcessTools and some tests try { - System.setProperty("main.wrapper", "Virtual"); + System.setProperty("test.thread.factory", "Virtual"); } catch (Throwable t) { // might be thrown by security manager } diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 9423825048c..87bcfcdfd0f 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -33,7 +33,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; -import java.lang.Thread.State; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.Charset; @@ -378,14 +377,14 @@ public static long getProcessId() throws Exception { } /* - Convert arguments for tests running with virtual threads main wrapper - When test is executed with process wrapper the line is changed from + Convert arguments for tests running with virtual threads test thread factory. + When test is executed with test thread factory the line is changed from java to - java -Dmain.wrapper= jdk.test.lib.process.ProcessTools + java -Dtest.thread.factory= jdk.test.lib.process.ProcessTools */ - private static List addMainWrapperArgs(String mainWrapper, List command) { + private static List addTestThreadFactoryArgs(String testThreadFactoryName, List command) { final List unsupportedArgs = List.of( "-jar", "-cp", "-classpath", "--class-path", "--describe-module", "-d", @@ -398,9 +397,9 @@ private static List addMainWrapperArgs(String mainWrapper, List ArrayList args = new ArrayList<>(); boolean expectSecondArg = false; - boolean isWrapperClassAdded = false; + boolean isTestThreadFactoryAdded = false; for (String cmd : command) { - if (isWrapperClassAdded) { + if (isTestThreadFactoryAdded) { args.add(cmd); continue; } @@ -433,10 +432,10 @@ private static List addMainWrapperArgs(String mainWrapper, List } // Some tests might check property to understand // if virtual threads are tested - args.add("-Dmain.wrapper=" + mainWrapper); + args.add("-Dtest.thread.factory=" + testThreadFactoryName); args.add("jdk.test.lib.process.ProcessTools"); - args.add(mainWrapper); - isWrapperClassAdded = true; + args.add(testThreadFactoryName); + isTestThreadFactoryAdded = true; args.add(cmd); } return args; @@ -461,9 +460,9 @@ private static ProcessBuilder createJavaProcessBuilder(String... command) { args.add(System.getProperty("java.class.path")); } - String mainWrapper = System.getProperty("main.wrapper"); - if (mainWrapper != null) { - args.addAll(addMainWrapperArgs(mainWrapper, Arrays.asList(command))); + String testThreadFactoryName = System.getProperty("test.thread.factory"); + if (testThreadFactoryName != null) { + args.addAll(addTestThreadFactoryArgs(testThreadFactoryName, Arrays.asList(command))); } else { Collections.addAll(args, command); } @@ -913,10 +912,10 @@ private void waitForStreams() throws InterruptedException { public static final String OLD_MAIN_THREAD_NAME = "old-m-a-i-n"; - // ProcessTools as a wrapper + // ProcessTools as a wrapper for test execution // It executes method main in a separate virtual or platform thread public static void main(String[] args) throws Throwable { - String wrapper = args[0]; + String testThreadFactoryName = args[0]; String className = args[1]; String[] classArgs = new String[args.length - 2]; System.arraycopy(args, 2, classArgs, 0, args.length - 2); @@ -924,7 +923,7 @@ public static void main(String[] args) throws Throwable { Method mainMethod = c.getMethod("main", new Class[] { String[].class }); mainMethod.setAccessible(true); - if (wrapper.equals("Virtual")) { + if (testThreadFactoryName.equals("Virtual")) { // MainThreadGroup used just as a container for exceptions // when main is executed in virtual thread MainThreadGroup tg = new MainThreadGroup(); @@ -944,7 +943,7 @@ public static void main(String[] args) throws Throwable { if (tg.uncaughtThrowable != null) { throw tg.uncaughtThrowable; } - } else if (wrapper.equals("Kernel")) { + } else if (testThreadFactoryName.equals("Kernel")) { MainThreadGroup tg = new MainThreadGroup(); Thread t = new Thread(tg, () -> { try { From 40b1c4b3c8ecb6479c8244155d1c89dd87de214b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 5 Apr 2024 19:09:59 +0000 Subject: [PATCH 151/298] 8308453: Convert JKS test keystores in test/jdk/javax/net/ssl/etc to PKCS12 Backport-of: 1696603ccd43a279efa35d9f6617ce664bfdf504 --- .../ssl/SSLSession/ResumeTLS13withSNI.java | 22 +++++++----------- .../ssl/SSLSession/SSLCtxAccessToSessCtx.java | 6 ++--- .../ssl/SSLSession/SessionCacheSizeTests.java | 9 ++++--- .../ssl/SSLSession/SessionTimeOutTests.java | 6 ++--- test/jdk/javax/net/ssl/etc/keystore | Bin 6494 -> 8074 bytes test/jdk/javax/net/ssl/etc/truststore | Bin 2785 -> 3318 bytes test/jdk/javax/net/ssl/etc/unknown_keystore | Bin 2538 -> 3231 bytes .../sun/net/www/http/HttpClient/B8025710.java | 6 ++--- .../security/provider/X509Factory/BadPem.java | 10 ++++---- .../security/provider/X509Factory/BigCRL.java | 7 +++--- .../sun/security/ssl/GenSSLConfigs/main.java | 7 +++--- .../ssl/InputRecord/ClientHelloRead.java | 9 ++++--- .../ssl/SSLEngineImpl/TestBadDNForPeerCA.java | 8 +++---- .../SSLEngineImpl/TestBadDNForPeerCA12.java | 8 +++---- .../SSLSocketSSLEngineCloseInbound.java | 12 +++------- .../ssl/ServerHandshaker/GetPeerHost.java | 4 +++- .../ServerHandshaker/GetPeerHostServer.java | 8 +++---- .../ServerHandshaker/HelloExtensionsTest.java | 9 +++---- .../ssl/X509KeyManager/PreferredKey.java | 5 ++-- .../X509KeyManager/SelectOneKeyOutOfMany.java | 5 ++-- .../CertRequestOverflow.java | 8 +++---- .../X509TrustManagerImpl/CheckNullEntity.java | 5 ++-- .../X509ExtendedTMEnabled.java | 8 +++---- 23 files changed, 68 insertions(+), 94 deletions(-) diff --git a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java index 3e70af733fb..3d05607bd39 100644 --- a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java +++ b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -438,13 +438,11 @@ private static void checkResumedClientHelloSNI(ByteBuffer resCliHello) private static TrustManagerFactory makeTrustManagerFactory(String tsPath, char[] pass) throws GeneralSecurityException, IOException { TrustManagerFactory tmf; - KeyStore ts = KeyStore.getInstance("JKS"); - try (FileInputStream fsIn = new FileInputStream(tsPath)) { - ts.load(fsIn, pass); - tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ts); - } + KeyStore ts = KeyStore.getInstance(new File(tsPath), pass); + tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + return tmf; } @@ -463,13 +461,11 @@ private static TrustManagerFactory makeTrustManagerFactory(String tsPath, private static KeyManagerFactory makeKeyManagerFactory(String ksPath, char[] pass) throws GeneralSecurityException, IOException { KeyManagerFactory kmf; - KeyStore ks = KeyStore.getInstance("JKS"); - try (FileInputStream fsIn = new FileInputStream(ksPath)) { - ks.load(fsIn, pass); - kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, pass); - } + KeyStore ks = KeyStore.getInstance(new File(ksPath), pass); + kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, pass); + return kmf; } diff --git a/test/jdk/javax/net/ssl/SSLSession/SSLCtxAccessToSessCtx.java b/test/jdk/javax/net/ssl/SSLSession/SSLCtxAccessToSessCtx.java index 4e3b8e0b076..d50a30bcc3c 100644 --- a/test/jdk/javax/net/ssl/SSLSession/SSLCtxAccessToSessCtx.java +++ b/test/jdk/javax/net/ssl/SSLSession/SSLCtxAccessToSessCtx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -179,8 +179,8 @@ public static void main(String[] args) throws Exception { sslctx = SSLContext.getInstance("TLS"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), passwd.toCharArray()); + KeyStore ks = KeyStore.getInstance(new File(keyFilename), + passwd.toCharArray()); kmf.init(ks, passwd.toCharArray()); sslctx.init(kmf.getKeyManagers(), null, null); diff --git a/test/jdk/javax/net/ssl/SSLSession/SessionCacheSizeTests.java b/test/jdk/javax/net/ssl/SSLSession/SessionCacheSizeTests.java index bb61abb35d5..bd6891a3573 100644 --- a/test/jdk/javax/net/ssl/SSLSession/SessionCacheSizeTests.java +++ b/test/jdk/javax/net/ssl/SSLSession/SessionCacheSizeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -315,10 +315,9 @@ public static void main(String[] args) throws Exception { sslctx = SSLContext.getInstance("TLS"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - try (FileInputStream fis = new FileInputStream(keyFilename)) { - ks.load(fis, passwd.toCharArray()); - } + KeyStore ks = KeyStore.getInstance(new File(keyFilename), + passwd.toCharArray()); + kmf.init(ks, passwd.toCharArray()); sslctx.init(kmf.getKeyManagers(), null, null); sslssf = (SSLServerSocketFactory) sslctx.getServerSocketFactory(); diff --git a/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java b/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java index c44c12f6c59..18a31dd1dd1 100644 --- a/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java +++ b/test/jdk/javax/net/ssl/SSLSession/SessionTimeOutTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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,8 +342,8 @@ public static void main(String[] args) throws Exception { sslctx = SSLContext.getInstance("TLS"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), passwd.toCharArray()); + KeyStore ks = KeyStore.getInstance(new File(keyFilename), + passwd.toCharArray()); kmf.init(ks, passwd.toCharArray()); sslctx.init(kmf.getKeyManagers(), null, null); sslssf = (SSLServerSocketFactory) sslctx.getServerSocketFactory(); diff --git a/test/jdk/javax/net/ssl/etc/keystore b/test/jdk/javax/net/ssl/etc/keystore index fc5e1ce53bf9ca25a722fa0c45057e3996e20e7e..7e2a8d69a44e0d34c2b22b040addc31045b9a917 100644 GIT binary patch literal 8074 zcmbW6WmH_tx~`GNf@=f8T^7&{q;Yq5C%C)2I|P@;-Q9z`OK?koU_la~2@V0m$-eiF zz0Wy+)*5%zkE;4g#;CX6`8{*Y2@0c(LV!mEg;9c#(O9BnqwX=`QQ(WhD5(Kql;nTH zB%m;Ks{b*BjtdAw$NUpU1BD>~k0*Fb z0R+L__aGzd&Oj^cZKf5%AJgfZCtU~#j5rAJR3Hpw)c?C90vZw=h#VQsBuWIHqoF--ilFhl8Gs;xnPc8t$;8m5Mg-YhG>M1;aIStevA#IEKq$IzkG4-HD4Iqs6 z4=K2{!-UX*YeEIjftELZ#%42y%*XHg&+cXo6#tc__XLT{W+bY?aE1A``|RH=;HyDI;p^77~sm@Jq7@l1X2F` zy3h!~coaBr7I2<$j(>{ppO!nEDTw+%69~Zs06a}wM@uR&gpUWz&B@2h`Hqw8j|={n zHA4G9q1}IHj67&|?Jza{&ojX>F@`KWF%lm0@_%9scjQO=+wsxHfIO6DWxZkxfa;dP z{`-;Z^9*WTG87EoFZcAvd> z3F}P@fb_G#V{RL)d64WGjrU61W;*u0R~uLsMEjpp6M%^*2>zQamT=~9ZvRLcUe5nd zX?P&^1|AE7<#IhVZ=rP}w|HA@y#GX+5b~-iQW?CMvx%rl%R9|BfNIJ?7NDM?QKf<~ zAc_773jUpMl5FOB(l!D@3wNpr zSulbL)(E#c|A{!mseL>5m`m2zU<=-sosWKiFu+0K4{?ugcXh{c1zn?I=D`L z8fU_ZU8)9snMlCgf*Wod)UPz71&{p(+eCZ}_`LpGCaK|Sv|?n~_EX5`@2;{Bq4An) zOB@ZblI8ILvW}r?HDRh5d|brh$3=*C=FC^u{->)iaQVl#RUh^?NqIef#y00A-jU@_ zq~S}T<&Z6oN55!e7bOJgGO<2~VkM=jUSogOWb7_=UWj;k|LZ+w*z5`^yF@=A%=`=y zjp(+JujgToNq>Xm;*9{~=ca5y_{EUM{xH>4V3!&*iqZ`g^I!$nM5PRehzW5bqLmrj z;K^)`p5_gPm0>P#3p-d4-eSU(I>zl3k7Y=lG9Gt&$n6A`*^wcCNq4SnJ>? z#<7J?q=H+KgwGPv6Tar0KMZyeF#dc=HL)$mH*X(MJ5J>x`F5J`>QMW$pl_h9ner%v znewjoK)s1DCTDQ|K>1)ap+)Mn#n@^tdyCBCH>Ot1`iLxYcevsVHHV~Mw)#^W_ui1o zxhbQOEdHyf0%!#yE-u=ifUz5^nGfdiaY`43_Ljx5XFX#2H=LkIy4z!acOgFzc7sMn zFw{HMcjC*=ClZg?33#E}b#s5fKGHG=rj?1f*x6~ia5*uc$6~=Q7w^CA2yB!@x{D!l zTD2wZ?B~; zENbtaa&xD&-bX)t9?FrVwZd$;pTsCA&I}`mIMMqL_)e>l0$!#~HW{!Jy4HnSm)quJ zyD0XY$i4J@`U1jTM+8|KX}gHF+o%wNH(ep)HhNPpFVZkN4`aw&!L!soo-@1tv^&yUE1ug3^OEpyjDgzl4DL8g z2bDX?x6myl_z5Jo1i^>&sHt~%L9|Lj`lu)aywAml?yV1%YNz-@w7uH}ns`_tW2^K+ z77o4a$X5uN&7>cUL!cM(KT4D5F%J}-cn5?J#5KvoCFfxNl+anw`0T;lFe2oTvY$1O z!~H%d>0k^I2^vT|bFZfM#3xF|5{5{fiiC1e?z{OZM#(`Vr$(@L|1G0=`ly!q1^3Ta z`n)@a{*uR@Q`nXNMGB*-!wZXC=WgiJ4T;ba6k_BU-V= z3qwx*L>|vB8~bPC?-m|gU||r+e+etw;rlX8C_RZq^|s~$ z9Os?y+!plVf>lAR|6LFY3NpBV0sQ|^>JP;K)pmj7gnI`E`2%(E-%9k32NZ^X`R^T3 zkc-0b_y2^xBEZA_sn-890{?d$V>sdZO5Z-waNJ6$CWT^+J!4#|{7*!~J8=$3r$7R< zmCK)t^E|ACgyEa)uUAR31$ja>h$p3C(^**A7OxMnn>Vpe7mDw$GSSMgho!*kKhd`5 zW+9~lFixiZ(CakL*l4GBZQXK3tAoxbhuP}yA>wa)@lBZpy+ushn-U@tMw)tNKOXC( z;u7STI7^Jmlp=rsf?;mCTvS(S5eihn&l~lx=Iabazbl_gLJYD|gLA(|-se*fy;4u@ z7BL)|J1DG)Xe6BXXLqct(qu>Gal!p!IsY1cQD$u>X11R~YRqqRQt??#%!iZ7;Z?(# zyX0JGjrYTvhUz)N5yP@Qhs97A3{88_E0F=CieIjp_}&8F^27+S|5|6QCA09eyh4H@ z+(yc^*enLt;*MTSY3b~8Hdpz0p0JHx`)8la`HkF)^Qpn2qpokBv$L9~RIFviks+z4 zF%YYij`}lme|8D2BeCQj&EK55~oW|UTXH7GNs4Sw#uG`ymcNBVUboOY zRCYbn~bL3lNTdyJe9}Qq;e9?qv|1sL{#x-e{$Nj(tZMiyr;AI%%2bint%| zMAVd-pBq+b*?sZJAajBD#np9via-vBD#sqGLrJVoqN1=i1uy27pk6$;cZcZsC~(9M z+4_3&?G5bdxpC0=_@D;Aa>JoK$ag370R{8IgN%Repw&Q1ZoNIzC`ApAfE6bh3)9d# zXFoW#14x20BsHD;SaKk_b@sz+$cyFrQ>Tcl5}_-(twef}v9$ClF4(J^=&Kex`8P14 zG;)hr#8<+BrX{iDuB9u=jRoNh#HPzQQK6}_R$T4tDh9V8l3Wx-=#rDQteqgfJvwFF zD>^-*b(n?PS)rkR>aVBm-mgCo;#EH|MMb~VsJWGCNBH{@LQs$paW#%;DC;xKup?N6 zz{FEtSQl}4ZG|y`7>=9tD+l`qu}JszD|Kq2(WI4jP8;H1Dla3pDC!$iT6ExBRFx*< zZxsA@l}Q*_1frfj6+EKDPv<#KIGMP*O#MBZJ;r^eTuH+(PUo%#LuqwJ;o~PyN;&8- zN^wgZ-cnU-!+hQrD9(OFc9c!fF0qUaebFxX0^(h3H@+6lgB~&6s`xf;+f>;?vi6Wf zO31#EFG=9@*Sd(Xb1QYaIE0!qiM6!RCa$c@D-DJhC1(R!#oQUyBftMjuRwHkja_$+ zK#=crp*I`HP9vhnK;LPoYBksFBsKVGV-6R77H#;#5^!Il8lYSg8u3Pvm@&+LUky`ZjTjOx?S^E}2Xclsg`rPG(`q4>&~1R}R|zoY#eX4KL3Q5u#1 zOmCpYP$6xS*Tk20@WJdv8c-UHz7K+-^8o#BU+Hl?*CF|iqDc&>1Y+34)0^rJ5CnuGS^X+xPdlIX*x z(-Ep=3)a&wtc_n7#F%X=g3i9U6qG^`+s%=(QN#{fx&xK2+_ zP3(!IP^#T4#{!9f@&P9O9x~6Y&a$JbuOne|9g>(=UX?52c)^SrOy5i*TiTdz38s9@ zGpnM-aSlH-I9G$ABcy#|yR8|4P|!+U_MeCI4o6^>yrqBC1aS=S#?Ha=wn~Kms62W) zIN&@5Q*nhmvQu)>*S%3U-tBQAy3A(H%?uo*J_F@LJ72%M`he5FpFP0TKW(w~FsxKn8>H(>k9ycny18m-UY?zvKE0UME0Ky^*&aAIXHbfht*De#4bqmy!xcjdkM!vL?q5ZxPrIKbb@z% z*|AMc;ZyTBBUJI)xG8;cmIRWXDvZE0O_oyw9Lk~1#LTRO7q$hf@?M;a{^Pb`6;$xq zR+H`W?~`vrEGp++2p&~Bx6@?$PfcCRbPRak7p^s}F$#ZeS5XA-gfy2GhIdog+v1M= z(4q%DpdxtsVS!^Fa8!LLM!$zmGn^@~-9DDst;S~7VntI|NXzziemUNEZ&NZ(vW)ew z?to?bFQMLDbJ`XMy-RibT|n3KHFyZz;Cb_K+30!lXZ{amg2tN{)Gr#;BN zO3bOf`rb8Qc|vq|2~%Rml6Z{?*{%m}fm0msaM79bCIIZSNYF!0v<}mynHXl@6{;+$ zr<1;$m%oiGGRd1OHuL)aiZb#AN7ua{&^B{=MM2mZ+;>D>u4rqNkhb8}3-wJmzUe9Z zs14MpEK8;f`$c=;q?2zJEAbI@a~J1oUQW_M=HwIB;G*x476CEH8ZRkF9FK1lf zfb^80RYkw%=-Wtg+lIHf>HuGRQnOV3w+}n1pB6U|Y0|!C1j12oo>0mlU}H7yubh{e zQc!wNty$8Ee-CrL`Mlf4?_5;o?OiH)&8j9Y@&3?2CzJKF_!g=AR;%b5_f7%6D**|0 zR3(%>m0sS8Xb|3VyPs=+Lpw<>-u<=?9TiBuQ`+d=c;#7P6Idc&d%l4l<=6KkSA|Si zS)6hF)0IcdfEw!4qJDSH=uX?cU|Y?Ha|Cs&D~>dq1UY97e$;1GB2(Q%7fe23{kk4- zV4uRv;$OX=WnW@}FRoja>pYlPV@XJZVR>R^8Q7}JNy4pRU(Hb_AHaPwpWTZSz}22x zKknfgj`hp?#Nl}RMrH+VKj9*HoX@@}aSju2BziDV_QWo)5)4QiNe}d~)&s^=9)nb1 zZj-!eMXBvmxCdF}_D$dIf%cwO`G_jdHrwH%B$wm5uz>@ODID)yi#rFW;Ql^JBY!r% z-?MHZ>2iTCjeFB6stPnVXIlFvN}ew=7d4$)h>8-Zfp$+)Gl(;kelUo0^liY3#(j9O zSl)}yDTl?4NZ=;*rYMjyPu*h2S@9xAGEGsGX%+}cF1N9I1bYKI->f;vZX&dvUTT+i)4+fX@QaA zQv>d?$X4M)Ux@bdczL-VP0nHG5kO281Iv<*EqS13<9W4))M<{+=DqVLh7~MG zW8$%}xub2qxtx|i3YLlC_H8a>j>jg6yFhDIGS?Z3e+ZkeSd+}Wl39GS+gtFjx+sl} zSY7pKyo8vPU6$!^b_r)9npRB*Ztp$dMo>yl|q zq0Y6PLMQ`$Y)~kS5OKI~!1y8iMn^;PRj5spTNy@%bz3pDILrz!aQSh%;8f0#_yHXM zCaK(U>wVZKTWW~c)o(Z0zUqDa>6mBQ*J8^~z%w#(NG^-@LEt@qmPEIM1s*4_jGGq++Qp~7PiyXQy;lQV(~JKONMHs1WS!IPdMB&&Pv~?m5tyRDAB(t zblu~JkP`7kCJ~Q$*z$Kr-U6!}<{Hqfs&l%me<9#B748IlSb(QDrH7A8eszA~ZrgM$ zA1>p6mJaJFrqwR~U9UTk%TZ(SvBN2np_EY{A%Nn1%gBG@qQ4!&knBy2uo?M4nTRV? zoooc(uRp1?pwvo@g_?B@?WAcVl2%MyMsm6#Yjni0hS*M_U@B1Cs|c3`u#ub( zd-G>J1^;=E#s>h;Bulh*K=$+-&R+3~BB2HwB>Aj`LM^=%qL{|em9Z)RZDfhNHC>|JG=U=%Sl^{3y`h_B(^ti^BjP@#>t@-hh7^8apv=H)K-%sI!{NdlTaM;sq{7sXNtb zhhbk*x)!Gou#k%};wUl7IR)G}-K@L^z6^SmW|&WMt~Yd8Fcms3mh|UrU3B@Y#~AAo zN7X##Ou!DGBG4~F(T-CS663kP>++4C$Y*`89n%{-_=iKYrxBXr$}oD6T4zWY|4LisYL zl(&&a1g{7rZad=1&g5^`w-r#Wl5qHJXk-LJFt@dSlTT+HAcU;nhh71&j5KB(01{#6 z>Qr{+0XU+#NP!BGo2?$(q_a0;Q_P~8!FBeO_fBff-dM%##pGuM?(b836b!tf55yBd z+4|R#?g)j8gu1oQ;MiLY>}P6g2lhwYNuenieHAXQ2_2PR&sHsHjB;PBrDA`@X=-?SFYlOMg$_wexUT*fB5Daks%v;~&AAe&j}7NC+B6fo9>EkgM^0+1)fphy1UX745tEP>0S|y~|nnfRTV};l|rie62 zH&v600)`^2hHcavHZSv6A2(;T*9zibNR5z^8jRB{LiLp4P*Kk>Fy2V*>8{r-reF2xbuXj{^9-PX4B*+WOGDlii5S_tJf~-KJ9flkGF8 z_V3wG(1<^6j7Ct?$$f zF&1T)iAWWC?#90M!KiQ+&Jbk2TM=!^pgq}At9+oYx9`_tm_c9fsXCHx+##fN^p-c{ z_mFeKo6%^@Ez#{A5e(yU))HMl;QI^f!s;eO z$YV)F3%{oEIY-|y2Or0XZk2-LHIj6LfQ^sHRNy@1vT-N8uRk_AJ;eA@i6e|_0J(XN z^UfA0bThM7n80u9ib_?A9n#1qz$LsaY!(yytg2Kn#xl{;+o9psm-F651EaHw5YgGH zu*!Y6f!=ZtX$8e?$AI$9N$RLJ0^QGAS$0}~Ki%{@g4L~#Nk5|Bj~+U?Zmw+E*K8k! zq1&_GnHKTD07hVkR7f3p*O{)?A;&1^d9ZK3FTDn2buanSF{LPa1j@fZ^p&gHhsh$3 zHVJFLrtvbop;mVuWt!*-&EB9!n5TR1R^!L)dp((cs$Q1;VNQ?|2n@pf_y1`GcqBLg z)m?sx^1hz%iJ1*~wP`22fgcE1$WIJ5q=yz_*$*M&0SMX~%2%&-X^Ax@Ke{6iPC6gJ Lg1-Fg6W@OU>?NZZ literal 6494 zcmeHLWmJ@F+nu7jyCozah6X8-MhQVeRE7rWl#~Gkq(MbO1nCx#P625UkWxAaP!W(& z7=&*yzU4XRJ%7Hn-t+xAKkhYaKhONQp8MYW+WWpvHcvJ|AP@wzurLb@!nO2tbo8-w zM__=t2UH~j^BV^QgQEaqYzEpQbn>6l8kxz z?qGiVOQqGhDM6^~f`yN-3i+;?)9eJ!^bKnX39op=nfc?4T*G)(1NEPVdohA;4tvJf zA{k3=OfjAs)_B*4#Cn(Ps=o4jDlBx&Pxx34J8$z`ZLOKtvXEHUNtGAX%w|@lBU?La zL=A7+Pfta#)VmMDrP=DJtR~*f8&+lF3?p5;!P}MUB*`^`8-+))C)lI3MYGeMFYi8;?rq0+s);Du zqet5so36qb>o z7$5}#K_!7;s3;H&+0KMQzz_%we)--uK!lBF7N!Qag2JE>ED&HXOaS0vLk(cq6cB@} zzW^=;L`hMY93VY=gF}I* z(CQAt(Z#_^(8AdfV5T7wmIOrLQg9JKTtw7_h6sKJC4a(yw3c9SErz@N*f_jlYOf_> zU<_b^Ad#SNcdsIuJju`N&1*an{J64qKvt`FVe1m8gIPYPMwiP@`Gx|!F4|Z&#^|WE zbH4#N=ub0nm_*71F^M{Vwl=H1ouZSQlaa9w^CM+%*KRDFJgMzs_$p(#)>V*4MFK;I z9E^4{cR zQlJ}uzaV6O(PT9PJ2A@oW{{r&rzKcR=442n7m5r8L6AX2t0sq*OCjHi5UK~4E2qC6 zp9Jt$$xl4!_h+wmv2XiAjG)rk(MOlOVsRN8<(tPPRO8wZY9JGpqXFJ&!gpf)A!E$W zU2F&D8DjBzGy+9Hx)w(*a}zqqjokPYTMN~9)qF737H;^$A(DyL+)*Hc0CtG>G*x+( z{@Q*mlJ{*k8^8iEVMxYA45Nlo&bY~xB)F5OOj~s5SWZu=3|bc_{E6gHArQb1p#;Jx z*eTx})()1bj+kHd=y49-uZK_y1#!1;+u`tdsD>|=IFu}*KkPsIE+hQ!1h%qp`_b`Q zXk&UX&+h^Of9ZF(-Q>jf_sWc0OD)Ep+&XwfK>NjhDOdS4?YLu3|Eq8kMfj*bW!_rM zT@yRm5x#W7^K%}=jRNO^|7eUBEUc18& zvi2g0{`m4i^%_YiJsW}RAf^Ne=$FDFgBW%9VyIj3Q{m16EJbG@k0Eu~7a}m2;O`Yq z_`AXh|AWE_|D^C=_?N;7|5o9m!Xkhq91s)xp>R=Q_)qwcD%=>L_@QoD2pAjpOy;ss zFb?!02nKH$Opu_jBgO9H@_gI!=An;>4>x{e>H)2`r34ZAEF1f!6l)m#0eH?|I*{8S z)0k``LUnmTgDP;P`X19)%fRf5fC9jB#y}1jEkGSa=?`BFuew+!lF&I{)TT7PZ$4i9 zb;oO8ry%I9N|FZ z_8FI=y09{#BICS&ntyM9!QQ zsSYuDi77bIsdgwTY5psdn>E`{T1!_hkGZ%zDBEDOPM`AJ;S#oj)6#j5SA43LucMN_ zJm(0PQWt!6E${uFuCW(kB$cRh*|8;ibS&dxnhWH2QR|ITE{Z zx?3Hcc~ul#$P+rr5vX|Rjc$23?T&JCp6-A5MZ|?ir^)i2&u}Wps8-C}P<5Ze_rqz+ zWK(pyQAOJu4S}5D6U#Z=<_qVa`=L1m%bmg(zJADW#X$qv5GWV~{(Xlq{qMW7jH$Bj zSIzIMC_M5#d6$9&I*7&NujuBa`H>I4$fgga%XS?Bq)2ktNSO?y4M?S-VVhiIk3((= zCf@gQw__2(Rb^d&F zSs)^-bzMp~{87^ZFei~3nnKRb;)~TRWt(b}glKXTzOL;Dfo z_3P=RY%p%(5BUDY&};)D&fT%unIE^H;I#k5waR=h_L(u?@OCq(x4AjI0q6Ao9U>n( zN}V!laVZZ8-H>EnM2f<|oF3QaC@eNq98JE#8$973n%o8WUWw4Vp)wYmwp`?@$k4j% z6-ggOUU|WS#JzSaqGRN{(f)EXa2tlm&6s6=rurvL0RGRmjY+EisLalC>MxB;0m8pa z{tW)3wOqqw@b4M*%*C+ykT4MbnT4rBS!E8VRNO+no=&&A6Xi6O@5ZvM=-`MxSiX>5 z9c+)Yzv{^eo)L<{K}sr;h^sUE6{J)4G%(mcudvRO0!yzc!*qj!oEeX)CZv&@is#V*c`|uUceO5h&Kqtw{=igij=D`v>(S8yaD- z!#(|G`-~sw`8_ycZio8yw8{aP>mw8hhMoR}WWlfxk-H|l)6ByzZrX>Bc7#n&$26?c z5)Lz*CFdA2d|wxsg$ccwRk1NzH%-b^~+wivP;$S>_xZda0S+bc{O%Et!qO@s=Jjk`t?9EVFV4A} zl8v++i#(rvc&#R1KIq{z&>|y}uYS<;o`fXll$`xdqGz$d{i*&-ao!TyX&MKw9@H~; zn(6dSGp|YvCkeBIhnHqZW-BUiTaC^IJK(rS?xZ^ktP6T{n@W34gz6!$Ms_(hll201RSf1n{X!MRz1Lx|pzY&;urAQpZcEOQQa99M^>tY0 zt*7_%3^)(#kYR-{N^FjPmfkw#6zUX5;7=nr=jA)`;0Dm^lUKDPWV9yXBT_i>bCn9$zQh3 zi4T5#YCBGbbhrO1+VW7Wv!F^vkJRPn6oF#{Z>F&p|_V&+O`U3tDyx-QEtn5~hOMZ$lG3~gtm)AjM+eEV;{{lDj1Vk-+wv~{<#aDj`7y9r|gh=tgQ&k;s>fq?&C;)ngG z8J}q7rk2qmdp496{|Wyt?EY5<#D71s ziQykQdN8ah7nR@*-kcd^V4&{cu2~v;>SrryRm2Y_k!v4VK)?vEx|`IiyrLf}5AK6B z=8GhMNGxU{8#E|9{?pKqV8DS@s3k}g#gp&(LdkPkdpcL~k7w{J6gNLf>Z)HrYg{bm zLd5frNG2P#EkiVv|i6pWXr1B+*F(boiSM)eBN2-e*nyu&^!PD diff --git a/test/jdk/javax/net/ssl/etc/truststore b/test/jdk/javax/net/ssl/etc/truststore index 0ab0702512e3320be3344d54cbea352257ab3c5e..5e08b3b456604250bf266409ce701932883f122e 100644 GIT binary patch literal 3318 zcmVivf(-Hk0Ru3C44eiDDuzgg_YDCD0ic2mjRb-Wi7&LNQU+thDZTr0|Wso1Q1MNI^J^!=7z4+q!g*NCZd3X3-H~?ByuR~s#3%Gg0jhFiCMf7 zIJ)^DrOGIqI2R}BH#P_k9`N%)ajl-ZgX{BKCa>tGA*#@#gz}P4NR~vq?#tn=QT@cA z#XHa@g2CaWNVSF4wkoH6^BZH)C_l(I&1;4q(|aq&EA zAq~D>m3LdSuwO}Us$gwI6+9-K9`deOQsz0R{FoFc<#NQ%-`)ycqnhTE@2cHW>4i#2 zp$s_PcOJTfl#gHBr9Rk)4J6|uBZ0GN@I)V~9-+BDa;+$K)z>zUJ25Wg-cnLZH6~@a zq)tDe`T0%I(vE;um5rOA1m9%iCV7vA;EsR2@0sg(P1NFo|;boSHA7Ou>VzBGj?5> zk7MwvGZpayCmU*TPSuEzP?rA8c0;4TFT|40yYH)6Yz;l=Q9hkE?>mi2%8nM|r0e>k z3iK$1G#LX`xaF9`wX?HQY6pTOO1mH8bc@fgqJG;T(_9Z8Zy8GEc&uPuYCB#(mryol z7V=EnxA^-YG!aJQkK)TyQxnZ`6^ZBQL|7smy#i;Gj|v6QefZ4C9b#>|%X>^?yDJn} zF>XZG7>Y5WONaF#Mz=djT)Jy3`2#QdWN6vPGi$z}u+ifcBJ9u=qJI=xz0h^9YUDu8 zqdsHR+q7486_e#KSGG@`c9fP#DaL6zhCn3wj>gQ~EMlTCw;)FReqF_cTRt%SR{T<& z;+Z21{ai60WCS(CFZV37bk5;r)&&I$9_K2=!g@Ez6S&#RQ1+BA$2gO zj7OO=I+e=Lgi5j#dji$i!kM-k854ZvFlZc`rf6xlsgGy%V}Hqysnva`&bDy-c5)SD zD?ukNMfH@G$;LIM+g>MljDY+!%A0J4e{KP|^XEH_2FYT~-Gw2f?<`Eo&;xxP_>0x@|;L;?7zZtYbFp zK`ZW13{534P#Kpy9sNU3U-Jc>>4uka$RuECCi57pEN*7OrTZ=>gYCf9H*7m$&sTM* zmYXSCefp4wjKSM}PG#(m7yuc+&i6Z8ln8$#{EVJy*j`gQW#64BQ?U~mObKmjo~~ce z-D@M%`=hxsXTd#o4^+(hd<@)u zmNo^;VUMN)L+|f9CXZVvi>;)#4XpyTq1h!#7xzA9zM%s>!4A{^u7_COshxos9eVn~ zH(gI+jo~*5KAf)WI+zZ4gJiwt%zWMe6QPUI+RV~L!dCK7nY8hZRqtq1C4me()qhBr z-qE3B{!+J+?G+fXlb^?cb>pLcCXPO=hqqlc(Q)e_4JQPT=An>iV8#Yia{Pf+T^jRg zxODmYpHyyqw&^tU9U_U}19g`nmDQ1s;;=So5RJ>V-XNm;9+DDN?Zh_0vz47b!t&gB0Sd(BaSWLqOE* z%=fR9&MLNIq3k7NKHCa;-wAKyG%||yE7*ZjeA`n5L}a!tPQCCUE0;sW_PdOv;cC5} zqiR)7q>V5C@zEC;kV}CFj<)c!I*4fb-MG6^863la`PnV1Y7kgaBs&v8!CEt} zxxFhS(0KoWmXmR5zRTM&0jkt%GH-@82P_e55*`T!*2SNdqt>r@vNEEZj^tz$>EuV(g^%l_^o z9j6I#$A?I6W*M8aY=!|-)ge=wC%zW{4hbFRg*W=H4y5x5^K=z-TlZztOT!uVp@;f<|z1a zb|`=`ZCuRE5L2%L0o$5hE5YZYL}kQl^SCm=h`U7d+b{zBd*AfPd7hDqB!d^QE==#b z;>vY5tqaZ+Q?gtHIRzHXrRXLjm2=O#g|yi zkfVKX$k1#n4x@e42R2A-7V7r?cOKSxviW)*)fsE17ts?cbI%`HemSEPi_~NqMcB|n zdAW}+olBco1H9=!sBj+;(|F{OkEkmuFePdIHaZ~&nMxr8^~94~z^P4I5#n^c zQa}_%mJL)C5G9a*5GgK24KiY`sb?nMedRd#0_bO5toL35!*)P_05i%T2eI8t)ZxD` z?GBV4VCYQhLWmuCr3i5@CImC{i8QJQ@Nh3O{Q}t#*~Pcy-fwNdF5R*!bPFpjQbX1L z%v}8HVV57zxJ_9{2V}q0dz+`f)n1x&cf08b5bP^(nVuX--i-YIjJ_sL&4lg?DMFUY z$gIt~s^@5axz_C9lR}gEq zT9NP?sW}h00;uiMe(Ch{vKn;ZFL9HF+yt!_{feMCYvT((ZbjGPeUbFrc0p{g3%~|p zy}*3UFz#^oFy9{T#=NCnXB;W|G8rIzT=5}yT=%Sxh`P~q(yGgf^#dA z7dy!@uBVrP6hbyr2ywL8Xc5R|5H1@$zBC-1(uEdz{j!6`?JhyD8zR~(aAg#z7L zLA;&hBRJ7+ca8SZ?L!(6&m@{-dM7bK%ld>{CI=d~sh=KWz$v%=2@-+{idbD6^J5s`-F8&=H_W|Lmi4=6(s)AlwZIs~>| znopXqGdd6kr|-;a@kkWjWUc6k&{PXWLG|f~ZfR44jxpLTfnPpjNiUvqg}+c#7mN8_uf!Urp{h!&`U58eQcci`aC(sRR>Umj4)uA`!Ygq@fgw@ zy$jlH%5vkLu1@<4hUpE{8#dX!Uu!T;FflL<1_@w>NC9O71OfpC00ba79W9r9xI7Ra zbyX-bkh_~jvIqw456&j(DzLLX{!AVO6kg;U*%884%rD;IXHt$#*lL7)K5ZIzO}ivIRF44 zQv;fX_$A05%2ylo8B8>B9_Y{t5~LAqY)yPML>AFarLm z_Fy0ije__9I211g3t&)QXbcYW@>m!AILO8tFA0lt-(Yb9HnG&esF;w5NW3U4%zY+^ zUbqO1ts2-YJQ6ZBxBp1z-~2!Sh& zKFY5;3j<`r3{V?`)l9X&Z-fRBp#;(Cz+Wdk=nAotyWGbdFYCOXoL-b*x|_Y(3v?-3 z(i+{=L-u`VrRv7A1sgh8KGayuya*rZffp$hSfM%6x2mYEg#-5BT}T?p z^>;lhttQl0pVP!Bo=p~-_u0ngj<)ptO3LE`^Jl%SRR@Xx_HH_U{(8%b$$uEj-cCa1 zSjG`IU+*)`L%uFkN3r5`+D!+UqiQow8ZtQM0|7!tPx*5*nYeV%giMX`k{U&=8|AUt z5hW*tR#Xhg3mkGBxZSj`bfLY{E$dWe(%5sqmqnPI^q@nuc&{B4(8+Y|frBQBo(w>A zn#fDPWy(a-U)M->i_Z0|_p57(nl~*UpX*IfZJ>sBE{T$)9Tz+~)wh+XLyxq^_=WA& zU+FeW=v&CbBl`&pnF-L4Vq~|?TM`m$viPdK{IGIBrhEI!*1_V)i0JI%S*>w4- zZB+6PKe0NZMM_(1-Mcrg)5dz|BvKe|ols7V$jh<9UoUCt|Oe-zR%fE=Y6kN19WQ zYi~gsH&2MYsY@atD71NLesPD1dPW-^=E|??FauQGxC)RDKruiu0O3FoVt^p^zssSL*{0f}=i{_1<2LpQ@u5=Fu93D!y}R@A-3tGPA`w-)W^( zrTSpw5!Z<|c66#&2zAQ3%hURN=If`ETS5ZEF@wM8?|I^TR6b?ZYrAXMl>1a2BO>wJ zYP==$Fud1x0_}Fla0el0ibc&y@h3^IXqfbzwf8|a1{o>6opiRA4@s}vB|D&r6D;_d zp0UH{kL_)zF)ggS4xB3<`ruWKLHkXdiCPDD?ZNVI z@UDMEIu!SOVC86nrA`m|YRs6h^L%3ewqtp7`|rxVlar647_-&4Mh+AYzIkFeT2(Sc z-9lJ3bq%T*YpeN@RNOIR?3Q++brF7Mn4g>{sj3vm*Jd1??^lee#O1crF%@=ohObDe zp*z(Qe)m_7InztDKE=ej%Ur#%U4O>#-Yfg=OUIKIsu737+D%2OI ztlLi0pVFv^yZB~~0i#Pkoi8BAeU?CBD0Xsd zxE0dDJq0SHtULv>GFIz{;NV5J3F&au>zO#(Qc7Ql5^3THb@lfo`Fin&8Rz-5Wm!A2r6oLr?%>|(wSP;5`CH|d&Be9m) zGrzA0tTY`ekHx`i@#n)Z%?T@`#o*htttwb36e`XJg$QC1^hf?X5y}V$u>AClc98}U zCm0<>ijEBgvk;E+Wv7R_Y1TZb$PGFW8rC|EkyK>1 zj_1oo=3est+-aqVccXR1ocT7EcS&-iCIA_00(!P02rJ;{U z9fnirt&;>|6vL0E%h=4!o0=0lC+xa^jO&yJDb48cf6qAdbo-+jV(v$t*rWyCGxE`O z3JSRWI>c~$fL>^Iv;Ikyf)-m3o>?K#YO48NoR;@!L%9bUVh;3@(?~UpF>-n7J!f0e zEL?TX3;HFfM}{^(eURF%yg7IiDUv%u*H7XAv%fw*mXqOi@)WK~Q9_2MI!H_a5ctqD!74>UF& z$rx9?ng=W?x3L)}xfBe*iQafov4CjO{-uG@w3Eo8;*V^`9ke*k8-fujcnbGa*I{zm zo5GWnt7P{qv{rk=5?>ShY{aJOT97Bi;fm1gEer-#7II-P(JO0P2hE!u+?T0;Sg5Hq zjaumpu(R9L>%Le`W%$O@vYrj|Od3CFj9={Ex|yQy8gIpFl@n#PW^8j?S=xk1D0r#g zeUX?o>>8T>okf2EQSy*+>LF{N7N27#O@dBdXin6RHPrO^5yCKtIjH>Bz_M?BjO2qK zcGgfk4Gl2W>0`R~s$(au;2XMCW-JFTp31gUKdSGF64(r;g;f>GYW)f6UnO8f$+8Ks z08W5EKma@dFTfpe!V3Mixnxmv9A+*aPJ*%uctu&9JQk;b#VP*k4Ez5T3DS-QAHf-fo%?;l0^&EWdccUj!SmHthUWZs4tJ*IMmP-sTsE(Vg<=|IS(ufXMW*@V_p zGh)vks4<`)3nzbwesQz)B_NjhOo988-VtGZ-_xK)*skypirYANFOwytZCKqwp0oOR z<*TUV$J{5{HJ56lMLiz}S4}F7^bK^xg#?&zrn@8_T6~D2A-8juGhKOSIOGgowwl*# z5}#`qt2pRVVIKOIX=6TYQ%Ed6o!MZ3r$GVv}b&IVbSIm4) z@XtAFBp1i7I*2!l)+YL1&N-pYY{wNe#F)c){oG*RC(tg6bs^h2tYWLU_C`Bw;+uME z?^E)NnQGPCG#YlKZmjD(l@{o#bXYWp+&12jj`h8+af>@aWd(o7bX09RJ_aL%7^^Qg8z0-N%Jh^Jcw=;vBNlv^L$liJ< zHiw*D=pEy6PSCY&QX}nj&7!Ot7XAC>QL+dDre8<|0B*nV2>2%`WU*(kAbr)}c?SAi zke>WY%7H?FUq{Ao2l7vl%rg(!rRyPWg@aZj4cmziBpl^j;}Fj- zS`{HE#dNX#DLnLou)(aaRLX%E?btUPP{`L~#VCs>&ZP!9QkcbDq_)sQX?tpM$M2&> zo3fL2Z}IUBXV^lNz0O!kx3e;8Chy(2h%G0&g%}h5Edpr})(J0ZTaJzt(I~Zj!r*6> zBt(|(YtTxf-CoJ~;+&4&24L0X&n;PDd)?DH@3psnoEqK$mJB6eEv{_?!$Myka=^$R z66d+}UuVZZ=*~Hju6e~GwGp9`EdK-8txNMu_kZ>khU9S z6HDwUVS&*!Q!*1Z>yv_Lyvlo&T9x(J#WA4z?7V)CDcKBD}8GxdKn_ zQ3<~GPxFc=Vpj`Xc(0**`4CWP8Ph)|`~))6#Ql6#;f9nW^pHerHpUiN&8guiaf^4-2+l&EHro8HOlGvBmyTB9r6P(Y2QkF z+hOj0RofiGPOz7jA3L7_-UTvzmQA!RleemK(UUezp7nmpwUF#;V|#EhR^DV!h2$Al z8^-B0&-x?sQVzkEr!yIar$5Th?JJR%Q|jFb_S6p1ePB%;!uU2BscH>2nTmccXXAaV z4!&0f^%>4f$wloh_7K808v?h`I`+Z(>4)&$^JVn<-)&@(6IE?*<|_C+2xoUbYOxNH z#-;6FFp<+^=-;(0wZe>M7`jGkMvsiB+&i#Y2u*aDmR58r2^6}-WJ4D2)Q=!0W0Xs0 z)65E3oxt4HjXD_fP;*@_pH7Oj+2F(qJyf7*3%(>zL!|~vd z#;AHrMR(=?n=QKggS&WSymn>pI`Z7I(58vfx*s4ZV6$)Cw2aA>k4V5Zt`}SlUl&#C zP*3hWLyBx>6F%6_ih$Rf$PY|;cPDf}NPSDf6J2Y>tAQZ)jgHij^d{aZ z^sJhR19H}eas#_Uv#OP8iR>rc@5cj$nGPx9Ph8Cou+7OI9UEv;Ck}l44<)NmObFXv z&%=Cmu`i)^gC0}(3i7+7#cyV|D|~;J=MPvfH1||8AoXIu23fv;knwR~H$BjT$QRv#8VIp%gW*^=!c2 zOxV}ZlDaas%jyG;?!sk)k&?u1XS0QT>-hPO&q2$Bf+8LP17A|GFUO&e#9kUZ@))Py zAZ9)L@zLLdNEHc>LB;q)40*TulFKAyzxjrPRal?g#f!St3fDGg_8g++a;fOjLnu6#n{qNt#T;uWEU*ugCe`Y)9P zwxw6(%7j>U{ltUDp1MCyos&W4vt}gei8`r&5;;>+kbsqh9gL702D-d{X36*KmlpUiK_uFF6H(qb7 zgkN|ldsZQS^XSd~)54p2s1$l?Iy&4lL?9qu)J!E8+p?i`Q8}B1%X`W?gu>}D#B{QJ zUGveHSxx?~URbMwoux3>6NHOH>54@;^+|NrdU#sk(Mx(Bk}}kHZHq-&g!8YixJxWk z5=NS4)gqOh{4Lc3`Hy2SU}dq$zd!9z2ppgjT;G{(;Lg8Bbz%^)`}%qxBzR=Xxfm`N m+wwgC;wG~l=ung=>bMs)wY<&fCZ-o(ECtpT{2u+eqW%NJIIW}r literal 2538 zcmchXX*d*W8^>og7_y8Ri8w~GO=HHEeJ4fseLDzQ#!{JVy%=k@m?4U!*On!F_7Yh; zlEah-avbFTNx`E))!*Y*7G`~L91ujl`J=%4AI0RRB##{mLh9wDxN zfdmf#0LZ1$pux-Nwc?^djkse>tWr!s2v8El1q4C?kZ4fB@_X`?$=*jqe=lUTaQz(G z;;_N9qBDH^MCe&Z=~_vLSb&1M^*(m!z_pWmo~*gpUTNs%BSvrxT9!yTd;kkrH#V0L zvzK(UA=I0X&rV*jOJyxnTTjoo2%;vHVi59$FKsW!YJD7bmxJ~zLqg5iYT8^wtHUeH zYRaKQ`2rH*(*5lqQn?|Z8Eb&QRZ!hgcrJRVkTRohSD6nnz`-r%yt_6=_t>0}6&WqV? zbSWL-Ow%Y>pB=BVm70JlHJzhrD|zybE-bx>|vt!s&x`={a+$06NUU*;~ftKOY4?tqfK* z`z-N+z(4@-ul5)Z17`Sg7#Dp*%UJ9K9ySs}Hf8IV zS9?|8jTzK?T{xP)p0%eNn~C8U41%RGd-Tc-86{+YP4C!ws^U{N>>xjK8} z`VJ#nX^b!>|NqYj3|^EZENb3-9}iI8ID3NoxH(F-Hg<2^%458fAcmO=(k#mZZ}FMB&?Z%6D-YbR&VV3;XVrdXa2Lu0|z(LF<^o$Qdo#Z121p%BC5AkKZ; zs*`J4h3l+KYh`4t)pWvjO+Jyuyddd<Cj=FMY#AX=~w)oG%W&>20!FMlXq3+$e8Z zk6BN%y#c=`E43z^5{K`k7Bb!UP0nuyWa<@*P{;p3T~Iw|hkL17LAR5@r2q@;~+CYX7I)eNl(t>o7 z$Sq+$ec>K_btybJNHP?#pnxqnS zQZ8WA)1}Gxu4!>me*O|9oD==rq^;~Vy{VUfSH^tx$aXPJLyEu$>L@MI1)pN!>$U=0N7i;`AH==NReMK$ zQsJo3Y||2&S>5(c`D65+jS*Z87Jb>w&gNF@sGZ5;6&NQe>hXEh6_F()aTKD7#v+r_ zUoxwT3QM-Ukt#k@SS2V`UqU4N7e>Or3Cp`}?7M{lPpJ$PZM2t~r6-ogOwZacZQ%dE8UH!J|o@3{}xuTGysPI z@th-O3Pu{Ub?PnvK-1&*(}ep^Yl3)Su7~=>#s*vUyEVm&a`1=`1a5BA7sy+YdskOz QIzH-P5#g!Gu&A{^0NpqMI{*Lx diff --git a/test/jdk/sun/net/www/http/HttpClient/B8025710.java b/test/jdk/sun/net/www/http/HttpClient/B8025710.java index 0c3a9344459..490f6aacb23 100644 --- a/test/jdk/sun/net/www/http/HttpClient/B8025710.java +++ b/test/jdk/sun/net/www/http/HttpClient/B8025710.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -264,8 +264,8 @@ class HttpServer extends Thread implements Closeable { HttpServer() throws Exception { super("HttpServer Thread"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keystorefile), passphrase.toCharArray()); + KeyStore ks = KeyStore.getInstance(new File(keystorefile), + passphrase.toCharArray()); KeyManagerFactory factory = KeyManagerFactory.getInstance("SunX509"); factory.init(ks, passphrase.toCharArray()); SSLContext ctx = SSLContext.getInstance("TLS"); diff --git a/test/jdk/sun/security/provider/X509Factory/BadPem.java b/test/jdk/sun/security/provider/X509Factory/BadPem.java index 69682ff7d19..c63f9295123 100644 --- a/test/jdk/sun/security/provider/X509Factory/BadPem.java +++ b/test/jdk/sun/security/provider/X509Factory/BadPem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -28,8 +28,9 @@ * @modules java.base/sun.security.provider */ +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; +import java.io.File; import java.io.PrintStream; import java.security.KeyStore; import java.security.cert.CertificateException; @@ -38,7 +39,6 @@ import sun.security.provider.X509Factory; import java.security.cert.CertificateFactory; -import java.io.ByteArrayInputStream; public class BadPem { @@ -49,8 +49,8 @@ public static void main(String[] args) throws Exception { String alias = "dummy"; CertificateFactory cf = CertificateFactory.getInstance("X.509"); - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(new FileInputStream(ks), pass.toCharArray()); + KeyStore keyStore = KeyStore.getInstance(new File(ks), + pass.toCharArray()); byte[] cert = keyStore.getCertificate(alias).getEncoded(); // 8074935 diff --git a/test/jdk/sun/security/provider/X509Factory/BigCRL.java b/test/jdk/sun/security/provider/X509Factory/BigCRL.java index eab4e7499f8..4709a34623d 100644 --- a/test/jdk/sun/security/provider/X509Factory/BigCRL.java +++ b/test/jdk/sun/security/provider/X509Factory/BigCRL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, 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,7 @@ * @run main/othervm -Xshare:off -Xmx1024m BigCRL */ +import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; import java.security.KeyStore; @@ -49,8 +50,8 @@ public static void main(String[] args) throws Exception { String pass = "passphrase"; String alias = "dummy"; - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(new FileInputStream(ks), pass.toCharArray()); + KeyStore keyStore = KeyStore.getInstance(new File(ks), + pass.toCharArray()); Certificate signerCert = keyStore.getCertificate(alias); byte[] encoded = signerCert.getEncoded(); X509CertImpl signerCertImpl = new X509CertImpl(encoded); diff --git a/test/jdk/sun/security/ssl/GenSSLConfigs/main.java b/test/jdk/sun/security/ssl/GenSSLConfigs/main.java index 6fcb39cea7c..50487634f46 100644 --- a/test/jdk/sun/security/ssl/GenSSLConfigs/main.java +++ b/test/jdk/sun/security/ssl/GenSSLConfigs/main.java @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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,9 +190,8 @@ private static void initContext() System.setProperty("javax.net.ssl.trustStore", testRoot + "/../../../../javax/net/ssl/etc/truststore"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(testRoot - + "/../../../../javax/net/ssl/etc/truststore"), + KeyStore ks = KeyStore.getInstance(new File(testRoot + + "/../../../../javax/net/ssl/etc/truststore"), "passphrase".toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, "passphrase".toCharArray()); diff --git a/test/jdk/sun/security/ssl/InputRecord/ClientHelloRead.java b/test/jdk/sun/security/ssl/InputRecord/ClientHelloRead.java index 4b0c19015e2..dab438ea9b9 100644 --- a/test/jdk/sun/security/ssl/InputRecord/ClientHelloRead.java +++ b/test/jdk/sun/security/ssl/InputRecord/ClientHelloRead.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -34,7 +34,7 @@ */ import java.io.BufferedReader; -import java.io.FileInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; @@ -146,10 +146,9 @@ public static void main(String args[]) throws Exception ctx = SSLContext.getInstance("TLS"); kmf = KeyManagerFactory.getInstance("SunX509"); - ks = KeyStore.getInstance("JKS"); + ks = KeyStore.getInstance(new File(System.getProperty( + "javax.net.ssl.keyStore")), passphrase); - ks.load(new FileInputStream(System.getProperty( - "javax.net.ssl.keyStore")), passphrase); kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java index 06e2aa94b35..20b4c39afb1 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java @@ -37,6 +37,7 @@ import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManagerFactory; +import java.io.File; import java.io.FileInputStream; import java.nio.ByteBuffer; import java.security.KeyStore; @@ -101,13 +102,10 @@ public static void main(String[] args) throws Exception { public TestBadDNForPeerCA() throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - char[] passphrase = passwd.toCharArray(); - ks.load(new FileInputStream(keyStoreFile), passphrase); - ts.load(new FileInputStream(keyStoreFile), passphrase); + KeyStore ks = KeyStore.getInstance(new File(keyStoreFile), passphrase); + KeyStore ts = KeyStore.getInstance(new File(keyStoreFile), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java index 701620a7502..527ceb406c6 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java @@ -37,6 +37,7 @@ import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManagerFactory; +import java.io.File; import java.io.FileInputStream; import java.nio.ByteBuffer; import java.security.KeyStore; @@ -124,13 +125,10 @@ public static void main(String[] args) throws Exception { public TestBadDNForPeerCA12() throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - char[] passphrase = passwd.toCharArray(); - ks.load(new FileInputStream(keyStoreFile), passphrase); - ts.load(new FileInputStream(keyStoreFile), passphrase); + KeyStore ks = KeyStore.getInstance(new File(keyStoreFile), passphrase); + KeyStore ts = KeyStore.getInstance(new File(keyStoreFile), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java index abf1571cadc..e084bdd3367 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, 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 @@ -173,16 +173,10 @@ public static void main(String[] args) throws Exception { */ public SSLSocketSSLEngineCloseInbound(String protocol) throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - char[] passphrase = "passphrase".toCharArray(); - try (FileInputStream keyFile = new FileInputStream(keyFilename); - FileInputStream trustFile = new FileInputStream(trustFilename)) { - ks.load(keyFile, passphrase); - ts.load(trustFile, passphrase); - } + KeyStore ks = KeyStore.getInstance(new File(keyFilename), passphrase); + KeyStore ts = KeyStore.getInstance(new File(trustFilename), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); diff --git a/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHost.java b/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHost.java index 96180df92be..664f9b2dd49 100644 --- a/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHost.java +++ b/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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,8 @@ public static void main(String[] argv) throws Exception { String testRoot = System.getProperty("test.src", "."); System.setProperty("javax.net.ssl.trustStore", testRoot + "/../../../../javax/net/ssl/etc/truststore"); + System.setProperty("javax.net.ssl.trustStoreType", "PKCS12"); + System.setProperty("javax.net.ssl.trustStorePassword", "passphrase"); GetPeerHostServer server = new GetPeerHostServer(); server.start(); GetPeerHostClient client = diff --git a/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHostServer.java b/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHostServer.java index afcaaf4b088..44a1e3b175a 100644 --- a/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHostServer.java +++ b/test/jdk/sun/security/ssl/ServerHandshaker/GetPeerHostServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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 @@ -49,12 +49,10 @@ public GetPeerHostServer () try { SSLContext ctx = SSLContext.getInstance("TLS"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); char[] passphrase = "passphrase".toCharArray(); String testRoot = System.getProperty("test.src", "."); - ks.load(new FileInputStream(testRoot - + "/../../../../javax/net/ssl/etc/keystore"), - passphrase); + KeyStore ks = KeyStore.getInstance(new File(testRoot + + "/../../../../javax/net/ssl/etc/keystore"), passphrase); kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); ServerSocketFactory ssf = ctx.getServerSocketFactory(); diff --git a/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java b/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java index 392e882a19a..b8ac579f8fe 100644 --- a/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java +++ b/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -254,13 +254,10 @@ static private SSLEngine createSSLEngine(String keyFile, String trustFile) SSLEngine ssle; - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - char[] passphrase = "passphrase".toCharArray(); - ks.load(new FileInputStream(keyFile), passphrase); - ts.load(new FileInputStream(trustFile), passphrase); + KeyStore ks = KeyStore.getInstance(new File(keyFile), passphrase); + KeyStore ts = KeyStore.getInstance(new File(trustFile), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); diff --git a/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java b/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java index 0f249f53516..5086463b589 100644 --- a/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java +++ b/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -71,8 +71,7 @@ public static void main(String[] args) throws Exception { "/" + keyStoreFile; char [] password = passwd.toCharArray(); - ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), password); + ks = KeyStore.getInstance(new File(keyFilename), password); kmf = KeyManagerFactory.getInstance("NewSunX509"); kmf.init(ks, password); km = (X509KeyManager) kmf.getKeyManagers()[0]; diff --git a/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java b/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java index b0348fec841..f05c32b3079 100644 --- a/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java +++ b/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -70,8 +70,7 @@ public static void main(String[] args) throws Exception { * Setup the tests. */ kmf = KeyManagerFactory.getInstance("SunX509"); - ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), passphrase); + ks = KeyStore.getInstance(new File(keyFilename), passphrase); kmf.init(ks, passphrase); km = (X509KeyManager) kmf.getKeyManagers()[0]; diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java index c91840fa8ed..36bb6ccf01f 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CertRequestOverflow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -192,13 +192,11 @@ private SSLContext getContext(boolean server) throws Exception { "/" + trustStoreFile; KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), cpasswd); + KeyStore ks = KeyStore.getInstance(new File(keyFilename), cpasswd); kmf.init(ks, cpasswd); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - KeyStore ts = KeyStore.getInstance("JKS"); - ts.load(new FileInputStream(trustFilename), cpasswd); + KeyStore ts = KeyStore.getInstance(new File(trustFilename), cpasswd); tmf.init(ts); TrustManager tms[] = tmf.getTrustManagers(); diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CheckNullEntity.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CheckNullEntity.java index 452fe1b4570..550cb8227cb 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CheckNullEntity.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CheckNullEntity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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,8 +65,7 @@ private void initialize() throws Exception { "/" + trustStoreFile; char[] passphrase = "passphrase".toCharArray(); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(trustFilename), passphrase); + KeyStore ks = KeyStore.getInstance(new File(trustFilename), passphrase); for (Enumeration e = ks.aliases() ; e.hasMoreElements() ;) { String alias = (String)e.nextElement(); diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java index d0eb242442e..337f36979bb 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, 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 @@ -181,13 +181,11 @@ private SSLContext getContext(boolean server) throws Exception { "/" + trustStoreFile; KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(keyFilename), cpasswd); + KeyStore ks = KeyStore.getInstance(new File(keyFilename), cpasswd); kmf.init(ks, cpasswd); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - KeyStore ts = KeyStore.getInstance("JKS"); - ts.load(new FileInputStream(trustFilename), cpasswd); + KeyStore ts = KeyStore.getInstance(new File(trustFilename), cpasswd); tmf.init(ts); TrustManager tms[] = tmf.getTrustManagers(); From 85ca789303aeb936142c8024f305c642773733e1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 5 Apr 2024 19:11:13 +0000 Subject: [PATCH 152/298] 8318962: Update ProcessTools javadoc with suggestions in 8315097 Backport-of: 7e4cb2f09d1219c6ba7bfa77be831a7c7c9b055a --- .../jdk/test/lib/process/ProcessTools.java | 94 +++++++++++++------ 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 87bcfcdfd0f..111f2088f24 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -492,12 +492,21 @@ private static void printStack(Thread t, StackTraceElement[] stack) { } /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - *

    - * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - * Create ProcessBuilder using the java launcher from the jdk to be tested. + * Create ProcessBuilder using the java launcher from the jdk to + * be tested. The default jvm options from jtreg, test.vm.opts and + * test.java.opts, are added. + * + *

    Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

    The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. @@ -507,12 +516,21 @@ public static ProcessBuilder createTestJavaProcessBuilder(List command) } /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - *

    - * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - * Create ProcessBuilder using the java launcher from the jdk to be tested. + * Create ProcessBuilder using the java launcher from the jdk to + * be tested. The default jvm options from jtreg, test.vm.opts and + * test.java.opts, are added. + * + *

    Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

    The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. @@ -536,6 +554,18 @@ public static ProcessBuilder createTestJavaProcessBuilder(String... command) { * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources. * + *

    Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

    The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. + * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. */ @@ -558,6 +588,18 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(List co * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources. * + *

    Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

    The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. + * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. */ @@ -566,14 +608,12 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma } /** - * Executes a test jvm process, waits for it to finish and returns the process output. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - * The java from the test.jdk is used to execute the command. - *

    - * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - *

    - * The jvm process will have exited before this method returns. + * Executes a test jvm process, waits for it to finish and returns + * the process output. + * + *

    The process is created using runtime flags set up by: + * {@link #createTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. * * @param cmds User specified arguments. * @return The output from the process. @@ -583,14 +623,12 @@ public static OutputAnalyzer executeTestJvm(List cmds) throws Exception } /** - * Executes a test jvm process, waits for it to finish and returns the process output. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - * The java from the test.jdk is used to execute the command. - *

    - * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - *

    - * The jvm process will have exited before this method returns. + * Executes a test jvm process, waits for it to finish and returns + * the process output. + * + *

    The process is created using runtime flags set up by: + * {@link #createTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. * * @param cmds User specified arguments. * @return The output from the process. From e1f8f838d72a78dd3a049ff594b3d5d4812826fc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 5 Apr 2024 19:12:41 +0000 Subject: [PATCH 153/298] 8316460: 4 javax/management tests ignore VM flags Backport-of: d39b7bab27af5ba24ff0925037b8e5fb99680dc0 --- test/jdk/ProblemList-Virtual.txt | 4 +- .../ImplVersionTest.java | 92 +++++++------------ .../connection/DefaultAgentFilterTest.java | 10 +- .../mandatory/version/ImplVersionTest.java | 79 ++++++---------- .../security/HashedPasswordFileTest.java | 8 +- 5 files changed, 73 insertions(+), 120 deletions(-) diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index 6d4ff898551..6461c3b4a61 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 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 @@ -75,4 +75,6 @@ java/lang/SecurityManager/modules/CustomSecurityManagerTest.java 0000000 generic java/util/PluggableLocale/PermissionTest.java 0000000 generic-all java/util/Properties/StoreReproducibilityTest.java 0000000 generic-all java/util/Properties/StoreReproducibilityTest.java 0000000 generic-all +javax/management/ImplementationVersion/ImplVersionTest.java 0000000 generic-all javax/management/remote/mandatory/subjectDelegation/SubjectDelegation1Test.java 0000000 generic-all +javax/management/remote/mandatory/version/ImplVersionTest.java 0000000 generic-all diff --git a/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java b/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java index cc77fced683..16f0c8f262f 100644 --- a/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java +++ b/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -30,70 +30,48 @@ * system property. * @author Luis-Miguel Alventosa * - * @run clean ImplVersionTest ImplVersionCommand + * @library /test/lib * @run build ImplVersionTest ImplVersionCommand ImplVersionReader * @run main ImplVersionTest */ +import jdk.test.lib.process.ProcessTools; + import java.io.File; public class ImplVersionTest { - public static void main(String[] args) { - try { - // Get OS name - // - String osName = System.getProperty("os.name"); - System.out.println("osName = " + osName); - if ("Windows 98".equals(osName)) { - // Disable this test on Win98 due to parsing - // errors (bad handling of white spaces) when - // J2SE is installed under "Program Files". - // - System.out.println("This test is disabled on Windows 98."); - System.out.println("Bye! Bye!"); - return; - } - // Get Java Home - // - String javaHome = System.getProperty("java.home"); - System.out.println("javaHome = " + javaHome); - // Get test src - // - String testSrc = System.getProperty("test.src"); - System.out.println("testSrc = " + testSrc); - // Get test classes - // - String testClasses = System.getProperty("test.classes"); - System.out.println("testClasses = " + testClasses); - // Get boot class path - // - String command = - javaHome + File.separator + "bin" + File.separator + "java " + - " -classpath " + testClasses + - " -Djava.security.manager -Djava.security.policy==" + testSrc + - File.separator + "policy -Dtest.classes=" + testClasses + - " ImplVersionCommand " + - System.getProperty("java.runtime.version"); - System.out.println("ImplVersionCommand Exec Command = " +command); - Process proc = Runtime.getRuntime().exec(command); - new ImplVersionReader(proc, proc.getInputStream()).start(); - new ImplVersionReader(proc, proc.getErrorStream()).start(); - int exitValue = proc.waitFor(); - System.out.println("ImplVersionCommand Exit Value = " + - exitValue); - if (exitValue != 0) { - System.out.println("TEST FAILED: Incorrect exit value " + - "from ImplVersionCommand"); - System.exit(exitValue); - } - // Test OK! - // - System.out.println("Bye! Bye!"); - } catch (Exception e) { - System.out.println("Unexpected exception caught = " + e); - e.printStackTrace(); - System.exit(1); + public static void main(String[] args) throws Exception { + // Get test src + // + String testSrc = System.getProperty("test.src"); + System.out.println("testSrc = " + testSrc); + // Get test classes + // + String testClasses = System.getProperty("test.classes"); + System.out.println("testClasses = " + testClasses); + // Get boot class path + // + String[] command = new String[] { + "-Djava.security.manager", + "-Djava.security.policy==" + testSrc + File.separator + "policy", + "-Dtest.classes=" + testClasses, + "ImplVersionCommand", + System.getProperty("java.runtime.version") + }; + + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(command); + Process proc = pb.start(); + new ImplVersionReader(proc, proc.getInputStream()).start(); + new ImplVersionReader(proc, proc.getErrorStream()).start(); + int exitValue = proc.waitFor(); + System.out.println("ImplVersionCommand Exit Value = " + exitValue); + if (exitValue != 0) { + throw new RuntimeException("TEST FAILED: Incorrect exit value " + + "from ImplVersionCommand " + exitValue); } + // Test OK! + // + System.out.println("Bye! Bye!"); } } diff --git a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java index 8645e6ff86a..7a3236a888e 100644 --- a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java +++ b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java @@ -262,11 +262,9 @@ private static void testDefaultAgent(String propertyFile, String additionalArgum * test other usages (Attributes, Query) */ private static void testDefaultAgent(String propertyFile, String additionalArgument, int port, boolean testOperations) throws Exception { - List pbArgs = new ArrayList<>(Arrays.asList( - "-cp", - System.getProperty("test.class.path"), - "-XX:+UsePerfData" - )); + List pbArgs = new ArrayList<>(); + pbArgs.add("-XX:+UsePerfData"); + // JMX config arguments, using propertyFile if non-null: pbArgs.add("-Dcom.sun.management.jmxremote.port=" + port); pbArgs.add("-Dcom.sun.management.jmxremote.authenticate=false"); @@ -280,7 +278,7 @@ private static void testDefaultAgent(String propertyFile, String additionalArgum } pbArgs.add(TEST_APP_NAME); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( pbArgs.toArray(new String[pbArgs.size()]) ); diff --git a/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java b/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java index 8ee4e769cd8..0a179358466 100644 --- a/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java +++ b/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -30,69 +30,48 @@ * system property. * @author Luis-Miguel Alventosa, Joel Feraud * - * @run clean ImplVersionTest ImplVersionCommand + * @library /test/lib * @run build ImplVersionTest ImplVersionCommand ImplVersionReader * @run main ImplVersionTest */ +import jdk.test.lib.process.ProcessTools; + import java.io.File; public class ImplVersionTest { - public static void main(String[] args) { - try { - // Get OS name - // - String osName = System.getProperty("os.name"); - System.out.println("osName = " + osName); - if ("Windows 98".equals(osName)) { - // Disable this test on Win98 due to parsing - // errors (bad handling of white spaces) when - // J2SE is installed under "Program Files". - // - System.out.println("This test is disabled on Windows 98."); - System.out.println("Bye! Bye!"); - return; - } + public static void main(String[] args) throws Exception { - // Get Java Home - String javaHome = System.getProperty("java.home"); + // Get test src + // + String testSrc = System.getProperty("test.src"); - // Get test src - // - String testSrc = System.getProperty("test.src"); + // Get test classes + String testClasses = System.getProperty("test.classes"); - // Get test classes - String testClasses = System.getProperty("test.classes"); + // Build command string - // Build command string - String command = - javaHome + File.separator + "bin" + File.separator + "java " + - " -classpath " + testClasses + - " -Djava.security.manager -Djava.security.policy==" + testSrc + - File.separator + "policy -Dtest.classes=" + testClasses + - " ImplVersionCommand " + System.getProperty("java.runtime.version"); - System.out.println("ImplVersionCommand Exec Command = " + command); + String[] command = new String[] { + "-Djava.security.manager", + "-Djava.security.policy==" + testSrc + File.separator + "policy", + "-Dtest.classes=" + testClasses, + "ImplVersionCommand", + System.getProperty("java.runtime.version") + }; - // Exec command - Process proc = Runtime.getRuntime().exec(command); - new ImplVersionReader(proc, proc.getInputStream()).start(); - new ImplVersionReader(proc, proc.getErrorStream()).start(); - int exitValue = proc.waitFor(); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(command); + Process proc = pb.start(); + new ImplVersionReader(proc, proc.getInputStream()).start(); + new ImplVersionReader(proc, proc.getErrorStream()).start(); + int exitValue = proc.waitFor(); - System.out.println("ImplVersionCommand Exit Value = " + - exitValue); - if (exitValue != 0) { - System.out.println("TEST FAILED: Incorrect exit value " + - "from ImplVersionCommand"); - System.exit(exitValue); - } - // Test OK! - System.out.println("Bye! Bye!"); - } catch (Exception e) { - System.out.println("Unexpected exception caught = " + e); - e.printStackTrace(); - System.exit(1); + System.out.println("ImplVersionCommand Exit Value = " + exitValue); + if (exitValue != 0) { + throw new RuntimeException("TEST FAILED: Incorrect exit value " + + "from ImplVersionCommand " + exitValue); } + // Test OK! + System.out.println("Bye! Bye!"); } } diff --git a/test/jdk/javax/management/security/HashedPasswordFileTest.java b/test/jdk/javax/management/security/HashedPasswordFileTest.java index 7a3f02bc7c8..195a9cd3449 100644 --- a/test/jdk/javax/management/security/HashedPasswordFileTest.java +++ b/test/jdk/javax/management/security/HashedPasswordFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -468,10 +468,6 @@ public void testDefaultAgentNoHash() throws Exception { perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_WRITE); Files.setPosixFilePermissions(file.toPath(), perms); - - pbArgs.add("-cp"); - pbArgs.add(System.getProperty("test.class.path")); - pbArgs.add("-Dcom.sun.management.jmxremote.port=0"); pbArgs.add("-Dcom.sun.management.jmxremote.authenticate=true"); pbArgs.add("-Dcom.sun.management.jmxremote.password.file=" + file.getAbsolutePath()); @@ -481,7 +477,7 @@ public void testDefaultAgentNoHash() throws Exception { pbArgs.add("jdk.management.agent/jdk.internal.agent=ALL-UNNAMED"); pbArgs.add(TestApp.class.getSimpleName()); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( pbArgs.toArray(new String[0])); Process process = ProcessTools.startProcess( TestApp.class.getSimpleName(), From 8ed46c2b0e8c5f440a7f079953ea51b1f9e0d41e Mon Sep 17 00:00:00 2001 From: Dan Lutker Date: Mon, 8 Apr 2024 06:58:00 +0000 Subject: [PATCH 154/298] 8294699: Launcher causes lingering busy cursor Backport-of: d3df3eb5d7f5537ade917db7a36caba028f94111 --- .../native/applauncher/WinLauncher.cpp | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp b/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp index 407cf00693b..d9757bd0819 100644 --- a/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp +++ b/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -150,6 +150,82 @@ void addCfgFileLookupDirForEnvVariable( } +class RunExecutorWithMsgLoop { +public: + static DWORD apply(const Executor& exec) { + RunExecutorWithMsgLoop instance(exec); + + UniqueHandle threadHandle = UniqueHandle(CreateThread(NULL, 0, worker, + static_cast(&instance), 0, NULL)); + if (threadHandle.get() == NULL) { + JP_THROW(SysError("CreateThread() failed", CreateThread)); + } + + MSG msg; + BOOL bRet; + while((bRet = GetMessage(&msg, instance.hwnd, 0, 0 )) != 0) { + if (bRet == -1) { + JP_THROW(SysError("GetMessage() failed", GetMessage)); + } else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + // Wait for worker thread to terminate to guarantee it will not linger + // around after the thread running a message loop terminates. + const DWORD res = ::WaitForSingleObject(threadHandle.get(), INFINITE); + if (WAIT_FAILED == res) { + JP_THROW(SysError("WaitForSingleObject() failed", + WaitForSingleObject)); + } + + LOG_TRACE(tstrings::any() + << "Executor worker thread terminated. Exit code=" + << instance.exitCode); + return instance.exitCode; + } + +private: + RunExecutorWithMsgLoop(const Executor& v): exec(v) { + exitCode = 1; + + // Message-only window. + hwnd = CreateWindowEx(0, _T("STATIC"), _T(""), 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + if (!hwnd) { + JP_THROW(SysError("CreateWindowEx() failed", CreateWindowEx)); + } + } + + static DWORD WINAPI worker(LPVOID param) { + static_cast(param)->run(); + return 0; + } + + void run() { + JP_TRY; + exitCode = static_cast(exec.execAndWaitForExit()); + JP_CATCH_ALL; + + JP_TRY; + if (!PostMessage(hwnd, WM_QUIT, 0, 0)) { + JP_THROW(SysError("PostMessage(WM_QUIT) failed", PostMessage)); + } + return; + JP_CATCH_ALL; + + // All went wrong, PostMessage() failed. Just terminate with error code. + exit(1); + } + +private: + const Executor& exec; + DWORD exitCode; + HWND hwnd; +}; + + void launchApp() { // [RT-31061] otherwise UI can be left in back of other windows. ::AllowSetForegroundWindow(ASFW_ANY); @@ -203,7 +279,7 @@ void launchApp() { exec.arg(arg); }); - DWORD exitCode = static_cast(exec.execAndWaitForExit()); + DWORD exitCode = RunExecutorWithMsgLoop::apply(exec); exit(exitCode); return; From e5c1031e1fce25b20e41a5fc6088fa441176b15e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:13:21 +0000 Subject: [PATCH 155/298] 8293069: Make -XX:+Verbose less verbose Backport-of: 238c51e621d17a24d35085a54c129ce99ad6d0d8 --- src/hotspot/share/ci/ciEnv.cpp | 8 +------- src/hotspot/share/opto/compile.cpp | 2 +- src/hotspot/share/opto/doCall.cpp | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 74208152988..c05c20dccd7 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1317,13 +1317,7 @@ void ciEnv::record_best_dyno_loc(const InstanceKlass* ik) { return; } const char *loc0; - if (dyno_loc(ik, loc0)) { - // TODO: found multiple references, see if we can improve - if (Verbose) { - tty->print_cr("existing call site @ %s for %s", - loc0, ik->external_name()); - } - } else { + if (!dyno_loc(ik, loc0)) { set_dyno_loc(ik); } } diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index c9b82face2d..b7ed590126f 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1936,7 +1936,7 @@ void Compile::process_for_unstable_if_traps(PhaseIterGVN& igvn) { if (!live_locals.at(i) && !local->is_top() && local != lhs && local!= rhs) { uint idx = jvms->locoff() + i; #ifdef ASSERT - if (Verbose) { + if (PrintOpto && Verbose) { tty->print("[unstable_if] kill local#%d: ", idx); local->dump(); tty->cr(); diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index f7fa5e9d8cc..401cb35e227 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -856,7 +856,7 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) { #ifndef PRODUCT // We do not expect the same handler bci to take both cold unloaded // and hot loaded exceptions. But, watch for it. - if ((Verbose || WizardMode) && extype->is_loaded()) { + if (PrintOpto && (Verbose || WizardMode) && extype->is_loaded()) { tty->print("Warning: Handler @%d takes mixed loaded/unloaded exceptions in ", bci()); method()->print_name(); tty->cr(); } else if (PrintOpto && (Verbose || WizardMode)) { From 3b3ec13364767dcbdbf4ae80e41f01a546f9696e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:18:26 +0000 Subject: [PATCH 156/298] 8314975: JavadocTester should set source path if not specified Backport-of: 2f4d601a56bf02db2766d1f8a2ddfff906b78678 --- .../javadoc/lib/javadoc/tester/JavadocTester.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java index dd0cc3c1f4a..a409dd2cedb 100644 --- a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java +++ b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java @@ -424,12 +424,14 @@ public void javadoc(String... args) { String charsetArg = null; String docencodingArg = null; String encodingArg = null; + boolean haveSourcePath = false; for (int i = 0; i < args.length - 2; i++) { switch (args[i]) { case "-d" -> outputDir = Path.of(args[++i]); case "-charset" -> charsetArg = args[++i]; case "-docencoding" -> docencodingArg = args[++i]; case "-encoding" -> encodingArg = args[++i]; + case "-sourcepath", "--source-path", "--module-source-path" -> haveSourcePath = true; } } @@ -451,6 +453,16 @@ public void javadoc(String... args) { charset = Charset.defaultCharset(); } + // explicitly set the source path if none specified + // to override the javadoc tool default to use the classpath + if (!haveSourcePath) { + var newArgs = new String[args.length + 2]; + newArgs[0] = "-sourcepath"; + newArgs[1] = testSrc; + System.arraycopy(args, 0, newArgs, 2, args.length); + args = newArgs; + } + out.println("args: " + Arrays.toString(args)); // log.setOutDir(outputDir); From e5ee283bc9f5bf1c89926c7f25c7b41d292ff85c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:20:02 +0000 Subject: [PATCH 157/298] 8321163: [test] OutputAnalyzer.getExitValue() unnecessarily logs even when process has already completed Backport-of: 672f37324f9f15ae3e03b9b3b86c7106e6a09eed --- test/lib/jdk/test/lib/process/OutputBuffer.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java index 3741ccbe2ff..fba2a5f6dcf 100644 --- a/test/lib/jdk/test/lib/process/OutputBuffer.java +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -120,6 +120,7 @@ public String get() { private final StreamTask outTask; private final StreamTask errTask; private final Process p; + private volatile Integer exitValue; // null implies we don't yet know private final void logProgress(String state) { System.out.println("[" + Instant.now().toString() + "] " + state @@ -146,14 +147,17 @@ public String getStderr() { @Override public int getExitValue() { + if (exitValue != null) { + return exitValue; + } try { logProgress("Waiting for completion"); boolean aborted = true; try { - int result = p.waitFor(); + exitValue = p.waitFor(); logProgress("Waiting for completion finished"); aborted = false; - return result; + return exitValue; } finally { if (aborted) { logProgress("Waiting for completion FAILED"); From d5c170ac5ccede957dd71f5bee50539cb14756da Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:21:53 +0000 Subject: [PATCH 158/298] 8319578: Few java/lang/instrument ignore test.java.opts and accept test.vm.opts only Backport-of: 3ebe6c192a5dd5cc46ae2d263713c9ff38cd46bb --- .../lang/instrument/BootClassPath/BootClassPathTest.sh | 8 ++++---- test/jdk/java/lang/instrument/ManifestTest.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineBigClass.sh | 6 +++--- .../java/lang/instrument/RedefineClassWithNativeMethod.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh | 4 ++-- .../jdk/java/lang/instrument/RedefineMethodInBacktrace.sh | 4 ++-- .../java/lang/instrument/RedefineMethodWithAnnotations.sh | 4 ++-- .../lang/instrument/RedefineSubclassWithTwoInterfaces.sh | 6 +++--- test/jdk/java/lang/instrument/RetransformBigClass.sh | 6 +++--- test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh | 4 ++-- .../appendToClassLoaderSearch/CircularityErrorTest.sh | 4 ++-- .../appendToClassLoaderSearch/ClassUnloadTest.sh | 4 ++-- .../instrument/appendToClassLoaderSearch/run_tests.sh | 8 ++++---- 14 files changed, 35 insertions(+), 35 deletions(-) diff --git a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh index 1c3b81cd14d..32306c97fbc 100644 --- a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh +++ b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 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 @@ -74,7 +74,7 @@ case ${OS} in ;; esac -"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent "${CYGWIN}" +"$JAVA" ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent "${CYGWIN}" BOOTDIR=`cat ${TESTCLASSES}/boot.dir` @@ -94,13 +94,13 @@ echo "Creating agent jar file..." echo "Running test..." -"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain result=$? echo "Cleanup..." "$JAVAC" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" \ "${TESTSRC}"/Cleanup.java -"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Cleanup "${BOOTDIR}" +"$JAVA" ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath "${TESTCLASSES}" Cleanup "${BOOTDIR}" exit $result diff --git a/test/jdk/java/lang/instrument/ManifestTest.sh b/test/jdk/java/lang/instrument/ManifestTest.sh index daed5ad3c4c..9feb1de53f5 100644 --- a/test/jdk/java/lang/instrument/ManifestTest.sh +++ b/test/jdk/java/lang/instrument/ManifestTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 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 @@ -380,7 +380,7 @@ while read token; do echo "===== begin test case: $token =====" make_a_JAR "$token" - "${JAVA}" ${TESTVMOPTS} -javaagent:${AGENT}.jar \ + "${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:${AGENT}.jar \ -classpath "${TESTCLASSES}" ManifestTestApp > output.log 2>&1 result=$? diff --git a/test/jdk/java/lang/instrument/RedefineBigClass.sh b/test/jdk/java/lang/instrument/RedefineBigClass.sh index 1c2bfb6b0c1..19421301fb0 100644 --- a/test/jdk/java/lang/instrument/RedefineBigClass.sh +++ b/test/jdk/java/lang/instrument/RedefineBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -62,14 +62,14 @@ JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java # Does this VM support the 'detail' level of NMT? -"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -XX:NativeMemoryTracking=detail -version if [ "$?" = 0 ]; then NMT=-XX:NativeMemoryTracking=detail else NMT=-XX:NativeMemoryTracking=summary fi -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=debug,redefine+class+load+exceptions=info ${NMT} \ -javaagent:RedefineBigClassAgent.jar=BigClass.class \ -classpath "${TESTCLASSES}" RedefineBigClassApp \ diff --git a/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh b/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh index 0a029bd1ebc..8c269ab1929 100644 --- a/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh +++ b/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 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 @@ -58,7 +58,7 @@ fi JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -javaagent:RedefineClassWithNativeMethodAgent.jar=java/lang/Thread.class \ -classpath "${TESTCLASSES}" RedefineClassWithNativeMethodApp \ > output.log 2>&1 diff --git a/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh b/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh index b5864fbc26b..284051d05d8 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 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 @@ -70,7 +70,7 @@ cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_2.java \ mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_2.java mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_2.class -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodAddInvokeApp > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh b/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh index 9924af3d2a8..0df5a104741 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 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 @@ -71,7 +71,7 @@ cp "${TESTSRC}"/RedefineMethodDelInvokeTarget_2.java \ mv RedefineMethodDelInvokeTarget.java RedefineMethodDelInvokeTarget_2.java mv RedefineMethodDelInvokeTarget.class RedefineMethodDelInvokeTarget_2.class -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodDelInvokeAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodDelInvokeAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodDelInvokeApp > output.log 2>&1 diff --git a/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh b/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh index d7cb2aa1c03..85d06fd486e 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -68,7 +68,7 @@ cp "${TESTSRC}"/RedefineMethodInBacktraceTargetB_2.java \ RedefineMethodInBacktraceTargetB.java "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodInBacktraceTargetB.java -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodInBacktraceApp > output.log 2>&1 RUN_RESULT=$? diff --git a/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh b/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh index ed3ef4ef412..beb04864623 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -67,7 +67,7 @@ cp "${TESTSRC}"/RedefineMethodWithAnnotationsAnnotations.java \ RedefineMethodWithAnnotationsTarget.java \ RedefineMethodWithAnnotationsAnnotations.java -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodWithAnnotationsAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodWithAnnotationsAgent.jar \ -XX:+UnlockDiagnosticVMOptions -XX:+StressLdcRewrite -XX:+IgnoreUnrecognizedVMOptions \ -cp "${TESTCLASSES}" RedefineMethodWithAnnotationsApp > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh b/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh index e583c9df469..fea99aecbaa 100644 --- a/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh +++ b/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -69,7 +69,7 @@ cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesImpl_1.java \ "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ -cp "${TESTCLASSES}" -d . \ RedefineSubclassWithTwoInterfacesTarget.java \ - RedefineSubclassWithTwoInterfacesImpl.java + RedefineSubclassWithTwoInterfacesImpl.java status="$?" if [ "$status" != 0 ]; then echo "FAIL: compile of *_1.java files failed." @@ -87,7 +87,7 @@ mv RedefineSubclassWithTwoInterfacesImpl.class \ echo "INFO: launching RedefineSubclassWithTwoInterfacesApp" -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=trace,redefine+class+load+exceptions=trace,redefine+class+timer=trace,redefine+class+obsolete=trace,redefine+class+obsolete+metadata=trace,redefine+class+constantpool=trace \ -javaagent:RedefineSubclassWithTwoInterfacesAgent.jar \ -classpath "${TESTCLASSES}" \ diff --git a/test/jdk/java/lang/instrument/RetransformBigClass.sh b/test/jdk/java/lang/instrument/RetransformBigClass.sh index 455f42a3247..31c92117e93 100644 --- a/test/jdk/java/lang/instrument/RetransformBigClass.sh +++ b/test/jdk/java/lang/instrument/RetransformBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -62,14 +62,14 @@ JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java # Does this VM support the 'detail' level of NMT? -"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -XX:NativeMemoryTracking=detail -version if [ "$?" = 0 ]; then NMT=-XX:NativeMemoryTracking=detail else NMT=-XX:NativeMemoryTracking=summary fi -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=debug,redefine+class+load+exceptions=info ${NMT} \ -javaagent:RetransformBigClassAgent.jar=BigClass.class \ -classpath "${TESTCLASSES}" RetransformBigClassApp \ diff --git a/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh b/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh index a2ba29d238b..3b9364f0cc3 100644 --- a/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh +++ b/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 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 @@ -51,7 +51,7 @@ fi JAVA="${TESTJAVA}"/bin/java -"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:basicAgent.jar \ -classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \ > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh index 0589b43ee07..0cfe6a64157 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -77,4 +77,4 @@ $JAR ${TESTTOOLVMOPTS} -cfm "${TESTCLASSES}"/CircularityErrorTest.jar "${MANIFES # Finally we run the test (cd "${TESTCLASSES}"; - $JAVA ${TESTVMOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest) + $JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest) diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh index 71923152da4..d6aec21a229 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -80,5 +80,5 @@ $JAR ${TESTTOOLVMOPTS} -cfm "${TESTCLASSES}"/ClassUnloadTest.jar "${MANIFEST}" \ # Finally we run the test (cd "${TESTCLASSES}"; \ - $JAVA ${TESTVMOPTS} -Xlog:class+unload \ + $JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -Xlog:class+unload \ -javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar) diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh index 51f89f09239..eb7abe71edc 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -56,7 +56,7 @@ failures=0 go() { echo '' - sh -xc "$JAVA ${TESTVMOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1 + sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi } @@ -85,11 +85,11 @@ mv Application.class InstrumentedApplication.bytes cp "${TESTSRC}"/Application.java . "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . Application.java -sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1 +sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi # Repeat test with security manager -sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1 +sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi # From 2a56bfbb6a5630b05efb9df2f876f63ba1783c67 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:23:36 +0000 Subject: [PATCH 159/298] 8316451: 6 java/lang/instrument/PremainClass tests ignore VM flags Backport-of: 9029bf644e238a504e1f114a73edf5760d19980b --- .../java/lang/instrument/NegativeAgentRunner.java | 4 ++-- .../instrument/PremainClass/PremainClassTest.java | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/test/jdk/java/lang/instrument/NegativeAgentRunner.java b/test/jdk/java/lang/instrument/NegativeAgentRunner.java index 9689c323114..2d585cc6e6a 100644 --- a/test/jdk/java/lang/instrument/NegativeAgentRunner.java +++ b/test/jdk/java/lang/instrument/NegativeAgentRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -35,7 +35,7 @@ public static void main(String argv[]) throws Exception { } String agentClassName = argv[0]; String excepClassName = argv[1]; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-javaagent:" + agentClassName + ".jar", "-Xmx128m", "-XX:-CreateCoredumpOnCrash", agentClassName); OutputAnalyzer output = new OutputAnalyzer(pb.start()); diff --git a/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java b/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java index ecd284fe6e0..216dbb94d8a 100644 --- a/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java +++ b/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -39,14 +39,10 @@ public class PremainClassTest { // a non ascii character. // Verify that the premain() function is executed correctly. public static void main(String[] a) throws Exception { - String testArgs = String.format( - "-javaagent:%s/Agent.jar -classpath %s DummyMain", - System.getProperty("test.src"), - System.getProperty("test.classes", ".")); + String testArgs = String.format("-javaagent:%s/Agent.jar", + System.getProperty("test.src")); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - Utils.addTestJavaOpts(testArgs.split("\\s+"))); - System.out.println("testjvm.cmd:" + Utils.getCommandLine(pb)); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(testArgs, "DummyMain"); OutputAnalyzer output = ProcessTools.executeProcess(pb); System.out.println("testjvm.stdout:" + output.getStdout()); From 35f291b9575620d2728193359d8a13aa10b1467b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 12:24:51 +0000 Subject: [PATCH 160/298] 8326718: Test java/util/Formatter/Padding.java should timeout on large inputs before fix in JDK-8299677 Backport-of: 4f336085d1098e7fba7b58f0a73c028179a2a13d --- test/jdk/java/util/Formatter/Padding.java | 43 +++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/util/Formatter/Padding.java b/test/jdk/java/util/Formatter/Padding.java index 5f0e7f0e201..dc3df0be0e4 100644 --- a/test/jdk/java/util/Formatter/Padding.java +++ b/test/jdk/java/util/Formatter/Padding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4906370 + * @bug 4906370 8299677 8326718 * @summary Tests to excercise padding on int and double values, * with various flag combinations. * @run junit Padding @@ -40,6 +40,9 @@ public class Padding { + private static final String tenMillionZeros = "0".repeat(10_000_000); + private static final String tenMillionBlanks = " ".repeat(10_000_000); + static Arguments[] padding() { return new Arguments[] { /* blank padding, right adjusted, optional plus sign */ @@ -49,6 +52,7 @@ static Arguments[] padding() { arguments(" 12", "%4d", 12), arguments(" 12", "%5d", 12), arguments(" 12", "%10d", 12), + arguments(tenMillionBlanks + "12", "%10000002d", 12), arguments("-12", "%1d", -12), arguments("-12", "%2d", -12), @@ -56,6 +60,7 @@ static Arguments[] padding() { arguments(" -12", "%4d", -12), arguments(" -12", "%5d", -12), arguments(" -12", "%10d", -12), + arguments(tenMillionBlanks + "-12", "%10000003d", -12), arguments("1.2", "%1.1f", 1.2), arguments("1.2", "%2.1f", 1.2), @@ -63,6 +68,7 @@ static Arguments[] padding() { arguments(" 1.2", "%4.1f", 1.2), arguments(" 1.2", "%5.1f", 1.2), arguments(" 1.2", "%10.1f", 1.2), + arguments(tenMillionBlanks + "1.2", "%10000003.1f", 1.2), arguments("-1.2", "%1.1f", -1.2), arguments("-1.2", "%2.1f", -1.2), @@ -70,6 +76,7 @@ static Arguments[] padding() { arguments("-1.2", "%4.1f", -1.2), arguments(" -1.2", "%5.1f", -1.2), arguments(" -1.2", "%10.1f", -1.2), + arguments(tenMillionBlanks + "-1.2", "%10000004.1f", -1.2), /* blank padding, right adjusted, mandatory plus sign */ arguments("+12", "%+1d", 12), @@ -78,6 +85,7 @@ static Arguments[] padding() { arguments(" +12", "%+4d", 12), arguments(" +12", "%+5d", 12), arguments(" +12", "%+10d", 12), + arguments(tenMillionBlanks + "+12", "%+10000003d", 12), arguments("-12", "%+1d", -12), arguments("-12", "%+2d", -12), @@ -85,6 +93,7 @@ static Arguments[] padding() { arguments(" -12", "%+4d", -12), arguments(" -12", "%+5d", -12), arguments(" -12", "%+10d", -12), + arguments(tenMillionBlanks + "-12", "%+10000003d", -12), arguments("+1.2", "%+1.1f", 1.2), arguments("+1.2", "%+2.1f", 1.2), @@ -92,6 +101,7 @@ static Arguments[] padding() { arguments("+1.2", "%+4.1f", 1.2), arguments(" +1.2", "%+5.1f", 1.2), arguments(" +1.2", "%+10.1f", 1.2), + arguments(tenMillionBlanks + "+1.2", "%+10000004.1f", 1.2), arguments("-1.2", "%+1.1f", -1.2), arguments("-1.2", "%+2.1f", -1.2), @@ -99,6 +109,7 @@ static Arguments[] padding() { arguments("-1.2", "%+4.1f", -1.2), arguments(" -1.2", "%+5.1f", -1.2), arguments(" -1.2", "%+10.1f", -1.2), + arguments(tenMillionBlanks + "-1.2", "%+10000004.1f", -1.2), /* blank padding, right adjusted, mandatory blank sign */ arguments(" 12", "% 1d", 12), @@ -107,6 +118,7 @@ static Arguments[] padding() { arguments(" 12", "% 4d", 12), arguments(" 12", "% 5d", 12), arguments(" 12", "% 10d", 12), + arguments(tenMillionBlanks + "12", "% 10000002d", 12), arguments("-12", "% 1d", -12), arguments("-12", "% 2d", -12), @@ -114,6 +126,7 @@ static Arguments[] padding() { arguments(" -12", "% 4d", -12), arguments(" -12", "% 5d", -12), arguments(" -12", "% 10d", -12), + arguments(tenMillionBlanks + "-12", "% 10000003d", -12), arguments(" 1.2", "% 1.1f", 1.2), arguments(" 1.2", "% 2.1f", 1.2), @@ -121,6 +134,7 @@ static Arguments[] padding() { arguments(" 1.2", "% 4.1f", 1.2), arguments(" 1.2", "% 5.1f", 1.2), arguments(" 1.2", "% 10.1f", 1.2), + arguments(tenMillionBlanks + "1.2", "% 10000003.1f", 1.2), arguments("-1.2", "% 1.1f", -1.2), arguments("-1.2", "% 2.1f", -1.2), @@ -128,6 +142,7 @@ static Arguments[] padding() { arguments("-1.2", "% 4.1f", -1.2), arguments(" -1.2", "% 5.1f", -1.2), arguments(" -1.2", "% 10.1f", -1.2), + arguments(tenMillionBlanks + "-1.2", "% 10000004.1f", -1.2), /* blank padding, left adjusted, optional sign */ arguments("12", "%-1d", 12), @@ -136,6 +151,7 @@ static Arguments[] padding() { arguments("12 ", "%-4d", 12), arguments("12 ", "%-5d", 12), arguments("12 ", "%-10d", 12), + arguments("12" + tenMillionBlanks, "%-10000002d", 12), arguments("-12", "%-1d", -12), arguments("-12", "%-2d", -12), @@ -143,6 +159,7 @@ static Arguments[] padding() { arguments("-12 ", "%-4d", -12), arguments("-12 ", "%-5d", -12), arguments("-12 ", "%-10d", -12), + arguments("-12" + tenMillionBlanks, "%-10000003d", -12), arguments("1.2", "%-1.1f", 1.2), arguments("1.2", "%-2.1f", 1.2), @@ -150,6 +167,7 @@ static Arguments[] padding() { arguments("1.2 ", "%-4.1f", 1.2), arguments("1.2 ", "%-5.1f", 1.2), arguments("1.2 ", "%-10.1f", 1.2), + arguments("1.2" + tenMillionBlanks, "%-10000003.1f", 1.2), arguments("-1.2", "%-1.1f", -1.2), arguments("-1.2", "%-2.1f", -1.2), @@ -157,6 +175,7 @@ static Arguments[] padding() { arguments("-1.2", "%-4.1f", -1.2), arguments("-1.2 ", "%-5.1f", -1.2), arguments("-1.2 ", "%-10.1f", -1.2), + arguments("-1.2" + tenMillionBlanks, "%-10000004.1f", -1.2), /* blank padding, left adjusted, mandatory plus sign */ arguments("+12", "%-+1d", 12), @@ -165,6 +184,7 @@ static Arguments[] padding() { arguments("+12 ", "%-+4d", 12), arguments("+12 ", "%-+5d", 12), arguments("+12 ", "%-+10d", 12), + arguments("+12" + tenMillionBlanks, "%-+10000003d", 12), arguments("-12", "%-+1d", -12), arguments("-12", "%-+2d", -12), @@ -172,6 +192,7 @@ static Arguments[] padding() { arguments("-12 ", "%-+4d", -12), arguments("-12 ", "%-+5d", -12), arguments("-12 ", "%-+10d", -12), + arguments("-12" + tenMillionBlanks, "%-+10000003d", -12), arguments("+1.2", "%-+1.1f", 1.2), arguments("+1.2", "%-+2.1f", 1.2), @@ -179,6 +200,7 @@ static Arguments[] padding() { arguments("+1.2", "%-+4.1f", 1.2), arguments("+1.2 ", "%-+5.1f", 1.2), arguments("+1.2 ", "%-+10.1f", 1.2), + arguments("+1.2" + tenMillionBlanks, "%-+10000004.1f", 1.2), arguments("-1.2", "%-+1.1f", -1.2), arguments("-1.2", "%-+2.1f", -1.2), @@ -186,6 +208,7 @@ static Arguments[] padding() { arguments("-1.2", "%-+4.1f", -1.2), arguments("-1.2 ", "%-+5.1f", -1.2), arguments("-1.2 ", "%-+10.1f", -1.2), + arguments("-1.2" + tenMillionBlanks, "%-+10000004.1f", -1.2), /* blank padding, left adjusted, mandatory blank sign */ arguments(" 12", "%- 1d", 12), @@ -194,6 +217,7 @@ static Arguments[] padding() { arguments(" 12 ", "%- 4d", 12), arguments(" 12 ", "%- 5d", 12), arguments(" 12 ", "%- 10d", 12), + arguments(" 12" + tenMillionBlanks, "%- 10000003d", 12), arguments("-12", "%- 1d", -12), arguments("-12", "%- 2d", -12), @@ -201,6 +225,7 @@ static Arguments[] padding() { arguments("-12 ", "%- 4d", -12), arguments("-12 ", "%- 5d", -12), arguments("-12 ", "%- 10d", -12), + arguments("-12" + tenMillionBlanks, "%- 10000003d", -12), arguments(" 1.2", "%- 1.1f", 1.2), arguments(" 1.2", "%- 2.1f", 1.2), @@ -208,6 +233,7 @@ static Arguments[] padding() { arguments(" 1.2", "%- 4.1f", 1.2), arguments(" 1.2 ", "%- 5.1f", 1.2), arguments(" 1.2 ", "%- 10.1f", 1.2), + arguments(" 1.2" + tenMillionBlanks, "%- 10000004.1f", 1.2), arguments("-1.2", "%- 1.1f", -1.2), arguments("-1.2", "%- 2.1f", -1.2), @@ -215,6 +241,7 @@ static Arguments[] padding() { arguments("-1.2", "%- 4.1f", -1.2), arguments("-1.2 ", "%- 5.1f", -1.2), arguments("-1.2 ", "%- 10.1f", -1.2), + arguments("-1.2" + tenMillionBlanks, "%- 10000004.1f", -1.2), /* zero padding, right adjusted, optional sign */ arguments("12", "%01d", 12), @@ -223,6 +250,7 @@ static Arguments[] padding() { arguments("0012", "%04d", 12), arguments("00012", "%05d", 12), arguments("0000000012", "%010d", 12), + arguments(tenMillionZeros + "12", "%010000002d", 12), arguments("-12", "%01d", -12), arguments("-12", "%02d", -12), @@ -230,6 +258,7 @@ static Arguments[] padding() { arguments("-012", "%04d", -12), arguments("-0012", "%05d", -12), arguments("-000000012", "%010d", -12), + arguments("-" + tenMillionZeros + "12", "%010000003d", -12), arguments("1.2", "%01.1f", 1.2), arguments("1.2", "%02.1f", 1.2), @@ -237,6 +266,7 @@ static Arguments[] padding() { arguments("01.2", "%04.1f", 1.2), arguments("001.2", "%05.1f", 1.2), arguments("00000001.2", "%010.1f", 1.2), + arguments(tenMillionZeros + "1.2", "%010000003.1f", 1.2), arguments("-1.2", "%01.1f", -1.2), arguments("-1.2", "%02.1f", -1.2), @@ -244,6 +274,7 @@ static Arguments[] padding() { arguments("-1.2", "%04.1f", -1.2), arguments("-01.2", "%05.1f", -1.2), arguments("-0000001.2", "%010.1f", -1.2), + arguments("-" + tenMillionZeros + "1.2", "%010000004.1f", -1.2), /* zero padding, right adjusted, mandatory plus sign */ arguments("+12", "%+01d", 12), @@ -252,6 +283,7 @@ static Arguments[] padding() { arguments("+012", "%+04d", 12), arguments("+0012", "%+05d", 12), arguments("+000000012", "%+010d", 12), + arguments("+" + tenMillionZeros + "12", "%+010000003d", 12), arguments("-12", "%+01d", -12), arguments("-12", "%+02d", -12), @@ -259,6 +291,7 @@ static Arguments[] padding() { arguments("-012", "%+04d", -12), arguments("-0012", "%+05d", -12), arguments("-000000012", "%+010d", -12), + arguments("-" + tenMillionZeros + "12", "%+010000003d", -12), arguments("+1.2", "%+01.1f", 1.2), arguments("+1.2", "%+02.1f", 1.2), @@ -266,6 +299,7 @@ static Arguments[] padding() { arguments("+1.2", "%+04.1f", 1.2), arguments("+01.2", "%+05.1f", 1.2), arguments("+0000001.2", "%+010.1f", 1.2), + arguments("+" + tenMillionZeros + "1.2", "%+010000004.1f", 1.2), arguments("-1.2", "%+01.1f", -1.2), arguments("-1.2", "%+02.1f", -1.2), @@ -273,6 +307,7 @@ static Arguments[] padding() { arguments("-1.2", "%+04.1f", -1.2), arguments("-01.2", "%+05.1f", -1.2), arguments("-0000001.2", "%+010.1f", -1.2), + arguments("-" + tenMillionZeros + "1.2", "%+010000004.1f", -1.2), /* zero padding, right adjusted, mandatory blank sign */ arguments(" 12", "% 01d", 12), @@ -281,6 +316,7 @@ static Arguments[] padding() { arguments(" 012", "% 04d", 12), arguments(" 0012", "% 05d", 12), arguments(" 000000012", "% 010d", 12), + arguments(" " + tenMillionZeros + "12", "% 010000003d", 12), arguments("-12", "% 01d", -12), arguments("-12", "% 02d", -12), @@ -288,6 +324,7 @@ static Arguments[] padding() { arguments("-012", "% 04d", -12), arguments("-0012", "% 05d", -12), arguments("-000000012", "% 010d", -12), + arguments("-" + tenMillionZeros + "12", "% 010000003d", -12), arguments(" 1.2", "% 01.1f", 1.2), arguments(" 1.2", "% 02.1f", 1.2), @@ -295,6 +332,7 @@ static Arguments[] padding() { arguments(" 1.2", "% 04.1f", 1.2), arguments(" 01.2", "% 05.1f", 1.2), arguments(" 0000001.2", "% 010.1f", 1.2), + arguments(" " + tenMillionZeros + "1.2", "% 010000004.1f", 1.2), arguments("-1.2", "% 01.1f", -1.2), arguments("-1.2", "% 02.1f", -1.2), @@ -302,6 +340,7 @@ static Arguments[] padding() { arguments("-1.2", "% 04.1f", -1.2), arguments("-01.2", "% 05.1f", -1.2), arguments("-0000001.2", "% 010.1f", -1.2), + arguments("-" + tenMillionZeros + "1.2", "% 010000004.1f", -1.2), }; } From 1c4479fd398b5ca31bc3a3d0e520b1ef3fea5cad Mon Sep 17 00:00:00 2001 From: Elif Aslan Date: Mon, 8 Apr 2024 20:21:25 +0000 Subject: [PATCH 161/298] 8325567: jspawnhelper without args fails with segfault Backport-of: 262747094670b00ac63463a059074afa9b81d8a4 --- .../unix/native/jspawnhelper/jspawnhelper.c | 5 ++ .../ProcessBuilder/JspawnhelperWarnings.java | 57 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java diff --git a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c index 5a583fda61f..974329a2857 100644 --- a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c +++ b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c @@ -63,6 +63,7 @@ void shutItDown() { fprintf(stdout, "only be run as the result of a call to\n"); fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java "); fprintf(stdout, "application\n"); + fflush(stdout); _exit(1); } @@ -140,6 +141,10 @@ int main(int argc, char *argv[]) { int r, fdinr, fdinw, fdout; sigset_t unblock_signals; + if (argc != 2) { + shutItDown(); + } + #ifdef DEBUG jtregSimulateCrash(0, 4); #endif diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java new file mode 100644 index 00000000000..0ff68186502 --- /dev/null +++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java @@ -0,0 +1,57 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8325567 + * @requires (os.family == "linux") | (os.family == "aix") | (os.family == "mac") + * @library /test/lib + * @run driver JspawnhelperWarnings + */ + +import java.nio.file.Paths; +import java.util.Arrays; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class JspawnhelperWarnings { + + private static void tryWithNArgs(int nArgs) throws Exception { + System.out.println("Running jspawnhelper with " + nArgs + " args"); + String[] args = new String[nArgs + 1]; + Arrays.fill(args, "1"); + args[0] = Paths.get(System.getProperty("java.home"), "lib", "jspawnhelper").toString(); + Process p = ProcessTools.startProcess("jspawnhelper", new ProcessBuilder(args)); + OutputAnalyzer oa = new OutputAnalyzer(p); + oa.shouldHaveExitValue(1); + oa.shouldContain("This command is not for general use"); + } + + public static void main(String[] args) throws Exception { + for (int nArgs = 0; nArgs < 10; nArgs++) { + tryWithNArgs(nArgs); + } + } +} From b9ca2532287b02388cd6f9e69b02a86713fc5b88 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Apr 2024 20:55:58 +0000 Subject: [PATCH 162/298] 8325203: System.exit(0) kills the launched 3rd party application Backport-of: 6944537c3ebbbb638479e4c2b90a71ad5869023c --- src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp b/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp index d9757bd0819..119cbbd79c5 100644 --- a/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp +++ b/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -264,7 +264,7 @@ void launchApp() { } JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { }; jobInfo.BasicLimitInformation.LimitFlags = - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; if (!SetInformationJobObject(jobHandle.get(), JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) { JP_THROW(SysError(tstrings::any() << From d5f44dcae2f0be291e1ce52562574fccce7dc763 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 9 Apr 2024 05:58:24 +0000 Subject: [PATCH 163/298] 8319650: Improve heap dump performance with class metadata caching Reviewed-by: phh Backport-of: 03db82818b905f21cb5ad1d56a687e238b4a6e33 --- src/hotspot/share/services/heapDumper.cpp | 157 ++++++++++++++++++---- 1 file changed, 133 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index 74786534069..8f044ed427f 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -883,8 +883,10 @@ class ParDumpWriter : public AbstractDumpWriter { Monitor* ParDumpWriter::_lock = nullptr; -// Support class with a collection of functions used when dumping the heap +class DumperClassCacheTable; +class DumperClassCacheTableEntry; +// Support class with a collection of functions used when dumping the heap class DumperSupport : AllStatic { public: @@ -899,7 +901,7 @@ class DumperSupport : AllStatic { static u4 sig2size(Symbol* sig); // returns the size of the instance of the given class - static u4 instance_size(Klass* k); + static u4 instance_size(InstanceKlass* ik, DumperClassCacheTableEntry* class_cache_entry = nullptr); // dump a jfloat static void dump_float(AbstractDumpWriter* writer, jfloat f); @@ -912,13 +914,13 @@ class DumperSupport : AllStatic { // dumps static fields of the given class static void dump_static_fields(AbstractDumpWriter* writer, Klass* k); // dump the raw values of the instance fields of the given object - static void dump_instance_fields(AbstractDumpWriter* writer, oop o); + static void dump_instance_fields(AbstractDumpWriter* writer, oop o, DumperClassCacheTableEntry* class_cache_entry); // get the count of the instance fields for a given class static u2 get_instance_fields_count(InstanceKlass* ik); // dumps the definition of the instance fields for a given class static void dump_instance_field_descriptors(AbstractDumpWriter* writer, Klass* k); // creates HPROF_GC_INSTANCE_DUMP record for the given object - static void dump_instance(AbstractDumpWriter* writer, oop o); + static void dump_instance(AbstractDumpWriter* writer, oop o, DumperClassCacheTable* class_cache); // creates HPROF_GC_CLASS_DUMP record for the given instance class static void dump_instance_class(AbstractDumpWriter* writer, Klass* k); // creates HPROF_GC_CLASS_DUMP record for a given array class @@ -948,6 +950,106 @@ class DumperSupport : AllStatic { } }; +// Hash table of klasses to the klass metadata. This should greatly improve the +// hash dumping performance. This hash table is supposed to be used by a single +// thread only. +// +class DumperClassCacheTableEntry : public CHeapObj { + friend class DumperClassCacheTable; +private: + GrowableArray _sigs_start; + GrowableArray _offsets; + u4 _instance_size; + int _entries; + +public: + DumperClassCacheTableEntry() : _instance_size(0), _entries(0) {}; + + int field_count() { return _entries; } + char sig_start(int field_idx) { return _sigs_start.at(field_idx); } + int offset(int field_idx) { return _offsets.at(field_idx); } + u4 instance_size() { return _instance_size; } +}; + +class DumperClassCacheTable { +private: + // ResourceHashtable SIZE is specified at compile time so we + // use 1031 which is the first prime after 1024. + static constexpr size_t TABLE_SIZE = 1031; + + // Maintain the cache for N classes. This limits memory footprint + // impact, regardless of how many classes we have in the dump. + // This also improves look up performance by keeping the statically + // sized table from overloading. + static constexpr int CACHE_TOP = 256; + + typedef ResourceHashtable PtrTable; + PtrTable* _ptrs; + + // Single-slot cache to handle the major case of objects of the same + // class back-to-back, e.g. from T[]. + InstanceKlass* _last_ik; + DumperClassCacheTableEntry* _last_entry; + + void unlink_all(PtrTable* table) { + class CleanupEntry: StackObj { + public: + bool do_entry(InstanceKlass*& key, DumperClassCacheTableEntry*& entry) { + delete entry; + return true; + } + } cleanup; + table->unlink(&cleanup); + } + +public: + DumperClassCacheTableEntry* lookup_or_create(InstanceKlass* ik) { + if (_last_ik == ik) { + return _last_entry; + } + + DumperClassCacheTableEntry* entry; + DumperClassCacheTableEntry** from_cache = _ptrs->get(ik); + if (from_cache == nullptr) { + entry = new DumperClassCacheTableEntry(); + for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { + if (!fld.access_flags().is_static()) { + Symbol* sig = fld.signature(); + entry->_sigs_start.push(sig->char_at(0)); + entry->_offsets.push(fld.offset()); + entry->_entries++; + entry->_instance_size += DumperSupport::sig2size(sig); + } + } + + if (_ptrs->number_of_entries() >= CACHE_TOP) { + // We do not track the individual hit rates for table entries. + // Purge the entire table, and let the cache catch up with new + // distribution. + unlink_all(_ptrs); + } + + _ptrs->put(ik, entry); + } else { + entry = *from_cache; + } + + // Remember for single-slot cache. + _last_ik = ik; + _last_entry = entry; + + return entry; + } + + DumperClassCacheTable() : _ptrs(new (mtServiceability) PtrTable), _last_ik(nullptr), _last_entry(nullptr) {} + + ~DumperClassCacheTable() { + unlink_all(_ptrs); + delete _ptrs; + } +}; + // write a header of the given type void DumperSupport:: write_header(AbstractDumpWriter* writer, hprofTag tag, u4 len) { writer->write_u1(tag); @@ -1092,16 +1194,18 @@ void DumperSupport::dump_field_value(AbstractDumpWriter* writer, char type, oop } // returns the size of the instance of the given class -u4 DumperSupport::instance_size(Klass* k) { - InstanceKlass* ik = InstanceKlass::cast(k); - u4 size = 0; - - for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { - if (!fld.access_flags().is_static()) { - size += sig2size(fld.signature()); +u4 DumperSupport::instance_size(InstanceKlass* ik, DumperClassCacheTableEntry* class_cache_entry) { + if (class_cache_entry != nullptr) { + return class_cache_entry->instance_size(); + } else { + u4 size = 0; + for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { + if (!fld.access_flags().is_static()) { + size += sig2size(fld.signature()); + } } + return size; } - return size; } u4 DumperSupport::get_static_fields_size(InstanceKlass* ik, u2& field_count) { @@ -1173,14 +1277,10 @@ void DumperSupport::dump_static_fields(AbstractDumpWriter* writer, Klass* k) { } // dump the raw values of the instance fields of the given object -void DumperSupport::dump_instance_fields(AbstractDumpWriter* writer, oop o) { - InstanceKlass* ik = InstanceKlass::cast(o->klass()); - - for (HierarchicalFieldStream fld(ik); !fld.done(); fld.next()) { - if (!fld.access_flags().is_static()) { - Symbol* sig = fld.signature(); - dump_field_value(writer, sig->char_at(0), o, fld.offset()); - } +void DumperSupport::dump_instance_fields(AbstractDumpWriter* writer, oop o, DumperClassCacheTableEntry* class_cache_entry) { + assert(class_cache_entry != nullptr, "Pre-condition: must be provided"); + for (int idx = 0; idx < class_cache_entry->field_count(); idx++) { + dump_field_value(writer, class_cache_entry->sig_start(idx), o, class_cache_entry->offset(idx)); } } @@ -1211,9 +1311,12 @@ void DumperSupport::dump_instance_field_descriptors(AbstractDumpWriter* writer, } // creates HPROF_GC_INSTANCE_DUMP record for the given object -void DumperSupport::dump_instance(AbstractDumpWriter* writer, oop o) { +void DumperSupport::dump_instance(AbstractDumpWriter* writer, oop o, DumperClassCacheTable* class_cache) { InstanceKlass* ik = InstanceKlass::cast(o->klass()); - u4 is = instance_size(ik); + + DumperClassCacheTableEntry* cache_entry = class_cache->lookup_or_create(ik); + + u4 is = instance_size(ik, cache_entry); u4 size = 1 + sizeof(address) + 4 + sizeof(address) + 4 + is; writer->start_sub_record(HPROF_GC_INSTANCE_DUMP, size); @@ -1227,7 +1330,7 @@ void DumperSupport::dump_instance(AbstractDumpWriter* writer, oop o) { writer->write_u4(is); // field values - dump_instance_fields(writer, o); + dump_instance_fields(writer, o, cache_entry); writer->end_sub_record(); } @@ -1690,6 +1793,9 @@ class HeapObjectDumper : public ObjectClosure { AbstractDumpWriter* writer() { return _writer; } bool is_large(oop o); + + DumperClassCacheTable _class_cache; + public: HeapObjectDumper(AbstractDumpWriter* writer, HeapDumpLargeObjectList* list = nullptr) { _writer = writer; @@ -1722,7 +1828,7 @@ void HeapObjectDumper::do_object(oop o) { if (o->is_instance()) { // create a HPROF_GC_INSTANCE record for each object - DumperSupport::dump_instance(writer(), o); + DumperSupport::dump_instance(writer(), o, &_class_cache); } else if (o->is_objArray()) { // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array DumperSupport::dump_object_array(writer(), objArrayOop(o)); @@ -2278,6 +2384,7 @@ void VM_HeapDumper::work(uint worker_id) { // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk // of the heap dump. if (_num_dumper_threads <= 1) { + ResourceMark rm; HeapObjectDumper obj_dumper(writer()); Universe::heap()->object_iterate(&obj_dumper); } else { @@ -2294,6 +2401,7 @@ void VM_HeapDumper::work(uint worker_id) { { ParDumpWriter pw(writer()); { + ResourceMark rm; HeapObjectDumper obj_dumper(&pw, _large_object_list); _poi->object_iterate(&obj_dumper, worker_id); } @@ -2314,6 +2422,7 @@ void VM_HeapDumper::work(uint worker_id) { assert(get_worker_type(worker_id) == VMDumperType, "Heap dumper must be VMDumper"); // Use writer() rather than ParDumpWriter to avoid memory consumption. + ResourceMark rm; HeapObjectDumper obj_dumper(writer()); dump_large_objects(&obj_dumper); // Writes the HPROF_HEAP_DUMP_END record. From fd507393b4a1792e0e7e6d7be363b7c5b441b716 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Tue, 9 Apr 2024 08:40:49 +0000 Subject: [PATCH 164/298] 8315652: RISC-V: Features string uses wrong separator for jtreg Reviewed-by: rehn Backport-of: cbbfa0ddfb1485edfc6275dd7085b3096f7eccf6 --- src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp index f890bfbdc02..a7528ae07bd 100644 --- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp @@ -108,7 +108,7 @@ void VM_Version::setup_cpu_available_features() { char buf[1024] = {}; if (uarch != nullptr && strcmp(uarch, "") != 0) { // Use at max half the buffer. - snprintf(buf, sizeof(buf)/2, "%s,", uarch); + snprintf(buf, sizeof(buf)/2, "%s ", uarch); } os::free((void*) uarch); strcat(buf, "rv64"); @@ -122,13 +122,14 @@ void VM_Version::setup_cpu_available_features() { if (_feature_list[i]->feature_string()) { const char* tmp = _feature_list[i]->pretty(); if (strlen(tmp) == 1) { + strcat(buf, " "); strcat(buf, tmp); } else { // Feature string is expected to be lower case. // Turn Zxxx into zxxx char prebuf[3] = {}; assert(strlen(tmp) > 1, "Must be"); - prebuf[0] = '_'; + prebuf[0] = ' '; prebuf[1] = (char)tolower(tmp[0]); strcat(buf, prebuf); strcat(buf, &tmp[1]); From 88abc6adb50997b90830980aa6fe9467ddf9a828 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 9 Apr 2024 08:53:55 +0000 Subject: [PATCH 165/298] 8328604: remove on_aix() function Backport-of: 940d1965f831a9f7e4f1ce34e381c038827c7ca2 --- src/hotspot/os/aix/os_aix.cpp | 32 +++++++------------------------- src/hotspot/os/aix/os_aix.hpp | 16 ++-------------- 2 files changed, 9 insertions(+), 39 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 8efb8c8f259..a8938c71fe8 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -765,10 +765,8 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???"); // Make sure we run in 1:1 kernel-user-thread mode. - if (os::Aix::on_aix()) { - guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???"); - guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???"); - } + guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???"); + guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???"); // Start in suspended state, and in os::thread_start, wake the thread up. guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???"); @@ -1271,22 +1269,10 @@ void os::print_memory_info(outputStream* st) { os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { - if (os::Aix::on_aix()) { - st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); - st->print_cr("physical free : " SIZE_FORMAT, mi.real_free); - st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total); - st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free); - } else { - // PASE - Numbers are result of QWCRSSTS; they mean: - // real_total: Sum of all system pools - // real_free: always 0 - // pgsp_total: we take the size of the system ASP - // pgsp_free: size of system ASP times percentage of system ASP unused - st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); - st->print_cr("system asp total : " SIZE_FORMAT, mi.pgsp_total); - st->print_cr("%% system asp used : %.2f", - mi.pgsp_total ? (100.0f * (mi.pgsp_total - mi.pgsp_free) / mi.pgsp_total) : -1.0f); - } + st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); + st->print_cr("physical free : " SIZE_FORMAT, mi.real_free); + st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total); + st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free); } st->cr(); @@ -2367,9 +2353,7 @@ void os::init(void) { } // Reset the perfstat information provided by ODM. - if (os::Aix::on_aix()) { - libperfstat::perfstat_reset(); - } + libperfstat::perfstat_reset(); // Now initialize basic system properties. Note that for some of the values we // need libperfstat etc. @@ -2940,9 +2924,7 @@ void os::Aix::initialize_libo4() { } } -// AIX: initialize the libperfstat library. void os::Aix::initialize_libperfstat() { - assert(os::Aix::on_aix(), "AIX only"); if (!libperfstat::init()) { trcVerbose("libperfstat initialization failed."); assert(false, "libperfstat initialization failed"); diff --git a/src/hotspot/os/aix/os_aix.hpp b/src/hotspot/os/aix/os_aix.hpp index a1db2b2be3c..22fb5327bf9 100644 --- a/src/hotspot/os/aix/os_aix.hpp +++ b/src/hotspot/os/aix/os_aix.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, 2023 SAP SE. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024 SAP SE. 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 @@ -101,13 +101,6 @@ class os::Aix { return _on_pase ? true : false; } - // Function returns true if we run on AIX, false if we run on OS/400 - // (pase). - static bool on_aix() { - assert(_on_pase != -1, "not initialized"); - return _on_pase ? false : true; - } - // Get 4 byte AIX kernel version number: // highest 2 bytes: Version, Release // if available: lowest 2 bytes: Tech Level, Service Pack. @@ -130,11 +123,6 @@ class os::Aix { return on_pase() && os_version_short() <= 0x0504; } - // Convenience method: returns true if running on AIX 5.3 or older. - static bool on_aix_53_or_older() { - return on_aix() && os_version_short() <= 0x0503; - } - // Returns true if we run in SPEC1170 compliant mode (XPG_SUS_ENV=ON). static bool xpg_sus_mode() { assert(_xpg_sus_mode != -1, "not initialized"); From e95e6feed59f478967a4d26fc30d190355a892c2 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 9 Apr 2024 18:16:23 +0000 Subject: [PATCH 166/298] 8305645: System Tray icons get corrupted when Windows primary monitor changes Backport-of: 6cd370e04b01c3033eb439de0f38e9b6d703c6f4 --- .../native/libawt/windows/awt_TrayIcon.cpp | 4 ++-- .../awt/TrayIcon/TrayIconScalingTest.java | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp b/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp index 7c8d78254ee..8b72fa7e008 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -262,7 +262,7 @@ LRESULT CALLBACK AwtTrayIcon::TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam } } break; - case WM_DPICHANGED: + case WM_DISPLAYCHANGE: // Set the flag to update icon images, see WmTaskbarCreated m_bDPIChanged = true; break; diff --git a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java index ed72ce115cf..e5c082ac6d2 100644 --- a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java +++ b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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,8 +52,9 @@ public class TrayIconScalingTest { private static TrayIcon icon; private static final String INSTRUCTIONS = - "This test checks if the tray icon gets updated when DPI / Scale" + - " is changed on the fly.\n\n" + + "This test checks if the tray icon gets updated correctly under 2 scenarios:\n\n" + + "Case 1: Single Screen - when DPI / Scale is changed on the fly.\n" + + "Case 2: Multi Screen - when both screens are set to different scales.\n\n" + "STEPS: \n\n" + "1. Check the system tray / notification area on Windows" + " taskbar, you should see a white icon which displays a" + @@ -61,11 +62,17 @@ public class TrayIconScalingTest { "2. Navigate to Settings > System > Display and change the" + " display scale by selecting any value from" + " Scale & Layout dropdown.\n\n"+ - "3. When the scale changes, check the white tray icon," + + "3. For Case 1, when the scale changes, check the white tray icon," + " there should be no distortion, it should be displayed sharp,\n" + " and the displayed number should correspond to the current"+ - " scale:\n" + - " 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n"+ + " scale.\n\n" + + "4. For Case 2, a dual monitor setup is required with 'Multiple Display'" + + " option under Display settings set to 'Extend the display'.\n\n" + + "5. Have the monitors set to different scales and toggle the" + + " 'Make this my main display' option under Display settings.\n\n" + + " In both cases, the tray icon should be displayed as a clear image" + + " without any distortion with the display number corresponding to the scale.\n" + + " 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n" + " If the icon is displayed sharp and without any distortion," + " press PASS, otherwise press FAIL.\n"; @@ -79,7 +86,7 @@ public static void main(String[] args) return; } PassFailJFrame passFailJFrame = new PassFailJFrame("TrayIcon " + - "Test Instructions", INSTRUCTIONS, 8, 18, 85); + "Test Instructions", INSTRUCTIONS, 8, 25, 85); createAndShowGUI(); // does not have a test window, // hence only the instruction frame is positioned From 8173c6489dd09c57a7f6c18c76ae002ef1fbe8bb Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 10 Apr 2024 06:43:01 +0000 Subject: [PATCH 167/298] 8329570: G1: Excessive is_obj_dead_cond calls in verification Backport-of: 29992e1fca4faef0fe0ac453c7e78db4628d5e70 --- src/hotspot/share/gc/g1/heapRegion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index b3e64c064e0..a79977d2545 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -608,7 +608,6 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure { template void do_oop_work(T* p) { assert(_containing_obj != nullptr, "must be"); - assert(!G1CollectedHeap::heap()->is_obj_dead_cond(_containing_obj, _vo), "Precondition"); if (num_failures() >= G1MaxVerifyFailures) { return; @@ -640,6 +639,7 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure { _num_failures(0) { } void set_containing_obj(oop const obj) { + assert(!G1CollectedHeap::heap()->is_obj_dead_cond(obj, _vo), "Precondition"); _containing_obj = obj; } From e0d22481451e74944ea688e74e54df8bed9f064d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 10 Apr 2024 09:45:21 +0000 Subject: [PATCH 168/298] 8311881: jdk/javax/swing/ProgressMonitor/ProgressTest.java does not show the ProgressMonitorInputStream all the time Backport-of: 197981b431fb7c7e6740ac45a671b99d1c7583c6 --- .../javax/swing/ProgressMonitor/ProgressTest.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/jdk/javax/swing/ProgressMonitor/ProgressTest.java b/test/jdk/javax/swing/ProgressMonitor/ProgressTest.java index 776cb720ae1..e06cba6cfb0 100644 --- a/test/jdk/javax/swing/ProgressMonitor/ProgressTest.java +++ b/test/jdk/javax/swing/ProgressMonitor/ProgressTest.java @@ -30,11 +30,11 @@ */ import java.io.InputStream; - +import java.awt.EventQueue; import javax.swing.ProgressMonitorInputStream; public class ProgressTest { - + static volatile long total = 0; private static final String instructionsText = "A ProgressMonitor will be shown.\n" + " If it shows blank progressbar after 2048MB bytes read,\n"+ @@ -69,15 +69,20 @@ public int read() { public void run() { byte[] buffer = new byte[512]; int nb = 0; - long total = 0; while (true) { try { nb = pmis.read(buffer); } catch (Exception e){} if (nb == 0) break; total += nb; - - pmis.getProgressMonitor().setNote(total/(1024*1024)+" MB Read"); + System.out.println("total " + total); + if ((total % (1024*1024)) == 0) { + try { + EventQueue.invokeAndWait(() -> { + pmis.getProgressMonitor().setNote(total/(1024*1024)+" MB Read"); + }); + } catch (Exception e) {} + } } } }; From 38a2173d5468a467d8ae00d70569840a1619adc7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 10 Apr 2024 09:46:29 +0000 Subject: [PATCH 169/298] 8318585: Rename CodeCache::UnloadingScope to UnlinkingScope Reviewed-by: sgehwolf Backport-of: 4eab39d9415b2ec5c2984d0d3c110e9364090835 --- src/hotspot/share/code/codeCache.cpp | 4 ++-- src/hotspot/share/code/codeCache.hpp | 11 +++++++---- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 2 +- src/hotspot/share/gc/g1/g1FullCollector.cpp | 2 +- src/hotspot/share/gc/parallel/psParallelCompact.cpp | 2 +- src/hotspot/share/gc/serial/genMarkSweep.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 2 +- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 7808c86a92c..d2ee5c36317 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1024,7 +1024,7 @@ void CodeCache::increment_unloading_cycle() { } } -CodeCache::UnloadingScope::UnloadingScope(BoolObjectClosure* is_alive) +CodeCache::UnlinkingScope::UnlinkingScope(BoolObjectClosure* is_alive) : _is_unloading_behaviour(is_alive) { _saved_behaviour = IsUnloadingBehaviour::current(); @@ -1033,7 +1033,7 @@ CodeCache::UnloadingScope::UnloadingScope(BoolObjectClosure* is_alive) DependencyContext::cleaning_start(); } -CodeCache::UnloadingScope::~UnloadingScope() { +CodeCache::UnlinkingScope::~UnlinkingScope() { IsUnloadingBehaviour::set_current(_saved_behaviour); DependencyContext::cleaning_end(); } diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 459df9b19f0..403eacdfab3 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -179,14 +179,17 @@ class CodeCache : AllStatic { // GC support static void verify_oops(); - // Scope object managing code cache unloading behavior. - class UnloadingScope: StackObj { + + // Helper scope object managing code cache unlinking behavior, i.e. sets and + // restores the closure that determines which nmethods are going to be removed + // during the unlinking part of code cache unloading. + class UnlinkingScope : StackObj { ClosureIsUnloadingBehaviour _is_unloading_behaviour; IsUnloadingBehaviour* _saved_behaviour; public: - UnloadingScope(BoolObjectClosure* is_alive); - ~UnloadingScope(); + UnlinkingScope(BoolObjectClosure* is_alive); + ~UnlinkingScope(); }; // Code cache unloading heuristics diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 23454ddffba..8930f97af6a 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1685,7 +1685,7 @@ void G1ConcurrentMark::weak_refs_work() { if (ClassUnloadingWithConcurrentMark) { GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm); { - CodeCache::UnloadingScope scope(&g1_is_alive); + CodeCache::UnlinkingScope scope(&g1_is_alive); bool unloading_occurred = SystemDictionary::do_unloading(_gc_timer_cm); _g1h->complete_cleaning(unloading_occurred); } diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index f225937a49f..039f13019ab 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -320,7 +320,7 @@ void G1FullCollector::phase1_mark_live_objects() { if (ClassUnloading) { GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer()); { - CodeCache::UnloadingScope unloading_scope(&_is_alive); + CodeCache::UnlinkingScope unloading_scope(&_is_alive); // Unload classes and purge the SystemDictionary. bool unloading_occurred = SystemDictionary::do_unloading(scope()->timer()); _heap->complete_cleaning(unloading_occurred); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index cf6471fd818..532031a2102 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -2055,7 +2055,7 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { bool unloading_occurred; { - CodeCache::UnloadingScope scope(is_alive_closure()); + CodeCache::UnlinkingScope scope(is_alive_closure()); // Follow system dictionary roots and unload classes. unloading_occurred = SystemDictionary::do_unloading(&_gc_timer); diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp index fec80327f12..995ebc337f0 100644 --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp @@ -198,7 +198,7 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { bool unloading_occurred; { - CodeCache::UnloadingScope scope(&is_alive); + CodeCache::UnlinkingScope scope(&is_alive); // Unload classes and purge the SystemDictionary. unloading_occurred = SystemDictionary::do_unloading(gc_timer()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index a1a5e8dbddd..2333e4e21bd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1774,7 +1774,7 @@ void ShenandoahHeap::stw_unload_classes(bool full_gc) { ShenandoahPhaseTimings::degen_gc_purge_class_unload; ShenandoahIsAliveSelector is_alive; { - CodeCache::UnloadingScope scope(is_alive.is_alive_closure()); + CodeCache::UnlinkingScope scope(is_alive.is_alive_closure()); ShenandoahGCPhase gc_phase(phase); ShenandoahGCWorkerPhase worker_phase(phase); bool unloading_occurred = SystemDictionary::do_unloading(gc_timer()); From c254affaf2e5c6f55ccb5a8724714aa60e48bf00 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 10 Apr 2024 09:57:44 +0000 Subject: [PATCH 170/298] 8321718: ProcessTools.executeProcess calls waitFor before logging Backport-of: 9ab29f8dcd1c0092e4251f996bd53c704e87a74a --- .../jdk/test/lib/process/OutputAnalyzer.java | 8 +++ .../jdk/test/lib/process/OutputBuffer.java | 51 ++++++++++++++----- .../jdk/test/lib/process/ProcessTools.java | 5 +- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index 41b240b9e48..bfdec8d63a4 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -106,6 +106,14 @@ public OutputAnalyzer(String stdout, String stderr, int exitValue) buffer = OutputBuffer.of(stdout, stderr, exitValue); } + /** + * Delegate waitFor to the OutputBuffer. This ensures that + * the progress and timestamps are logged correctly. + */ + public void waitFor() { + buffer.waitFor(); + } + /** * Verify that the stdout contents of output buffer is empty * diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java index fba2a5f6dcf..f032591f358 100644 --- a/test/lib/jdk/test/lib/process/OutputBuffer.java +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java @@ -44,6 +44,12 @@ public OutputBufferException(Throwable cause) { } } + /** + * Waits for a process to finish, if there is one assocated with + * this OutputBuffer. + */ + public void waitFor(); + /** * Returns the stdout result * @@ -67,6 +73,13 @@ default public List getStdoutAsList() { * @return stderr result */ public String getStderr(); + + + /** + * Returns the exit value + * + * @return exit value + */ public int getExitValue(); /** @@ -136,20 +149,12 @@ private LazyOutputBuffer(Process p, Charset cs) { } @Override - public String getStdout() { - return outTask.get(); - } - - @Override - public String getStderr() { - return errTask.get(); - } - - @Override - public int getExitValue() { + public void waitFor() { if (exitValue != null) { - return exitValue; + // Already waited for this process + return; } + try { logProgress("Waiting for completion"); boolean aborted = true; @@ -157,7 +162,6 @@ public int getExitValue() { exitValue = p.waitFor(); logProgress("Waiting for completion finished"); aborted = false; - return exitValue; } finally { if (aborted) { logProgress("Waiting for completion FAILED"); @@ -169,6 +173,22 @@ public int getExitValue() { } } + @Override + public String getStdout() { + return outTask.get(); + } + + @Override + public String getStderr() { + return errTask.get(); + } + + @Override + public int getExitValue() { + waitFor(); + return exitValue; + } + @Override public long pid() { return p.pid(); @@ -186,6 +206,11 @@ private EagerOutputBuffer(String stdout, String stderr, int exitValue) { this.exitValue = exitValue; } + @Override + public void waitFor() { + // Nothing to do since this buffer is not associated with a Process. + } + @Override public String getStdout() { return stdout; diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 111f2088f24..12e2f0de6a2 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -697,7 +697,10 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, } output = new OutputAnalyzer(p, cs); - p.waitFor(); + + // Wait for the process to finish. Call through the output + // analyzer to get correct logging and timestamps. + output.waitFor(); { // Dumping the process output to a separate file var fileName = String.format("pid-%d-output.log", p.pid()); From 6f609576d53fd0f3fead712bdda807169e81d2f9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 10 Apr 2024 09:58:59 +0000 Subject: [PATCH 171/298] 8328037: Test java/util/Formatter/Padding.java has unnecessary high heap requirement after JDK-8326718 Backport-of: 128e60a29f1bd1e1fbe165ac382107070858ecc6 --- test/jdk/java/util/Formatter/Padding.java | 688 ++++++++++++---------- 1 file changed, 381 insertions(+), 307 deletions(-) diff --git a/test/jdk/java/util/Formatter/Padding.java b/test/jdk/java/util/Formatter/Padding.java index dc3df0be0e4..64965d64365 100644 --- a/test/jdk/java/util/Formatter/Padding.java +++ b/test/jdk/java/util/Formatter/Padding.java @@ -23,332 +23,406 @@ /* * @test - * @bug 4906370 8299677 8326718 - * @summary Tests to excercise padding on int and double values, + * @bug 4906370 8299677 8326718 8328037 + * @summary Tests to exercise padding on int and double values, * with various flag combinations. * @run junit Padding */ import java.util.Locale; +import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.params.provider.Arguments.arguments; public class Padding { + /* blank padding, right adjusted, optional sign */ + static Stream blankPaddingRightAdjustedOptionalSign() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of("12", "%1d", 12), + Arguments.of("12", "%2d", 12), + Arguments.of(" 12", "%3d", 12), + Arguments.of(" 12", "%4d", 12), + Arguments.of(" 12", "%5d", 12), + Arguments.of(" 12", "%10d", 12), + Arguments.of(tenMillionBlanks + "12", "%10000002d", 12), + + Arguments.of("-12", "%1d", -12), + Arguments.of("-12", "%2d", -12), + Arguments.of("-12", "%3d", -12), + Arguments.of(" -12", "%4d", -12), + Arguments.of(" -12", "%5d", -12), + Arguments.of(" -12", "%10d", -12), + Arguments.of(tenMillionBlanks + "-12", "%10000003d", -12), + + Arguments.of("1.2", "%1.1f", 1.2), + Arguments.of("1.2", "%2.1f", 1.2), + Arguments.of("1.2", "%3.1f", 1.2), + Arguments.of(" 1.2", "%4.1f", 1.2), + Arguments.of(" 1.2", "%5.1f", 1.2), + Arguments.of(" 1.2", "%10.1f", 1.2), + Arguments.of(tenMillionBlanks + "1.2", "%10000003.1f", 1.2), + + Arguments.of("-1.2", "%1.1f", -1.2), + Arguments.of("-1.2", "%2.1f", -1.2), + Arguments.of("-1.2", "%3.1f", -1.2), + Arguments.of("-1.2", "%4.1f", -1.2), + Arguments.of(" -1.2", "%5.1f", -1.2), + Arguments.of(" -1.2", "%10.1f", -1.2), + Arguments.of(tenMillionBlanks + "-1.2", "%10000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void blankPaddingRightAdjustedOptionalSign(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* blank padding, right adjusted, mandatory sign */ + static Stream blankPaddingRightAdjustedMandatorySign() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of("+12", "%+1d", 12), + Arguments.of("+12", "%+2d", 12), + Arguments.of("+12", "%+3d", 12), + Arguments.of(" +12", "%+4d", 12), + Arguments.of(" +12", "%+5d", 12), + Arguments.of(" +12", "%+10d", 12), + Arguments.of(tenMillionBlanks + "+12", "%+10000003d", 12), + + Arguments.of("-12", "%+1d", -12), + Arguments.of("-12", "%+2d", -12), + Arguments.of("-12", "%+3d", -12), + Arguments.of(" -12", "%+4d", -12), + Arguments.of(" -12", "%+5d", -12), + Arguments.of(" -12", "%+10d", -12), + Arguments.of(tenMillionBlanks + "-12", "%+10000003d", -12), + + Arguments.of("+1.2", "%+1.1f", 1.2), + Arguments.of("+1.2", "%+2.1f", 1.2), + Arguments.of("+1.2", "%+3.1f", 1.2), + Arguments.of("+1.2", "%+4.1f", 1.2), + Arguments.of(" +1.2", "%+5.1f", 1.2), + Arguments.of(" +1.2", "%+10.1f", 1.2), + Arguments.of(tenMillionBlanks + "+1.2", "%+10000004.1f", 1.2), + + Arguments.of("-1.2", "%+1.1f", -1.2), + Arguments.of("-1.2", "%+2.1f", -1.2), + Arguments.of("-1.2", "%+3.1f", -1.2), + Arguments.of("-1.2", "%+4.1f", -1.2), + Arguments.of(" -1.2", "%+5.1f", -1.2), + Arguments.of(" -1.2", "%+10.1f", -1.2), + Arguments.of(tenMillionBlanks + "-1.2", "%+10000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void blankPaddingRightAdjustedMandatorySign(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* blank padding, right adjusted, mandatory blank sign */ + static Stream blankPaddingRightAdjustedMandatoryBlank() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of(" 12", "% 1d", 12), + Arguments.of(" 12", "% 2d", 12), + Arguments.of(" 12", "% 3d", 12), + Arguments.of(" 12", "% 4d", 12), + Arguments.of(" 12", "% 5d", 12), + Arguments.of(" 12", "% 10d", 12), + Arguments.of(tenMillionBlanks + "12", "% 10000002d", 12), + + Arguments.of("-12", "% 1d", -12), + Arguments.of("-12", "% 2d", -12), + Arguments.of("-12", "% 3d", -12), + Arguments.of(" -12", "% 4d", -12), + Arguments.of(" -12", "% 5d", -12), + Arguments.of(" -12", "% 10d", -12), + Arguments.of(tenMillionBlanks + "-12", "% 10000003d", -12), + + Arguments.of(" 1.2", "% 1.1f", 1.2), + Arguments.of(" 1.2", "% 2.1f", 1.2), + Arguments.of(" 1.2", "% 3.1f", 1.2), + Arguments.of(" 1.2", "% 4.1f", 1.2), + Arguments.of(" 1.2", "% 5.1f", 1.2), + Arguments.of(" 1.2", "% 10.1f", 1.2), + Arguments.of(tenMillionBlanks + "1.2", "% 10000003.1f", 1.2), + + Arguments.of("-1.2", "% 1.1f", -1.2), + Arguments.of("-1.2", "% 2.1f", -1.2), + Arguments.of("-1.2", "% 3.1f", -1.2), + Arguments.of("-1.2", "% 4.1f", -1.2), + Arguments.of(" -1.2", "% 5.1f", -1.2), + Arguments.of(" -1.2", "% 10.1f", -1.2), + Arguments.of(tenMillionBlanks + "-1.2", "% 10000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void blankPaddingRightAdjustedMandatoryBlank(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* blank padding, left adjusted, optional sign */ + static Stream blankPaddingLeftAdjustedOptionalSign() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of("12", "%-1d", 12), + Arguments.of("12", "%-2d", 12), + Arguments.of("12 ", "%-3d", 12), + Arguments.of("12 ", "%-4d", 12), + Arguments.of("12 ", "%-5d", 12), + Arguments.of("12 ", "%-10d", 12), + Arguments.of("12" + tenMillionBlanks, "%-10000002d", 12), + + Arguments.of("-12", "%-1d", -12), + Arguments.of("-12", "%-2d", -12), + Arguments.of("-12", "%-3d", -12), + Arguments.of("-12 ", "%-4d", -12), + Arguments.of("-12 ", "%-5d", -12), + Arguments.of("-12 ", "%-10d", -12), + Arguments.of("-12" + tenMillionBlanks, "%-10000003d", -12), + + Arguments.of("1.2", "%-1.1f", 1.2), + Arguments.of("1.2", "%-2.1f", 1.2), + Arguments.of("1.2", "%-3.1f", 1.2), + Arguments.of("1.2 ", "%-4.1f", 1.2), + Arguments.of("1.2 ", "%-5.1f", 1.2), + Arguments.of("1.2 ", "%-10.1f", 1.2), + Arguments.of("1.2" + tenMillionBlanks, "%-10000003.1f", 1.2), + + Arguments.of("-1.2", "%-1.1f", -1.2), + Arguments.of("-1.2", "%-2.1f", -1.2), + Arguments.of("-1.2", "%-3.1f", -1.2), + Arguments.of("-1.2", "%-4.1f", -1.2), + Arguments.of("-1.2 ", "%-5.1f", -1.2), + Arguments.of("-1.2 ", "%-10.1f", -1.2), + Arguments.of("-1.2" + tenMillionBlanks, "%-10000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void blankPaddingLeftAdjustedOptionalSign(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } - private static final String tenMillionZeros = "0".repeat(10_000_000); - private static final String tenMillionBlanks = " ".repeat(10_000_000); - - static Arguments[] padding() { - return new Arguments[] { - /* blank padding, right adjusted, optional plus sign */ - arguments("12", "%1d", 12), - arguments("12", "%2d", 12), - arguments(" 12", "%3d", 12), - arguments(" 12", "%4d", 12), - arguments(" 12", "%5d", 12), - arguments(" 12", "%10d", 12), - arguments(tenMillionBlanks + "12", "%10000002d", 12), - - arguments("-12", "%1d", -12), - arguments("-12", "%2d", -12), - arguments("-12", "%3d", -12), - arguments(" -12", "%4d", -12), - arguments(" -12", "%5d", -12), - arguments(" -12", "%10d", -12), - arguments(tenMillionBlanks + "-12", "%10000003d", -12), - - arguments("1.2", "%1.1f", 1.2), - arguments("1.2", "%2.1f", 1.2), - arguments("1.2", "%3.1f", 1.2), - arguments(" 1.2", "%4.1f", 1.2), - arguments(" 1.2", "%5.1f", 1.2), - arguments(" 1.2", "%10.1f", 1.2), - arguments(tenMillionBlanks + "1.2", "%10000003.1f", 1.2), - - arguments("-1.2", "%1.1f", -1.2), - arguments("-1.2", "%2.1f", -1.2), - arguments("-1.2", "%3.1f", -1.2), - arguments("-1.2", "%4.1f", -1.2), - arguments(" -1.2", "%5.1f", -1.2), - arguments(" -1.2", "%10.1f", -1.2), - arguments(tenMillionBlanks + "-1.2", "%10000004.1f", -1.2), - - /* blank padding, right adjusted, mandatory plus sign */ - arguments("+12", "%+1d", 12), - arguments("+12", "%+2d", 12), - arguments("+12", "%+3d", 12), - arguments(" +12", "%+4d", 12), - arguments(" +12", "%+5d", 12), - arguments(" +12", "%+10d", 12), - arguments(tenMillionBlanks + "+12", "%+10000003d", 12), - - arguments("-12", "%+1d", -12), - arguments("-12", "%+2d", -12), - arguments("-12", "%+3d", -12), - arguments(" -12", "%+4d", -12), - arguments(" -12", "%+5d", -12), - arguments(" -12", "%+10d", -12), - arguments(tenMillionBlanks + "-12", "%+10000003d", -12), - - arguments("+1.2", "%+1.1f", 1.2), - arguments("+1.2", "%+2.1f", 1.2), - arguments("+1.2", "%+3.1f", 1.2), - arguments("+1.2", "%+4.1f", 1.2), - arguments(" +1.2", "%+5.1f", 1.2), - arguments(" +1.2", "%+10.1f", 1.2), - arguments(tenMillionBlanks + "+1.2", "%+10000004.1f", 1.2), - - arguments("-1.2", "%+1.1f", -1.2), - arguments("-1.2", "%+2.1f", -1.2), - arguments("-1.2", "%+3.1f", -1.2), - arguments("-1.2", "%+4.1f", -1.2), - arguments(" -1.2", "%+5.1f", -1.2), - arguments(" -1.2", "%+10.1f", -1.2), - arguments(tenMillionBlanks + "-1.2", "%+10000004.1f", -1.2), - - /* blank padding, right adjusted, mandatory blank sign */ - arguments(" 12", "% 1d", 12), - arguments(" 12", "% 2d", 12), - arguments(" 12", "% 3d", 12), - arguments(" 12", "% 4d", 12), - arguments(" 12", "% 5d", 12), - arguments(" 12", "% 10d", 12), - arguments(tenMillionBlanks + "12", "% 10000002d", 12), - - arguments("-12", "% 1d", -12), - arguments("-12", "% 2d", -12), - arguments("-12", "% 3d", -12), - arguments(" -12", "% 4d", -12), - arguments(" -12", "% 5d", -12), - arguments(" -12", "% 10d", -12), - arguments(tenMillionBlanks + "-12", "% 10000003d", -12), - - arguments(" 1.2", "% 1.1f", 1.2), - arguments(" 1.2", "% 2.1f", 1.2), - arguments(" 1.2", "% 3.1f", 1.2), - arguments(" 1.2", "% 4.1f", 1.2), - arguments(" 1.2", "% 5.1f", 1.2), - arguments(" 1.2", "% 10.1f", 1.2), - arguments(tenMillionBlanks + "1.2", "% 10000003.1f", 1.2), - - arguments("-1.2", "% 1.1f", -1.2), - arguments("-1.2", "% 2.1f", -1.2), - arguments("-1.2", "% 3.1f", -1.2), - arguments("-1.2", "% 4.1f", -1.2), - arguments(" -1.2", "% 5.1f", -1.2), - arguments(" -1.2", "% 10.1f", -1.2), - arguments(tenMillionBlanks + "-1.2", "% 10000004.1f", -1.2), - - /* blank padding, left adjusted, optional sign */ - arguments("12", "%-1d", 12), - arguments("12", "%-2d", 12), - arguments("12 ", "%-3d", 12), - arguments("12 ", "%-4d", 12), - arguments("12 ", "%-5d", 12), - arguments("12 ", "%-10d", 12), - arguments("12" + tenMillionBlanks, "%-10000002d", 12), - - arguments("-12", "%-1d", -12), - arguments("-12", "%-2d", -12), - arguments("-12", "%-3d", -12), - arguments("-12 ", "%-4d", -12), - arguments("-12 ", "%-5d", -12), - arguments("-12 ", "%-10d", -12), - arguments("-12" + tenMillionBlanks, "%-10000003d", -12), - - arguments("1.2", "%-1.1f", 1.2), - arguments("1.2", "%-2.1f", 1.2), - arguments("1.2", "%-3.1f", 1.2), - arguments("1.2 ", "%-4.1f", 1.2), - arguments("1.2 ", "%-5.1f", 1.2), - arguments("1.2 ", "%-10.1f", 1.2), - arguments("1.2" + tenMillionBlanks, "%-10000003.1f", 1.2), - - arguments("-1.2", "%-1.1f", -1.2), - arguments("-1.2", "%-2.1f", -1.2), - arguments("-1.2", "%-3.1f", -1.2), - arguments("-1.2", "%-4.1f", -1.2), - arguments("-1.2 ", "%-5.1f", -1.2), - arguments("-1.2 ", "%-10.1f", -1.2), - arguments("-1.2" + tenMillionBlanks, "%-10000004.1f", -1.2), - - /* blank padding, left adjusted, mandatory plus sign */ - arguments("+12", "%-+1d", 12), - arguments("+12", "%-+2d", 12), - arguments("+12", "%-+3d", 12), - arguments("+12 ", "%-+4d", 12), - arguments("+12 ", "%-+5d", 12), - arguments("+12 ", "%-+10d", 12), - arguments("+12" + tenMillionBlanks, "%-+10000003d", 12), - - arguments("-12", "%-+1d", -12), - arguments("-12", "%-+2d", -12), - arguments("-12", "%-+3d", -12), - arguments("-12 ", "%-+4d", -12), - arguments("-12 ", "%-+5d", -12), - arguments("-12 ", "%-+10d", -12), - arguments("-12" + tenMillionBlanks, "%-+10000003d", -12), - - arguments("+1.2", "%-+1.1f", 1.2), - arguments("+1.2", "%-+2.1f", 1.2), - arguments("+1.2", "%-+3.1f", 1.2), - arguments("+1.2", "%-+4.1f", 1.2), - arguments("+1.2 ", "%-+5.1f", 1.2), - arguments("+1.2 ", "%-+10.1f", 1.2), - arguments("+1.2" + tenMillionBlanks, "%-+10000004.1f", 1.2), - - arguments("-1.2", "%-+1.1f", -1.2), - arguments("-1.2", "%-+2.1f", -1.2), - arguments("-1.2", "%-+3.1f", -1.2), - arguments("-1.2", "%-+4.1f", -1.2), - arguments("-1.2 ", "%-+5.1f", -1.2), - arguments("-1.2 ", "%-+10.1f", -1.2), - arguments("-1.2" + tenMillionBlanks, "%-+10000004.1f", -1.2), - - /* blank padding, left adjusted, mandatory blank sign */ - arguments(" 12", "%- 1d", 12), - arguments(" 12", "%- 2d", 12), - arguments(" 12", "%- 3d", 12), - arguments(" 12 ", "%- 4d", 12), - arguments(" 12 ", "%- 5d", 12), - arguments(" 12 ", "%- 10d", 12), - arguments(" 12" + tenMillionBlanks, "%- 10000003d", 12), - - arguments("-12", "%- 1d", -12), - arguments("-12", "%- 2d", -12), - arguments("-12", "%- 3d", -12), - arguments("-12 ", "%- 4d", -12), - arguments("-12 ", "%- 5d", -12), - arguments("-12 ", "%- 10d", -12), - arguments("-12" + tenMillionBlanks, "%- 10000003d", -12), - - arguments(" 1.2", "%- 1.1f", 1.2), - arguments(" 1.2", "%- 2.1f", 1.2), - arguments(" 1.2", "%- 3.1f", 1.2), - arguments(" 1.2", "%- 4.1f", 1.2), - arguments(" 1.2 ", "%- 5.1f", 1.2), - arguments(" 1.2 ", "%- 10.1f", 1.2), - arguments(" 1.2" + tenMillionBlanks, "%- 10000004.1f", 1.2), - - arguments("-1.2", "%- 1.1f", -1.2), - arguments("-1.2", "%- 2.1f", -1.2), - arguments("-1.2", "%- 3.1f", -1.2), - arguments("-1.2", "%- 4.1f", -1.2), - arguments("-1.2 ", "%- 5.1f", -1.2), - arguments("-1.2 ", "%- 10.1f", -1.2), - arguments("-1.2" + tenMillionBlanks, "%- 10000004.1f", -1.2), - - /* zero padding, right adjusted, optional sign */ - arguments("12", "%01d", 12), - arguments("12", "%02d", 12), - arguments("012", "%03d", 12), - arguments("0012", "%04d", 12), - arguments("00012", "%05d", 12), - arguments("0000000012", "%010d", 12), - arguments(tenMillionZeros + "12", "%010000002d", 12), - - arguments("-12", "%01d", -12), - arguments("-12", "%02d", -12), - arguments("-12", "%03d", -12), - arguments("-012", "%04d", -12), - arguments("-0012", "%05d", -12), - arguments("-000000012", "%010d", -12), - arguments("-" + tenMillionZeros + "12", "%010000003d", -12), - - arguments("1.2", "%01.1f", 1.2), - arguments("1.2", "%02.1f", 1.2), - arguments("1.2", "%03.1f", 1.2), - arguments("01.2", "%04.1f", 1.2), - arguments("001.2", "%05.1f", 1.2), - arguments("00000001.2", "%010.1f", 1.2), - arguments(tenMillionZeros + "1.2", "%010000003.1f", 1.2), - - arguments("-1.2", "%01.1f", -1.2), - arguments("-1.2", "%02.1f", -1.2), - arguments("-1.2", "%03.1f", -1.2), - arguments("-1.2", "%04.1f", -1.2), - arguments("-01.2", "%05.1f", -1.2), - arguments("-0000001.2", "%010.1f", -1.2), - arguments("-" + tenMillionZeros + "1.2", "%010000004.1f", -1.2), - - /* zero padding, right adjusted, mandatory plus sign */ - arguments("+12", "%+01d", 12), - arguments("+12", "%+02d", 12), - arguments("+12", "%+03d", 12), - arguments("+012", "%+04d", 12), - arguments("+0012", "%+05d", 12), - arguments("+000000012", "%+010d", 12), - arguments("+" + tenMillionZeros + "12", "%+010000003d", 12), - - arguments("-12", "%+01d", -12), - arguments("-12", "%+02d", -12), - arguments("-12", "%+03d", -12), - arguments("-012", "%+04d", -12), - arguments("-0012", "%+05d", -12), - arguments("-000000012", "%+010d", -12), - arguments("-" + tenMillionZeros + "12", "%+010000003d", -12), - - arguments("+1.2", "%+01.1f", 1.2), - arguments("+1.2", "%+02.1f", 1.2), - arguments("+1.2", "%+03.1f", 1.2), - arguments("+1.2", "%+04.1f", 1.2), - arguments("+01.2", "%+05.1f", 1.2), - arguments("+0000001.2", "%+010.1f", 1.2), - arguments("+" + tenMillionZeros + "1.2", "%+010000004.1f", 1.2), - - arguments("-1.2", "%+01.1f", -1.2), - arguments("-1.2", "%+02.1f", -1.2), - arguments("-1.2", "%+03.1f", -1.2), - arguments("-1.2", "%+04.1f", -1.2), - arguments("-01.2", "%+05.1f", -1.2), - arguments("-0000001.2", "%+010.1f", -1.2), - arguments("-" + tenMillionZeros + "1.2", "%+010000004.1f", -1.2), - - /* zero padding, right adjusted, mandatory blank sign */ - arguments(" 12", "% 01d", 12), - arguments(" 12", "% 02d", 12), - arguments(" 12", "% 03d", 12), - arguments(" 012", "% 04d", 12), - arguments(" 0012", "% 05d", 12), - arguments(" 000000012", "% 010d", 12), - arguments(" " + tenMillionZeros + "12", "% 010000003d", 12), - - arguments("-12", "% 01d", -12), - arguments("-12", "% 02d", -12), - arguments("-12", "% 03d", -12), - arguments("-012", "% 04d", -12), - arguments("-0012", "% 05d", -12), - arguments("-000000012", "% 010d", -12), - arguments("-" + tenMillionZeros + "12", "% 010000003d", -12), - - arguments(" 1.2", "% 01.1f", 1.2), - arguments(" 1.2", "% 02.1f", 1.2), - arguments(" 1.2", "% 03.1f", 1.2), - arguments(" 1.2", "% 04.1f", 1.2), - arguments(" 01.2", "% 05.1f", 1.2), - arguments(" 0000001.2", "% 010.1f", 1.2), - arguments(" " + tenMillionZeros + "1.2", "% 010000004.1f", 1.2), - - arguments("-1.2", "% 01.1f", -1.2), - arguments("-1.2", "% 02.1f", -1.2), - arguments("-1.2", "% 03.1f", -1.2), - arguments("-1.2", "% 04.1f", -1.2), - arguments("-01.2", "% 05.1f", -1.2), - arguments("-0000001.2", "% 010.1f", -1.2), - arguments("-" + tenMillionZeros + "1.2", "% 010000004.1f", -1.2), - - }; + /* blank padding, left adjusted, mandatory sign */ + static Stream blankPaddingLeftAdjustedMandatorySign() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of("+12", "%-+1d", 12), + Arguments.of("+12", "%-+2d", 12), + Arguments.of("+12", "%-+3d", 12), + Arguments.of("+12 ", "%-+4d", 12), + Arguments.of("+12 ", "%-+5d", 12), + Arguments.of("+12 ", "%-+10d", 12), + Arguments.of("+12" + tenMillionBlanks, "%-+10000003d", 12), + + Arguments.of("-12", "%-+1d", -12), + Arguments.of("-12", "%-+2d", -12), + Arguments.of("-12", "%-+3d", -12), + Arguments.of("-12 ", "%-+4d", -12), + Arguments.of("-12 ", "%-+5d", -12), + Arguments.of("-12 ", "%-+10d", -12), + Arguments.of("-12" + tenMillionBlanks, "%-+10000003d", -12), + + Arguments.of("+1.2", "%-+1.1f", 1.2), + Arguments.of("+1.2", "%-+2.1f", 1.2), + Arguments.of("+1.2", "%-+3.1f", 1.2), + Arguments.of("+1.2", "%-+4.1f", 1.2), + Arguments.of("+1.2 ", "%-+5.1f", 1.2), + Arguments.of("+1.2 ", "%-+10.1f", 1.2), + Arguments.of("+1.2" + tenMillionBlanks, "%-+10000004.1f", 1.2), + + Arguments.of("-1.2", "%-+1.1f", -1.2), + Arguments.of("-1.2", "%-+2.1f", -1.2), + Arguments.of("-1.2", "%-+3.1f", -1.2), + Arguments.of("-1.2", "%-+4.1f", -1.2), + Arguments.of("-1.2 ", "%-+5.1f", -1.2), + Arguments.of("-1.2 ", "%-+10.1f", -1.2), + Arguments.of("-1.2" + tenMillionBlanks, "%-+10000004.1f", -1.2)); } @ParameterizedTest @MethodSource - void padding(String expected, String format, Object value) { + void blankPaddingLeftAdjustedMandatorySign(String expected, String format, Object value) { assertEquals(expected, String.format(Locale.US, format, value)); } + /* blank padding, left adjusted, mandatory blank sign */ + static Stream blankPaddingLeftAdjustedMandatoryBlank() { + var tenMillionBlanks = " ".repeat(10_000_000); + return Stream.of( + Arguments.of(" 12", "%- 1d", 12), + Arguments.of(" 12", "%- 2d", 12), + Arguments.of(" 12", "%- 3d", 12), + Arguments.of(" 12 ", "%- 4d", 12), + Arguments.of(" 12 ", "%- 5d", 12), + Arguments.of(" 12 ", "%- 10d", 12), + Arguments.of(" 12" + tenMillionBlanks, "%- 10000003d", 12), + + Arguments.of("-12", "%- 1d", -12), + Arguments.of("-12", "%- 2d", -12), + Arguments.of("-12", "%- 3d", -12), + Arguments.of("-12 ", "%- 4d", -12), + Arguments.of("-12 ", "%- 5d", -12), + Arguments.of("-12 ", "%- 10d", -12), + Arguments.of("-12" + tenMillionBlanks, "%- 10000003d", -12), + + Arguments.of(" 1.2", "%- 1.1f", 1.2), + Arguments.of(" 1.2", "%- 2.1f", 1.2), + Arguments.of(" 1.2", "%- 3.1f", 1.2), + Arguments.of(" 1.2", "%- 4.1f", 1.2), + Arguments.of(" 1.2 ", "%- 5.1f", 1.2), + Arguments.of(" 1.2 ", "%- 10.1f", 1.2), + Arguments.of(" 1.2" + tenMillionBlanks, "%- 10000004.1f", 1.2), + + Arguments.of("-1.2", "%- 1.1f", -1.2), + Arguments.of("-1.2", "%- 2.1f", -1.2), + Arguments.of("-1.2", "%- 3.1f", -1.2), + Arguments.of("-1.2", "%- 4.1f", -1.2), + Arguments.of("-1.2 ", "%- 5.1f", -1.2), + Arguments.of("-1.2 ", "%- 10.1f", -1.2), + Arguments.of("-1.2" + tenMillionBlanks, "%- 10000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void blankPaddingLeftAdjustedMandatoryBlank(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* zero padding, right adjusted, optional sign */ + static Stream zeroPaddingRightAdjustedOptionalSign() { + var tenMillionZeros = "0".repeat(10_000_000); + return Stream.of( + Arguments.of("12", "%01d", 12), + Arguments.of("12", "%02d", 12), + Arguments.of("012", "%03d", 12), + Arguments.of("0012", "%04d", 12), + Arguments.of("00012", "%05d", 12), + Arguments.of("0000000012", "%010d", 12), + Arguments.of(tenMillionZeros + "12", "%010000002d", 12), + + Arguments.of("-12", "%01d", -12), + Arguments.of("-12", "%02d", -12), + Arguments.of("-12", "%03d", -12), + Arguments.of("-012", "%04d", -12), + Arguments.of("-0012", "%05d", -12), + Arguments.of("-000000012", "%010d", -12), + Arguments.of("-" + tenMillionZeros + "12", "%010000003d", -12), + + Arguments.of("1.2", "%01.1f", 1.2), + Arguments.of("1.2", "%02.1f", 1.2), + Arguments.of("1.2", "%03.1f", 1.2), + Arguments.of("01.2", "%04.1f", 1.2), + Arguments.of("001.2", "%05.1f", 1.2), + Arguments.of("00000001.2", "%010.1f", 1.2), + Arguments.of(tenMillionZeros + "1.2", "%010000003.1f", 1.2), + + Arguments.of("-1.2", "%01.1f", -1.2), + Arguments.of("-1.2", "%02.1f", -1.2), + Arguments.of("-1.2", "%03.1f", -1.2), + Arguments.of("-1.2", "%04.1f", -1.2), + Arguments.of("-01.2", "%05.1f", -1.2), + Arguments.of("-0000001.2", "%010.1f", -1.2), + Arguments.of("-" + tenMillionZeros + "1.2", "%010000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void zeroPaddingRightAdjustedOptionalSign(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* zero padding, right adjusted, mandatory sign */ + static Stream zeroPaddingRightAdjustedMandatorySign() { + var tenMillionZeros = "0".repeat(10_000_000); + return Stream.of( + Arguments.of("+12", "%+01d", 12), + Arguments.of("+12", "%+02d", 12), + Arguments.of("+12", "%+03d", 12), + Arguments.of("+012", "%+04d", 12), + Arguments.of("+0012", "%+05d", 12), + Arguments.of("+000000012", "%+010d", 12), + Arguments.of("+" + tenMillionZeros + "12", "%+010000003d", 12), + + Arguments.of("-12", "%+01d", -12), + Arguments.of("-12", "%+02d", -12), + Arguments.of("-12", "%+03d", -12), + Arguments.of("-012", "%+04d", -12), + Arguments.of("-0012", "%+05d", -12), + Arguments.of("-000000012", "%+010d", -12), + Arguments.of("-" + tenMillionZeros + "12", "%+010000003d", -12), + + Arguments.of("+1.2", "%+01.1f", 1.2), + Arguments.of("+1.2", "%+02.1f", 1.2), + Arguments.of("+1.2", "%+03.1f", 1.2), + Arguments.of("+1.2", "%+04.1f", 1.2), + Arguments.of("+01.2", "%+05.1f", 1.2), + Arguments.of("+0000001.2", "%+010.1f", 1.2), + Arguments.of("+" + tenMillionZeros + "1.2", "%+010000004.1f", 1.2), + + Arguments.of("-1.2", "%+01.1f", -1.2), + Arguments.of("-1.2", "%+02.1f", -1.2), + Arguments.of("-1.2", "%+03.1f", -1.2), + Arguments.of("-1.2", "%+04.1f", -1.2), + Arguments.of("-01.2", "%+05.1f", -1.2), + Arguments.of("-0000001.2", "%+010.1f", -1.2), + Arguments.of("-" + tenMillionZeros + "1.2", "%+010000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void zeroPaddingRightAdjustedMandatorySign(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } + + /* zero padding, right adjusted, mandatory blank sign */ + static Stream zeroPaddingRightAdjustedMandatoryBlank() { + var tenMillionZeros = "0".repeat(10_000_000); + return Stream.of( + Arguments.of(" 12", "% 01d", 12), + Arguments.of(" 12", "% 02d", 12), + Arguments.of(" 12", "% 03d", 12), + Arguments.of(" 012", "% 04d", 12), + Arguments.of(" 0012", "% 05d", 12), + Arguments.of(" 000000012", "% 010d", 12), + Arguments.of(" " + tenMillionZeros + "12", "% 010000003d", 12), + + Arguments.of("-12", "% 01d", -12), + Arguments.of("-12", "% 02d", -12), + Arguments.of("-12", "% 03d", -12), + Arguments.of("-012", "% 04d", -12), + Arguments.of("-0012", "% 05d", -12), + Arguments.of("-000000012", "% 010d", -12), + Arguments.of("-" + tenMillionZeros + "12", "% 010000003d", -12), + + Arguments.of(" 1.2", "% 01.1f", 1.2), + Arguments.of(" 1.2", "% 02.1f", 1.2), + Arguments.of(" 1.2", "% 03.1f", 1.2), + Arguments.of(" 1.2", "% 04.1f", 1.2), + Arguments.of(" 01.2", "% 05.1f", 1.2), + Arguments.of(" 0000001.2", "% 010.1f", 1.2), + Arguments.of(" " + tenMillionZeros + "1.2", "% 010000004.1f", 1.2), + + Arguments.of("-1.2", "% 01.1f", -1.2), + Arguments.of("-1.2", "% 02.1f", -1.2), + Arguments.of("-1.2", "% 03.1f", -1.2), + Arguments.of("-1.2", "% 04.1f", -1.2), + Arguments.of("-01.2", "% 05.1f", -1.2), + Arguments.of("-0000001.2", "% 010.1f", -1.2), + Arguments.of("-" + tenMillionZeros + "1.2", "% 010000004.1f", -1.2)); + } + + @ParameterizedTest + @MethodSource + void zeroPaddingRightAdjustedMandatoryBlank(String expected, String format, Object value) { + assertEquals(expected, String.format(Locale.US, format, value)); + } } From 249d89632c8e78b301c419678081796bf273e285 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 10 Apr 2024 18:13:01 +0000 Subject: [PATCH 172/298] 8328702: C2: Crash during parsing because sub type check is not folded Backport-of: e5e21a8a6e64466f9cda2064aa2723a15d4ae86a --- src/hotspot/share/opto/graphKit.cpp | 13 +- src/hotspot/share/opto/type.cpp | 11 +- .../TestSubTypeCheckWithBottomArray.java | 121 ++++++++++++++++++ 3 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/types/TestSubTypeCheckWithBottomArray.java diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 1c60de9b9d8..53454cfdece 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -2702,7 +2702,18 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, No // Foo[] fa = blah(); Foo x = fa[0]; fa[1] = x; // Here, the type of 'fa' is often exact, so the store check // of fa[1]=x will fold up, without testing the nullness of x. - switch (C->static_subtype_check(superk, subk)) { + // + // Do not skip the static sub type check with StressReflectiveCode during + // parsing (i.e. with ExpandSubTypeCheckAtParseTime) because the + // associated CheckCastNodePP could already be folded when the type + // system can prove it's an impossible type. Therefore, we should also + // do the static sub type check here to ensure control is folded as well. + // Otherwise, the graph is left in a broken state. + // At macro expansion, we would have already folded the SubTypeCheckNode + // being expanded here because we always perform the static sub type + // check in SubTypeCheckNode::sub() regardless of whether + // StressReflectiveCode is set or not. + switch (C->static_subtype_check(superk, subk, !ExpandSubTypeCheckAtParseTime)) { case Compile::SSC_always_false: { Node* always_fail = *ctrl; diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index 4e0bd43be5c..5a764f7cad1 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -6458,14 +6458,19 @@ template bool TypePtr::maybe_java_subtype_of_helper_for_arr if (other->klass() == ciEnv::current()->Object_klass() && other->_interfaces->empty() && other_exact) { return true; } - int dummy; - bool this_top_or_bottom = (this_one->base_element_type(dummy) == Type::TOP || this_one->base_element_type(dummy) == Type::BOTTOM); - if (!this_one->is_loaded() || !other->is_loaded() || this_top_or_bottom) { + if (!this_one->is_loaded() || !other->is_loaded()) { return true; } if (this_one->is_instance_type(other)) { return other->klass()->equals(ciEnv::current()->Object_klass()) && other->_interfaces->intersection_with(this_one->_interfaces)->eq(other->_interfaces); } + + int dummy; + bool this_top_or_bottom = (this_one->base_element_type(dummy) == Type::TOP || this_one->base_element_type(dummy) == Type::BOTTOM); + if (this_top_or_bottom) { + return true; + } + assert(this_one->is_array_type(other), ""); const T1* other_ary = this_one->is_array_type(other); diff --git a/test/hotspot/jtreg/compiler/types/TestSubTypeCheckWithBottomArray.java b/test/hotspot/jtreg/compiler/types/TestSubTypeCheckWithBottomArray.java new file mode 100644 index 00000000000..a9cb3d7e6c8 --- /dev/null +++ b/test/hotspot/jtreg/compiler/types/TestSubTypeCheckWithBottomArray.java @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/* + * @test id=Xcomp + * @bug 8328702 + * @summary Check that SubTypeCheckNode is properly folded when having an array with bottom type elements checked + * against an interface. + * + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,compiler.types.TestSubTypeCheckWithBottomArray::test* + * -XX:CompileCommand=inline,compiler.types.TestSubTypeCheckWithBottomArray::check* + * compiler.types.TestSubTypeCheckWithBottomArray + */ + +/* + * @test id=Xbatch + * @bug 8328702 + * @summary Check that SubTypeCheckNode is properly folded when having an array with bottom type elements checked + * against an interface. + * + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.types.TestSubTypeCheckWithBottomArray::test* + * -XX:CompileCommand=inline,compiler.types.TestSubTypeCheckWithBottomArray::check* + * compiler.types.TestSubTypeCheckWithBottomArray + */ + +/* + * @test id=stress + * @bug 8328702 + * @summary Check that PartialSubtypeCheckNode is properly folded when having an array with bottom type elements checked + * either against an interface or an unrelated non-sub-class. + * + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,compiler.types.TestSubTypeCheckWithBottomArray::test* + * -XX:+UnlockDiagnosticVMOptions -XX:+ExpandSubTypeCheckAtParseTime + * -XX:+IgnoreUnrecognizedVMOptions -XX:+StressReflectiveCode + * -XX:CompileCommand=inline,compiler.types.TestSubTypeCheckWithBottomArray::check* + * compiler.types.TestSubTypeCheckWithBottomArray + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.types.TestSubTypeCheckWithBottomArray::test* + * -XX:+UnlockDiagnosticVMOptions -XX:+ExpandSubTypeCheckAtParseTime + * -XX:+IgnoreUnrecognizedVMOptions -XX:+StressReflectiveCode + * -XX:CompileCommand=inline,compiler.types.TestSubTypeCheckWithBottomArray::check* + * compiler.types.TestSubTypeCheckWithBottomArray + */ + +package compiler.types; + +public class TestSubTypeCheckWithBottomArray { + static byte[] bArr = new byte[10]; + static Object[] oArr = new Object[10]; + static boolean flag; + + public static void main(String[] args) { + A a = new A(); + B b = new B(); + Y y = new Y(); + Z z = new Z(); + for (int i = 0; i < 10000; i++) { + // With -Xcomp: Immediatly crashes because of no profiling -> don't know anything. + checkInterface(a); // Make sure that checkInterface() sometimes passes instanceof. + checkInterface(b); // Use two sub classes such that checkcast is required. + testInterface(); + + checkClass(y); // Make sure that checkClass() sometimes passes instanceof. + checkClass(z); // Use two sub classes such that checkcast is required. + testClass(); + flag = !flag; + } + } + + static void testInterface() { + checkInterface(flag ? bArr : oArr); // Inlined, never passes instanceof + } + + static void checkInterface(Object o) { + if (o instanceof I i) { + // Use of i: Needs CheckCastPP which is replaced by top because [bottom <: I cannot be true. + // But: SubTypeCheckNode is not folded away -> broken graph (data dies, control not) + i.getClass(); + } + } + + static void testClass() { + checkClass(flag ? bArr : oArr); // Inlined, never passes instanceof + } + + static void checkClass(Object o) { + if (o instanceof X x) { + // Use of i: Needs CheckCastPP which is replaced by top because [bottom <: I cannot be true. + // But: SubTypeCheckNode is not folded away -> broken graph (data dies, control not) + x.getClass(); + } + } + +} + +interface I {} +class A implements I {} +class B implements I {} + +class X {} +class Y extends X {} +class Z extends X {} From fb10dd97ed3fcfe2adfbdeff916a45f378ea2da9 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 11 Apr 2024 02:01:33 +0000 Subject: [PATCH 173/298] 8281658: Add a security category to the java -XshowSettings option Backport-of: 2e12a123c9955b7360fd752a6a33d59b6271c5af --- .../classes/sun/launcher/LauncherHelper.java | 12 +- .../sun/launcher/SecuritySettings.java | 217 ++++++++++++++++++ .../launcher/resources/launcher.properties | 10 + .../security/Security/ConfigFileTest.java | 18 +- test/jdk/tools/launcher/Settings.java | 67 +++++- 5 files changed, 318 insertions(+), 6 deletions(-) create mode 100644 src/java.base/share/classes/sun/launcher/SecuritySettings.java diff --git a/src/java.base/share/classes/sun/launcher/LauncherHelper.java b/src/java.base/share/classes/sun/launcher/LauncherHelper.java index abd0acbf75c..8985077df37 100644 --- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java +++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java @@ -47,8 +47,8 @@ import java.lang.module.ModuleFinder; import java.lang.module.ModuleReference; import java.lang.module.ResolvedModule; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; @@ -78,7 +78,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.internal.util.OperatingSystem; import jdk.internal.misc.MainMethodFinder; import jdk.internal.misc.PreviewFeatures; import jdk.internal.misc.VM; @@ -86,6 +85,7 @@ import jdk.internal.module.Modules; import jdk.internal.platform.Container; import jdk.internal.platform.Metrics; +import jdk.internal.util.OperatingSystem; import sun.util.calendar.ZoneInfoFile; /** @@ -172,6 +172,10 @@ static void showSettings(boolean printToStderr, String optionFlag, case "locale": printLocale(); break; + case "security": + var opt = opts.length > 2 ? opts[2].trim() : "all"; + SecuritySettings.printSecuritySettings(opt, ostream); + break; case "system": if (OperatingSystem.isLinux()) { printSystemMetrics(); @@ -181,6 +185,7 @@ static void showSettings(boolean printToStderr, String optionFlag, printVmSettings(initialHeapSize, maxHeapSize, stackSize); printProperties(); printLocale(); + SecuritySettings.printSecuritySummarySettings(ostream); if (OperatingSystem.isLinux()) { printSystemMetrics(); } @@ -318,9 +323,10 @@ private static void printLocales() { ostream.print(INDENT + INDENT); } } + ostream.println(); } - public static void printSystemMetrics() { + private static void printSystemMetrics() { Metrics c = Container.metrics(); ostream.println("Operating System Metrics:"); diff --git a/src/java.base/share/classes/sun/launcher/SecuritySettings.java b/src/java.base/share/classes/sun/launcher/SecuritySettings.java new file mode 100644 index 00000000000..c2bc67761c2 --- /dev/null +++ b/src/java.base/share/classes/sun/launcher/SecuritySettings.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023, 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 sun.launcher; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.io.PrintStream; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.stream.Collectors; + +import jdk.internal.access.SharedSecrets; + +/** + * A utility class for security libs functionality + * in the -XshowSettings:security output + */ +public final class SecuritySettings { + + private static final String INDENT = " "; + private static final String TWOINDENT = INDENT + INDENT; + private static final String THREEINDENT = TWOINDENT + INDENT; + private static final String PROV_INFO_STRING = "Provider information: "; + private static PrintStream ostream = null; + + static void printSecuritySettings(String arg, PrintStream stream) { + ostream = stream; + switch (arg) { + case "properties" -> printSecurityProperties(); + case "providers" -> printSecurityProviderConfig(true); + case "tls" -> printSecurityTLSConfig(true); + case "all" -> printAllSecurityConfig(); + default -> ostream.println( + "\nUnrecognized security subcommand. Valid values are " + + "\"all\", \"properties\", \"providers\", \"tls\". See \"java -X\"\n"); + } + } + + // A non-verbose description of some core security configuration settings + static void printSecuritySummarySettings(PrintStream stream) { + ostream = stream; + ostream.println("Security settings summary: " + "\n" + + INDENT + "See \"java -X\" for verbose security settings options"); + printSecurityProviderConfig(false); + printSecurityTLSConfig(false); + } + + static void printAllSecurityConfig() { + ostream.println("Security settings:"); + printSecurityProperties(); + printSecurityProviderConfig(true); + printSecurityTLSConfig(true); + } + + private static void printSecurityProperties() { + ostream.println(INDENT + "Security properties:"); + Properties p = SharedSecrets.getJavaSecurityPropertiesAccess().getInitialProperties(); + for (String key : p.stringPropertyNames().stream().sorted().toList()) { + String val = p.getProperty(key); + if (val.length() > 60) { + splitLongPropertyLines(key, val); + } else { + ostream.println(TWOINDENT + key + "=" + val); + } + } + ostream.println(); + } + + private static void splitLongPropertyLines(String key, String val) { + // split long property values which use well known separator + if (val.contains(",") || val.contains(";")) { + String separator = (val.contains(",")) ? "," : ";"; + ostream.println(TWOINDENT + key + "="); + String[] values = val.split(separator); + String lastValue = values[values.length -1].trim(); + List.of(values).forEach( + s -> ostream.println(THREEINDENT + s.trim() + + (s.trim().equals(lastValue) ? "" : separator))); + } else { + ostream.println(TWOINDENT + key + "=" + val); + } + } + + private static void printSecurityTLSConfig(boolean verbose) { + SSLSocket ssls; + SSLContext sslContext; + try { + sslContext = SSLContext.getDefault(); + ssls = (SSLSocket)sslContext.getSocketFactory().createSocket(); + } catch (IOException | NoSuchAlgorithmException e) { + ostream.println(INDENT + "Failed to create SSL socket"); + ostream.println(INDENT + e + "\n"); + return; + } + + ostream.println(INDENT + "Security TLS configuration (" + + sslContext.getProvider().getName() + " provider):"); + ostream.println(TWOINDENT + "Enabled Protocols:"); + for (String s : ssls.getEnabledProtocols()) { + ostream.println(THREEINDENT + s); + } + + if (verbose) { + ostream.println("\n" + TWOINDENT + "Enabled Cipher Suites:"); + for (String s : ssls.getEnabledCipherSuites()) { + ostream.println(THREEINDENT + s); + } + } + ostream.println(); + } + + private static void printSecurityProviderConfig(boolean verbose) { + ostream.println(INDENT + "Security provider static configuration: (in order of preference)"); + for (Provider p : Security.getProviders()) { + if (verbose) { + // separate the views out + ostream.println(TWOINDENT + "-".repeat(40)); + } + ostream.println(TWOINDENT + "Provider name: " + p.getName()); + if (verbose) { + ostream.println(wrappedString(PROV_INFO_STRING + p.getInfo(), 80, + TWOINDENT, THREEINDENT)); + ostream.println(TWOINDENT + "Provider services: (type : algorithm)"); + Set services = p.getServices(); + Set keys = Collections.list(p.keys()) + .stream() + .map(String.class::cast) + .filter(s -> s.startsWith("Alg.Alias.")) + .collect(Collectors.toSet()); + if (!services.isEmpty()) { + services.stream() + .sorted(Comparator.comparing(Provider.Service::getType) + .thenComparing(Provider.Service::getAlgorithm)) + .forEach(ps -> { + ostream.println(THREEINDENT + + ps.getType() + "." + ps.getAlgorithm()); + List aliases = keys + .stream() + .filter(s -> s.startsWith("Alg.Alias." + ps.getType())) + .filter(s -> p.getProperty(s).equals(ps.getAlgorithm())) + .map(s -> s.substring(("Alg.Alias." + ps.getType() + ".").length())) + .toList(); + + if (!aliases.isEmpty()) { + ostream.println(wrappedString( + aliases.stream() + .collect(Collectors.joining(", ", INDENT + " aliases: [", "]")), + 80, " " + TWOINDENT, INDENT + THREEINDENT)); + } + }); + } else { + ostream.println(THREEINDENT + ""); + } + } + } + if (verbose) { + ostream.println(); + } + } + + // return a string split across multiple lines which aims to limit max length + private static String wrappedString(String orig, int limit, + String initIndent, String successiveIndent) { + if (orig == null || orig.isEmpty() || limit <= 0) { + // bad input + return orig; + } + StringBuilder sb = new StringBuilder(); + int widthCount = 0; + for (String s : orig.split(" ")) { + if (widthCount == 0) { + // first iteration only + sb.append(initIndent + s); + widthCount = s.length() + initIndent.length(); + } else { + if (widthCount + s.length() > limit) { + sb.append("\n" + successiveIndent + s); + widthCount = s.length() + successiveIndent.length(); + } else { + sb.append(" " + s); + widthCount += s.length() + 1; + } + } + } + return sb.toString(); + } +} diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/src/java.base/share/classes/sun/launcher/resources/launcher.properties index 9960b026d11..7d10527b2a8 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -170,6 +170,16 @@ java.launcher.X.usage=\n\ \ show all property settings and continue\n\ \ -XshowSettings:vm\n\ \ show all vm related settings and continue\n\ +\ -XshowSettings:security\n\ +\ show all security settings and continue\n\ +\ -XshowSettings:security:all\n\ +\ show all security settings and continue\n\ +\ -XshowSettings:security:properties\n\ +\ show security properties and continue\n\ +\ -XshowSettings:security:providers\n\ +\ show static security provider settings and continue\n\ +\ -XshowSettings:security:tls\n\ +\ show TLS related security settings and continue\n\ \ -XshowSettings:system\n\ \ (Linux Only) show host system or container\n\ \ configuration and continue\n\ diff --git a/test/jdk/java/security/Security/ConfigFileTest.java b/test/jdk/java/security/Security/ConfigFileTest.java index e6f54a7491e..fe022fc45ce 100644 --- a/test/jdk/java/security/Security/ConfigFileTest.java +++ b/test/jdk/java/security/Security/ConfigFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -36,7 +36,7 @@ /* * @test * @summary Throw error if default java.security file is missing - * @bug 8155246 8292297 8292177 + * @bug 8155246 8292297 8292177 8281658 * @library /test/lib * @run main ConfigFileTest */ @@ -71,6 +71,10 @@ public static void main(String[] args) throws Exception { copyJDK(jdkTestDir, copyJdkDir); String extraPropsFile = Path.of(System.getProperty("test.src"), "override.props").toString(); + // sanity test -XshowSettings:security option + exerciseShowSettingsSecurity(copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-XshowSettings:security", "ConfigFileTest", "runner"); + // exercise some debug flags while we're here // regular JDK install - should expect success exerciseSecurity(0, "java", @@ -136,6 +140,16 @@ private static void exerciseSecurity(int exitCode, String output, String... args } } + // exercise the -XshowSettings:security launcher + private static void exerciseShowSettingsSecurity(String... args) throws Exception { + ProcessBuilder process = new ProcessBuilder(args); + OutputAnalyzer oa = ProcessTools.executeProcess(process); + oa.shouldHaveExitValue(0) + .shouldContain("Security properties:") + .shouldContain("Security provider static configuration:") + .shouldContain("Security TLS configuration"); + } + private static void copyJDK(Path src, Path dst) throws Exception { Files.walk(src) .skip(1) diff --git a/test/jdk/tools/launcher/Settings.java b/test/jdk/tools/launcher/Settings.java index 76e62ffbe57..29af50d5c02 100644 --- a/test/jdk/tools/launcher/Settings.java +++ b/test/jdk/tools/launcher/Settings.java @@ -25,7 +25,7 @@ /* * @test - * @bug 6994753 7123582 8305950 + * @bug 6994753 7123582 8305950 8281658 * @summary tests -XshowSettings options * @modules jdk.compiler * jdk.zipfs @@ -67,6 +67,13 @@ static void checkNotContains(TestResult tr, String str) { private static final String VM_SETTINGS = "VM settings:"; private static final String PROP_SETTINGS = "Property settings:"; private static final String LOCALE_SETTINGS = "Locale settings:"; + private static final String SEC_PROPS_SETTINGS = "Security properties:"; + private static final String SEC_SUMMARY_PROPS_SETTINGS = + "Security settings summary:"; + private static final String SEC_PROVIDER_SETTINGS = + "Security provider static configuration:"; + private static final String SEC_TLS_SETTINGS = "Security TLS configuration"; + private static final String BAD_SEC_OPTION_MSG = "Unrecognized security subcommand"; private static final String SYSTEM_SETTINGS = "Operating System Metrics:"; private static final String STACKSIZE_SETTINGS = "Stack Size:"; private static final String TZDATA_SETTINGS = "tzdata version"; @@ -75,6 +82,11 @@ static void containsAllOptions(TestResult tr) { checkContains(tr, VM_SETTINGS); checkContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); + // no verbose security settings unless "security" used + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_SUMMARY_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); checkContains(tr, TZDATA_SETTINGS); if (System.getProperty("os.name").contains("Linux")) { checkContains(tr, SYSTEM_SETTINGS); @@ -144,6 +156,54 @@ static void runTestOptionLocale() throws IOException { checkContains(tr, TZDATA_SETTINGS); } + static void runTestOptionSecurity() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security"); + checkNotContains(tr, VM_SETTINGS); + checkNotContains(tr, PROP_SETTINGS); + checkContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); + } + + static void runTestOptionSecurityProps() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:properties"); + checkContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + // test a well known property for sanity + checkContains(tr, "keystore.type=pkcs12"); + } + + static void runTestOptionSecurityProv() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:providers"); + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + // test a well known Provider for sanity + checkContains(tr, "Provider name: SUN"); + // test for a well known alias (SunJCE: AlgorithmParameterGenerator.DiffieHellman) + checkContains(tr, "aliases: [1.2.840.113549.1.3.1, " + + "DH, OID.1.2.840.113549.1.3.1]"); + } + + static void runTestOptionSecurityTLS() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:tls"); + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); + // test a well known TLS config for sanity + checkContains(tr, "TLSv1.2"); + } + + // ensure error message is printed when unrecognized option used + static void runTestOptionBadSecurityOption() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:bad"); + checkContains(tr, BAD_SEC_OPTION_MSG); + // we print all security settings in such scenario + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + } static void runTestOptionSystem() throws IOException { TestResult tr = doExec(javaCmd, "-XshowSettings:system"); if (System.getProperty("os.name").contains("Linux")) { @@ -181,6 +241,11 @@ public static void main(String... args) throws IOException { runTestOptionVM(); runTestOptionProperty(); runTestOptionLocale(); + runTestOptionSecurity(); + runTestOptionSecurityProps(); + runTestOptionSecurityProv(); + runTestOptionSecurityTLS(); + runTestOptionBadSecurityOption(); runTestOptionSystem(); runTestBadOptions(); runTest7123582(); From ba4ad2b4874482b37889576020ab846b4b75cf6d Mon Sep 17 00:00:00 2001 From: Soumadipta Roy Date: Thu, 11 Apr 2024 07:09:54 +0000 Subject: [PATCH 174/298] 8316608: Enable parallelism in vmTestbase/gc/vector tests Backport-of: f61499c73fe03e2e3680d7f58a84183364c5c5ac --- .../vector/CircularListHigh/TEST.properties | 23 ------------------- .../gc/vector/CircularListLow/TEST.properties | 23 ------------------- .../gc/vector/DoubleArrayHigh/TEST.properties | 23 ------------------- .../gc/vector/DoubleArrayLow/TEST.properties | 23 ------------------- .../gc/vector/FloatArrayHigh/TEST.properties | 23 ------------------- .../gc/vector/FloatArrayLow/TEST.properties | 23 ------------------- .../gc/vector/LinearListHigh/TEST.properties | 23 ------------------- .../gc/vector/LinearListLow/TEST.properties | 23 ------------------- .../vector/NonbranchyTreeHigh/TEST.properties | 23 ------------------- .../vector/NonbranchyTreeLow/TEST.properties | 23 ------------------- .../gc/vector/ObjectArrayHigh/TEST.properties | 23 ------------------- .../gc/vector/ObjectArrayLow/TEST.properties | 23 ------------------- .../gc/vector/SimpleGC/TEST.properties | 23 ------------------- 13 files changed, 299 deletions(-) delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. From fbb424f95d73e99c7a533ed5dae8fbb6d13dc93b Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 11 Apr 2024 08:38:52 +0000 Subject: [PATCH 175/298] 8325579: Inconsistent behavior in com.sun.jndi.ldap.Connection::createSocket Backport-of: 92d6fa4abec1fdf8e57723e4490be0ba4f97e59d --- .../classes/com/sun/jndi/ldap/Connection.java | 47 ++-- .../share/classes/module-info.java | 24 +- .../ldap/LdapSSLHandshakeFailureTest.java | 254 ++++++++++++------ 3 files changed, 210 insertions(+), 115 deletions(-) diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java index 33e4df43325..be7ebf9c574 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -120,17 +120,15 @@ public final class Connection implements Runnable { private static final boolean debug = false; - private static final int dump = 0; // > 0 r, > 1 rw - private final Thread worker; // Initialized in constructor - private boolean v3 = true; // Set in setV3() + private boolean v3 = true; // Set in setV3() public final String host; // used by LdapClient for generating exception messages - // used by StartTlsResponse when creating an SSL socket + // used by StartTlsResponse when creating an SSL socket public final int port; // used by LdapClient for generating exception messages - // used by StartTlsResponse when creating an SSL socket + // used by StartTlsResponse when creating an SSL socket private boolean bound = false; // Set in setBound() @@ -319,30 +317,37 @@ private SocketFactory getSocketFactory(String socketFactoryName) throws Exceptio } private Socket createConnectionSocket(String host, int port, SocketFactory factory, - int connectTimeout) throws Exception { + int connectTimeout) throws IOException { Socket socket = null; + // if timeout is supplied, try to use unconnected socket for connecting with timeout if (connectTimeout > 0) { - // create unconnected socket and then connect it if timeout - // is supplied - InetSocketAddress endpoint = - createInetSocketAddress(host, port); - // unconnected socket - socket = factory.createSocket(); - // connect socket with a timeout - socket.connect(endpoint, connectTimeout); if (debug) { - System.err.println("Connection: creating socket with " + - "a connect timeout"); + System.err.println("Connection: creating socket with a connect timeout"); + } + try { + // unconnected socket + socket = factory.createSocket(); + } catch (IOException e) { + // unconnected socket is likely not supported by the SocketFactory + if (debug) { + System.err.println("Connection: unconnected socket not supported by SocketFactory"); + } + } + if (socket != null) { + InetSocketAddress endpoint = createInetSocketAddress(host, port); + // connect socket with a timeout + socket.connect(endpoint, connectTimeout); } } + + // either no timeout was supplied or unconnected socket did not work if (socket == null) { // create connected socket - socket = factory.createSocket(host, port); if (debug) { - System.err.println("Connection: creating connected socket with" + - " no connect timeout"); + System.err.println("Connection: creating connected socket with no connect timeout"); } + socket = factory.createSocket(host, port); } return socket; } @@ -351,7 +356,7 @@ private Socket createConnectionSocket(String host, int port, SocketFactory facto // the SSL handshake following socket connection as part of the timeout. // So explicitly set a socket read timeout, trigger the SSL handshake, // then reset the timeout. - private void initialSSLHandshake(SSLSocket sslSocket , int connectTimeout) throws Exception { + private void initialSSLHandshake(SSLSocket sslSocket, int connectTimeout) throws Exception { if (!IS_HOSTNAME_VERIFICATION_DISABLED) { SSLParameters param = sslSocket.getSSLParameters(); diff --git a/src/java.naming/share/classes/module-info.java b/src/java.naming/share/classes/module-info.java index c4c7a606c6c..5a731000194 100644 --- a/src/java.naming/share/classes/module-info.java +++ b/src/java.naming/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -36,21 +36,33 @@ * The following implementation specific environment properties are supported by the * default LDAP Naming Service Provider implementation in the JDK: *

      + *
    • {@code java.naming.ldap.factory.socket}: + *
      The value of this environment property specifies the fully + * qualified class name of the socket factory used by the LDAP provider. + * This class must implement the {@link javax.net.SocketFactory} abstract class + * and provide an implementation of the static "getDefault()" method that + * returns an instance of the socket factory. By default the environment + * property is not set. + *
    • *
    • {@code com.sun.jndi.ldap.connect.timeout}: - *
      The value of this property is the string representation - * of an integer representing the connection timeout in - * milliseconds. If the LDAP provider cannot establish a - * connection within that period, it aborts the connection attempt. + *
      The value of this environment property is the string representation + * of an integer specifying the connection timeout in milliseconds. + * If the LDAP provider cannot establish a connection within that period, + * it aborts the connection attempt. * The integer should be greater than zero. An integer less than * or equal to zero means to use the network protocol's (i.e., TCP's) * timeout value. *
      If this property is not specified, the default is to wait * for the connection to be established or until the underlying * network times out. + *
      If a custom socket factory is provided via environment property + * {@code java.naming.ldap.factory.socket} and unconnected sockets + * are not supported, the specified timeout is ignored + * and the provider behaves as if no connection timeout was set. *
    • *
    • {@code com.sun.jndi.ldap.read.timeout}: *
      The value of this property is the string representation - * of an integer representing the read timeout in milliseconds + * of an integer specifying the read timeout in milliseconds * for LDAP operations. If the LDAP provider cannot get a LDAP * response within that period, it aborts the read attempt. The * integer should be greater than zero. An integer less than or diff --git a/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java b/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java index 29f74d250f7..15d8f8b074c 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -21,68 +21,117 @@ * questions. */ -import jdk.test.lib.net.URIBuilder; - -import javax.naming.Context; -import javax.naming.ldap.InitialLdapContext; -import javax.naming.ldap.LdapContext; -import javax.net.SocketFactory; -import javax.net.ssl.SSLServerSocketFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Field; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import javax.net.SocketFactory; +import javax.net.ssl.SSLServerSocketFactory; + +import jdk.test.lib.net.URIBuilder; + /* * @test - * @bug 8314063 + * @bug 8314063 8325579 * @library /test/lib - * @summary For LDAPs connection, if the value of com.sun.jndi.ldap.connect.timeout is - * set too small or not an optimal value for the system, after the socket is created and - * connected to the server, but the handshake between the client and server fails due to - * socket time out, the opened socket is not closed properly. In this test case, the server - * is forced to sleep ten seconds and connection time out for client is one second. This - * will allow the socket opened and connected, and give the chance for the handshake to be - * timed out. Before this fix, the socket is kept opened. Right now the exception will be - * caught and the socket will be closed. + * @summary Several scenarios for LDAP connection handshaking are tested here. + * We test different combinations of com.sun.jndi.ldap.connect.timeout values + * and server behavior, e.g. a server that replies immediately vs a server that + * delays the initial answer. We also try to check whether the underlying Socket + * object will be closed correctly. + * We expect exceptions when using a custom SocketFactory that does not supply + * SSL Sockets. In that case we instrument the supplied Socket object and check + * if it was properly closed after the handshake failure. + * When the value of com.sun.jndi.ldap.connect.timeout is set lower than the + * server delay, we also expect an exception. + * In all other cases a valid Context object shall be returned and we check + * whether the socket is closed after closing the Context. * - * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest -1000 true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest -1000 false 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 2000 false 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 0 true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 0 false 6000 + * @modules java.naming/javax.naming:+open java.naming/com.sun.jndi.ldap:+open + * @run main/othervm LdapSSLHandshakeFailureTest * @run main/othervm LdapSSLHandshakeFailureTest true - * @run main/othervm LdapSSLHandshakeFailureTest false + * @run main/othervm LdapSSLHandshakeFailureTest 0 + * @run main/othervm LdapSSLHandshakeFailureTest 0 true + * @run main/othervm LdapSSLHandshakeFailureTest 2000 + * @run main/othervm LdapSSLHandshakeFailureTest 2000 true + * @run main/othervm LdapSSLHandshakeFailureTest -1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected 1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected 1000 true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory 1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory 1000 true */ public class LdapSSLHandshakeFailureTest { - private static String SOCKET_CLOSED_MSG = "The socket has been closed."; + private static int SERVER_SLEEPING_TIME = 4000; + private static String progArgs[]; + private static int curArg; + private static String customSocketFactory; + private static Integer connectTimeout; + private static boolean serverSlowDown; + + private static String popArg() { + if (curArg >= progArgs.length) { + return null; + } + return progArgs[curArg++]; + } - private static int serverSleepingTime = 5000; + private static void parseArgs(String args[]) { + progArgs = args; + curArg = 0; - public static void main(String args[]) throws Exception { + String arg = popArg(); + if (arg == null) + return; - // Set the keystores - setKeyStore(); - boolean serverSlowDown = Boolean.valueOf(args[0]); - if (args.length == 2) { - serverSlowDown = Boolean.valueOf(args[1]); + if (arg.startsWith("LdapSSLHandshakeFailureTest$CustomSocketFactory")) { + customSocketFactory = arg; + arg = popArg(); + if (arg == null) + return; } - if (args.length == 3) { - serverSleepingTime = Integer.valueOf(args[2]); + try { + connectTimeout = Integer.valueOf(arg); + arg = popArg(); + if (arg == null) + return; + } catch (NumberFormatException e) { + // then it must be the boolean arg for serverSlowDown } - boolean hasCustomSocketFactory = args[0] - .equals("LdapSSLHandshakeFailureTest$CustomSocketFactory"); + serverSlowDown = Boolean.valueOf(arg); + } + + public static void main(String args[]) { + parseArgs(args); + + System.out.println("Testing " + + (customSocketFactory == null ? "without custom SocketFactory" : "with custom SocketFactory \"" + customSocketFactory + "\"") + + ", " + (connectTimeout == null ? "no connectTimeout" : "connectTimeout=" + connectTimeout + "") + + ", serverSlowDown=" + serverSlowDown); + + // Set the keystores + setKeyStore(); + // start the test server first. - try (TestServer server = new TestServer(serverSlowDown, serverSleepingTime)) { + try (TestServer server = new TestServer(serverSlowDown)) { server.start(); Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); @@ -93,15 +142,13 @@ public static void main(String args[]) throws Exception { .port(server.getPortNumber()) .buildUnchecked().toString()); - if (hasCustomSocketFactory) { - env.put("java.naming.ldap.factory.socket", args[0]); - env.put("com.sun.jndi.ldap.connect.timeout", "1000"); + if (customSocketFactory != null) { + env.put("java.naming.ldap.factory.socket", customSocketFactory); } - if (args.length == 2 && !hasCustomSocketFactory) { - env.put("com.sun.jndi.ldap.connect.timeout", args[0]); + if (connectTimeout != null) { + env.put("com.sun.jndi.ldap.connect.timeout", connectTimeout.toString()); } - env.put(Context.SECURITY_PROTOCOL, "ssl"); env.put(Context.SECURITY_AUTHENTICATION, "Simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=principal"); @@ -109,94 +156,127 @@ public static void main(String args[]) throws Exception { LdapContext ctx = null; try { ctx = new InitialLdapContext(env, null); - } catch (Exception e) { - if (CustomSocketFactory.customSocket.closeMethodCalledCount() > 0 - && hasCustomSocketFactory - && Boolean.valueOf(args[1])) { - System.out.println(SOCKET_CLOSED_MSG); + } catch (NamingException e) { + if (customSocketFactory != null) { + System.out.println("Caught expected Exception with custom SocketFactory (no SSL Socket)."); + if (CustomSocketFactory.customSocket.closeMethodCalledCount() <= 0) { + throw new RuntimeException("Custom Socket was not closed."); + } + } else if (connectTimeout > 0) { + System.out.println("Caught expected Exception with connectTimeout > 0."); } else { throw e; } } finally { - if (ctx != null) + if (ctx != null) { + System.out.println("Context was created, closing it."); + Socket sock = getSocket(ctx); ctx.close(); + if (!sock.isClosed()) { + throw new RuntimeException("Socket isn't closed"); + } + } } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); } } - public static class CustomSocketFactory extends SocketFactory { - private static CustomSocket customSocket; + private static Socket getSocket(LdapContext ctx) throws Exception { + Field defaultInitCtxField = ctx.getClass().getSuperclass().getSuperclass().getDeclaredField("defaultInitCtx"); + defaultInitCtxField.setAccessible(true); + Object defaultInitCtx = defaultInitCtxField.get(ctx); + Field clntField = defaultInitCtx.getClass().getDeclaredField("clnt"); + clntField.setAccessible(true); + Object clnt = clntField.get(defaultInitCtx); + Field connField = clnt.getClass().getDeclaredField("conn"); + connField.setAccessible(true); + Object conn = connField.get(clnt); + return (Socket)conn.getClass().getDeclaredField("sock").get(conn); + } - public static CustomSocketFactory getDefault() { - return new CustomSocketFactory(); + private static class CustomSocket extends Socket { + private int closeMethodCalled; + + public CustomSocket() { + super(); } - @Override - public Socket createSocket() throws SocketException { - customSocket = new CustomSocket(); - return customSocket; + public CustomSocket(String s, int port) throws IOException { + super(s, port); } - @Override - public Socket createSocket(String s, int timeout) { - return customSocket; + public int closeMethodCalledCount() { + return closeMethodCalled; } @Override - public Socket createSocket(String host, int port, InetAddress localHost, - int localPort) { - return customSocket; + public void close() throws java.io.IOException { + closeMethodCalled++; + super.close(); + } + } + + public static class CustomSocketFactoryNoUnconnected extends SocketFactory { + static CustomSocket customSocket; + + public static SocketFactory getDefault() { + return new CustomSocketFactoryNoUnconnected(); } @Override - public Socket createSocket(InetAddress host, int port) { + public Socket createSocket(String s, int port) throws IOException { + customSocket = new CustomSocket(s, port); return customSocket; } @Override - public Socket createSocket(InetAddress address, int port, - InetAddress localAddress, int localPort) { - return customSocket; + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) + throws IOException, UnknownHostException { + return null; } - } - private static class CustomSocket extends Socket { - private int closeMethodCalled = 0; + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return null; + } - public CustomSocket() { - closeMethodCalled = 0; + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException { + return null; } + } - public int closeMethodCalledCount() { - return closeMethodCalled; + public static class CustomSocketFactory extends CustomSocketFactoryNoUnconnected { + public static SocketFactory getDefault() { + return new CustomSocketFactory(); } @Override - public void close() throws java.io.IOException { - closeMethodCalled++; - super.close(); + public Socket createSocket() throws SocketException { + customSocket = new CustomSocket(); + return customSocket; } } private static void setKeyStore() { + String keystore = System.getProperty("test.src", ".") + File.separator + "ksWithSAN"; - String fileName = "ksWithSAN", dir = System.getProperty("test.src", ".") + File.separator; - - System.setProperty("javax.net.ssl.keyStore", dir + fileName); + System.setProperty("javax.net.ssl.keyStore", keystore); System.setProperty("javax.net.ssl.keyStorePassword", "welcome1"); - System.setProperty("javax.net.ssl.trustStore", dir + fileName); + System.setProperty("javax.net.ssl.trustStore", keystore); System.setProperty("javax.net.ssl.trustStorePassword", "welcome1"); } static class TestServer extends Thread implements AutoCloseable { private boolean isForceToSleep; - private int sleepingTime; private final ServerSocket serverSocket; private final int PORT; - private TestServer(boolean isForceToSleep, int sleepingTime) { + private TestServer(boolean isForceToSleep) { this.isForceToSleep = isForceToSleep; - this.sleepingTime = sleepingTime; try { SSLServerSocketFactory socketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); serverSocket = socketFactory.createServerSocket(0, 0, InetAddress.getLoopbackAddress()); @@ -217,7 +297,7 @@ public void run() { InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream()) { if (isForceToSleep) { - Thread.sleep(sleepingTime); + Thread.sleep(SERVER_SLEEPING_TIME); } byte[] bindResponse = {0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00}; @@ -233,7 +313,7 @@ public void run() { in.skip(in.available()); } } catch (Exception e) { - e.printStackTrace(); + // e.printStackTrace(); } } @@ -245,5 +325,3 @@ public void close() throws Exception { } } } - - From c993c0cd990426c4e4e5ee53a615f932f744e65a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 11 Apr 2024 09:20:06 +0000 Subject: [PATCH 176/298] 8313702: Update IANA Language Subtag Registry to Version 2023-08-02 Backport-of: 1da82a34b14189814e45a93c68620ccb51427111 --- .../share/data/lsrdata/language-subtag-registry.txt | 11 ++++++++++- .../java/util/Locale/LanguageSubtagRegistryTest.java | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/data/lsrdata/language-subtag-registry.txt b/src/java.base/share/data/lsrdata/language-subtag-registry.txt index 48ba4d1d9aa..85e0822ed13 100644 --- a/src/java.base/share/data/lsrdata/language-subtag-registry.txt +++ b/src/java.base/share/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2023-05-11 +File-Date: 2023-08-02 %% Type: language Subtag: aa @@ -47644,6 +47644,15 @@ Comments: The dialect of San Giorgio/Bila is one of the four major local dialects of Resian %% Type: variant +Subtag: blasl +Description: Black American Sign Language dialect +Added: 2023-07-31 +Prefix: ase +Prefix: sgn-ase +Comments: Black American Sign Language (BASL) or Black Sign Variation + (BSV) is a dialect of American Sign Language (ASL) +%% +Type: variant Subtag: bohoric Description: Slovene in Bohorič alphabet Added: 2012-06-27 diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index dc792f9f72a..aa8e8c2c6f5 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -24,9 +24,9 @@ /* * @test * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 - * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 + * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2023-05-11) with Locale and Locale.LanguageRange + * (LSR Revision: 2023-08-02) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ From d1caa3fdf8596de73e383a9c9fda4d02149e370c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 11 Apr 2024 09:25:20 +0000 Subject: [PATCH 177/298] 8313899: JVMCI exception Translation can fail in TranslatedException. Backport-of: 6f5c903d10aa5f7ff979a79f121609c167f88eff --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 13 +++++++++++++ src/hotspot/share/jvmci/jvmciEnv.cpp | 14 ++++++++++++-- src/hotspot/share/jvmci/jvmciRuntime.cpp | 4 ++++ .../jdk/internal/vm/TranslatedException.java | 19 +++++++++++++++++++ .../TestUncaughtErrorInCompileMethod.java | 3 +++ .../hotspot/test/TestHotSpotJVMCIRuntime.java | 8 ++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index ae13fc86143..5b45499f965 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -52,6 +52,7 @@ #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" +#include "runtime/arguments.hpp" #include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/fieldDescriptor.inline.hpp" @@ -585,6 +586,18 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", str)); } +#ifdef ASSERT + const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.lookupTypeException"); + if (val != nullptr) { + if (strstr(val, "") != nullptr) { + tty->print_cr("CompilerToVM.lookupType: %s", str); + } else if (strstr(val, str) != nullptr) { + THROW_MSG_0(vmSymbols::java_lang_Exception(), + err_msg("lookupTypeException: %s", str)); + } + } +#endif + JVMCIKlassHandle resolved_klass(THREAD); Klass* accessing_klass = UNPACK_PAIR(Klass, accessing_klass); Handle class_loader; diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 32759a1889a..329afe8cfa5 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -505,8 +505,7 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation { private: const Handle& _throwable; - int encode(JavaThread* THREAD, jlong buffer, int buffer_size) { - Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD); + bool handle_pending_exception(JavaThread* THREAD, jlong buffer, int buffer_size) { if (HAS_PENDING_EXCEPTION) { Handle throwable = Handle(THREAD, PENDING_EXCEPTION); Symbol *ex_name = throwable->klass()->name(); @@ -523,6 +522,14 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation { JVMCI_event_1("error translating exception: %s", char_buffer); decode(THREAD, _encode_fail, buffer); } + return true; + } + return false; + } + + int encode(JavaThread* THREAD, jlong buffer, int buffer_size) { + Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD); + if (handle_pending_exception(THREAD, buffer, buffer_size)) { return 0; } JavaCallArguments jargs; @@ -534,6 +541,9 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation { vmSupport, vmSymbols::encodeThrowable_name(), vmSymbols::encodeThrowable_signature(), &jargs, THREAD); + if (handle_pending_exception(THREAD, buffer, buffer_size)) { + return 0; + } return result.get_jint(); } diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 6a1bc38b4d5..73a19d01173 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -1231,11 +1231,13 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) { MutexLocker locker(_lock); JavaVM* javaVM = _shared_library_javavm; if (javaVM == nullptr) { +#ifdef ASSERT const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.forceEnomemOnLibjvmciInit"); if (val != nullptr && strcmp(val, "true") == 0) { *create_JavaVM_err = JNI_ENOMEM; return nullptr; } +#endif char* sl_path; void* sl_handle = JVMCI::get_shared_library(sl_path, true); @@ -2059,12 +2061,14 @@ void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, c JVMCIObject result_object = JVMCIENV->call_HotSpotJVMCIRuntime_compileMethod(receiver, jvmci_method, entry_bci, (jlong) compile_state, compile_state->task()->compile_id()); +#ifdef ASSERT if (JVMCIENV->has_pending_exception()) { const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.compileMethodExceptionIsFatal"); if (val != nullptr && strcmp(val, "true") == 0) { fatal_exception(JVMCIENV, "testing JVMCI fatal exception handling"); } } +#endif if (after_compiler_upcall(JVMCIENV, compiler, method, "call_HotSpotJVMCIRuntime_compileMethod")) { return; diff --git a/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java b/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java index 6907f4fec9d..92a443704e8 100644 --- a/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java +++ b/src/java.base/share/classes/jdk/internal/vm/TranslatedException.java @@ -24,6 +24,8 @@ */ package jdk.internal.vm; +import jdk.internal.misc.VM; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -56,6 +58,7 @@ final class TranslatedException extends Exception { */ private static final byte[] FALLBACK_ENCODED_THROWABLE_BYTES; static { + maybeFailClinit(); try { FALLBACK_ENCODED_THROWABLE_BYTES = encodeThrowable(new TranslatedException("error during encoding", @@ -67,6 +70,22 @@ final class TranslatedException extends Exception { } } + /** + * Helper to test exception translation. + */ + private static void maybeFailClinit() { + String className = VM.getSavedProperty("test.jvmci.TranslatedException.clinit.throw"); + if (className != null) { + try { + throw (Throwable) Class.forName(className).getDeclaredConstructor().newInstance(); + } catch (RuntimeException | Error e) { + throw e; + } catch (Throwable e) { + throw new InternalError(e); + } + } + } + /** * Class name of exception that could not be instantiated. */ diff --git a/test/hotspot/jtreg/compiler/jvmci/TestUncaughtErrorInCompileMethod.java b/test/hotspot/jtreg/compiler/jvmci/TestUncaughtErrorInCompileMethod.java index fcf58674f1c..511e0c4b98c 100644 --- a/test/hotspot/jtreg/compiler/jvmci/TestUncaughtErrorInCompileMethod.java +++ b/test/hotspot/jtreg/compiler/jvmci/TestUncaughtErrorInCompileMethod.java @@ -24,7 +24,10 @@ /* * @test * @summary Tests handling of an exception thrown by HotSpotJVMCIRuntime.compileMethod. + * Requires a debug VM as it uses test.jvmci.compileMethodExceptionIsFatal + * which is only read in a debug VM. * @requires vm.jvmci + * @requires vm.debug * @library /test/lib / * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot * jdk.internal.vm.ci/jdk.vm.ci.code diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotJVMCIRuntime.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotJVMCIRuntime.java index 0ccc7b9b56c..1ab094a0277 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotJVMCIRuntime.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotJVMCIRuntime.java @@ -32,6 +32,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.common * @library /compiler/jvmci/jdk.vm.ci.hotspot.test/src * /compiler/jvmci/jdk.vm.ci.code.test/src + * @library /test/lib * @run testng/othervm * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler * jdk.vm.ci.hotspot.test.TestHotSpotJVMCIRuntime @@ -53,6 +54,8 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.test.lib.Platform; + public class TestHotSpotJVMCIRuntime { @Test @@ -157,6 +160,11 @@ public static void main(String[] args) { @Test public void jniEnomemTest() throws Exception { + if (!Platform.isDebugBuild()) { + // The test.jvmci.forceEnomemOnLibjvmciInit property is only + // read in a debug VM. + return; + } String[] names = {"translate", "attachCurrentThread", "registerNativeMethods"}; for (String name : names) { ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( From db8ea85c7d8259a4c46ba5d1a66d7acc2c4da3e6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 11 Apr 2024 09:26:56 +0000 Subject: [PATCH 178/298] 8303959: tools/jpackage/share/RuntimePackageTest.java fails with java.lang.AssertionError missing files Backport-of: 5a6aa569aa279141193038dc2e61e18a8b24bc11 --- .../jpackage/share/RuntimePackageTest.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java index e3ebdd3327e..12edff1cea5 100644 --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java @@ -25,7 +25,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.HashSet; -import java.util.Optional; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -34,6 +33,8 @@ import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; +import jdk.jpackage.test.JavaTool; import jdk.jpackage.test.LinuxHelper; import static jdk.jpackage.test.TKit.assertTrue; import static jdk.jpackage.test.TKit.assertFalse; @@ -101,9 +102,25 @@ private static PackageTest init(Set types) { return new PackageTest() .forTypes(types) .addInitializer(cmd -> { - cmd.addArguments("--runtime-image", Optional.ofNullable( - JPackageCommand.DEFAULT_RUNTIME_IMAGE).orElse(Path.of( - System.getProperty("java.home")))); + final Path runtimeImageDir; + if (JPackageCommand.DEFAULT_RUNTIME_IMAGE != null) { + runtimeImageDir = JPackageCommand.DEFAULT_RUNTIME_IMAGE; + } else { + runtimeImageDir = TKit.createTempDirectory("runtime").resolve("data"); + + new Executor() + .setToolProvider(JavaTool.JLINK) + .dumpOutput() + .addArguments( + "--output", runtimeImageDir.toString(), + "--compress=0", + "--add-modules", "ALL-MODULE-PATH", + "--strip-debug", + "--no-header-files", + "--no-man-pages") + .execute(); + } + cmd.addArguments("--runtime-image", runtimeImageDir); // Remove --input parameter from jpackage command line as we don't // create input directory in the test and jpackage fails // if --input references non existant directory. From dc536692917b34e44e0daef564fdef7cdb826e4d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 11 Apr 2024 09:55:24 +0000 Subject: [PATCH 179/298] 8318322: Update IANA Language Subtag Registry to Version 2023-10-16 Backport-of: cc8f8da293914c25cb15d38caad994bc761a3957 --- .../data/lsrdata/language-subtag-registry.txt | 52 ++++++++++++++++++- .../Locale/LanguageSubtagRegistryTest.java | 4 +- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/data/lsrdata/language-subtag-registry.txt b/src/java.base/share/data/lsrdata/language-subtag-registry.txt index 85e0822ed13..c6937ee80f1 100644 --- a/src/java.base/share/data/lsrdata/language-subtag-registry.txt +++ b/src/java.base/share/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2023-08-02 +File-Date: 2023-10-16 %% Type: language Subtag: aa @@ -44880,6 +44880,11 @@ Description: Cherokee Added: 2005-10-16 %% Type: script +Subtag: Chis +Description: Chisoi +Added: 2023-10-16 +%% +Type: script Subtag: Chrs Description: Chorasmian Added: 2019-09-11 @@ -44975,6 +44980,11 @@ Description: Ge'ez Added: 2005-10-16 %% Type: script +Subtag: Gara +Description: Garay +Added: 2023-10-16 +%% +Type: script Subtag: Geok Description: Khutsuri (Asomtavruli and Nuskhuri) Added: 2005-10-16 @@ -45020,6 +45030,11 @@ Description: Gujarati Added: 2005-10-16 %% Type: script +Subtag: Gukh +Description: Gurung Khema +Added: 2023-10-16 +%% +Type: script Subtag: Guru Description: Gurmukhi Added: 2005-10-16 @@ -45190,6 +45205,11 @@ Description: Kpelle Added: 2010-04-10 %% Type: script +Subtag: Krai +Description: Kirat Rai +Added: 2023-10-16 +%% +Type: script Subtag: Kthi Description: Kaithi Added: 2007-12-05 @@ -45437,6 +45457,11 @@ Description: Santali Added: 2006-07-21 %% Type: script +Subtag: Onao +Description: Ol Onal +Added: 2023-10-16 +%% +Type: script Subtag: Orkh Description: Old Turkic Description: Orkhon Runic @@ -45616,6 +45641,11 @@ Description: Siddhamātṛkā Added: 2013-12-02 %% Type: script +Subtag: Sidt +Description: Sidetic +Added: 2023-10-16 +%% +Type: script Subtag: Sind Description: Khudawadi Description: Sindhi @@ -45719,6 +45749,11 @@ Description: Tai Viet Added: 2007-12-05 %% Type: script +Subtag: Tayo +Description: Tai Yo +Added: 2023-10-16 +%% +Type: script Subtag: Telu Description: Telugu Added: 2005-10-16 @@ -45767,11 +45802,26 @@ Description: Tangsa Added: 2021-03-05 %% Type: script +Subtag: Todr +Description: Todhri +Added: 2023-10-16 +%% +Type: script +Subtag: Tols +Description: Tolong Siki +Added: 2023-10-16 +%% +Type: script Subtag: Toto Description: Toto Added: 2020-05-12 %% Type: script +Subtag: Tutg +Description: Tulu-Tigalari +Added: 2023-10-16 +%% +Type: script Subtag: Ugar Description: Ugaritic Added: 2005-10-16 diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index aa8e8c2c6f5..d0141b304a8 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -24,9 +24,9 @@ /* * @test * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 - * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 + * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2023-08-02) with Locale and Locale.LanguageRange + * (LSR Revision: 2023-10-16) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ From db750ffb896bd2a9a8135304bb6fcadae02fa695 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 11 Apr 2024 09:56:47 +0000 Subject: [PATCH 180/298] 8320349: Simplify FileChooserSymLinkTest.java by using single-window testUI Backport-of: b1cb37432a4b4a10ba68f468e4d988f2a935f198 --- .../javax/swing/JFileChooser/FileChooserSymLinkTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java b/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java index 15ac95bc198..4736e73e61d 100644 --- a/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java +++ b/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java @@ -22,14 +22,12 @@ */ import java.awt.BorderLayout; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.Arrays; -import java.util.List; import javax.swing.JCheckBox; import javax.swing.JFileChooser; @@ -118,7 +116,7 @@ public static void main(String[] args) throws Exception { .awaitAndCheck(); } - private static List createTestUI() { + private static JFrame createTestUI() { frame = new JFrame("JFileChooser Symbolic Link test"); panel = new JPanel(new BorderLayout()); multiSelection = new JCheckBox("Enable Multi-Selection"); @@ -159,6 +157,6 @@ public void propertyChange(PropertyChangeEvent evt) { frame.add(panel, BorderLayout.NORTH); frame.add(jfc, BorderLayout.CENTER); frame.pack(); - return List.of(frame); + return frame; } } From 18254641606816215189a06a281e1763fd86eecf Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Thu, 11 Apr 2024 12:41:04 +0000 Subject: [PATCH 181/298] 8329823: RISC-V: Need to sync CPU features with related JVM flags Backport-of: b9331cd25ca88b07ce079405f5e3031cf8c13ea6 --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 29 ++++++++++++------- .../linux_riscv/vm_version_linux_riscv.cpp | 11 +++++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 93ebd9e4e7d..0de6e9a19e1 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -55,6 +55,10 @@ class VM_Version : public Abstract_VM_Version { _enabled = true; _value = value; } + void disable_feature() { + _enabled = false; + _value = -1; + } const char* const pretty() { return _pretty; } const uint64_t feature_bit() { return _feature_bit; } const bool feature_string() { return _feature_string; } @@ -63,16 +67,21 @@ class VM_Version : public Abstract_VM_Version { virtual void update_flag() = 0; }; - #define UPDATE_DEFAULT(flag) \ - void update_flag() { \ - assert(enabled(), "Must be."); \ - if (FLAG_IS_DEFAULT(flag)) { \ - FLAG_SET_DEFAULT(flag, true); \ - } \ - } \ - - #define NO_UPDATE_DEFAULT \ - void update_flag() {} \ + #define UPDATE_DEFAULT(flag) \ + void update_flag() { \ + assert(enabled(), "Must be."); \ + if (FLAG_IS_DEFAULT(flag)) { \ + FLAG_SET_DEFAULT(flag, true); \ + } else { \ + /* Sync CPU features with flags */ \ + if (!flag) { \ + disable_feature(); \ + } \ + } \ + } \ + + #define NO_UPDATE_DEFAULT \ + void update_flag() {} \ // Frozen standard extensions // I RV64I diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp index a7528ae07bd..7b4381cb590 100644 --- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp @@ -115,6 +115,15 @@ void VM_Version::setup_cpu_available_features() { int i = 0; while (_feature_list[i] != nullptr) { if (_feature_list[i]->enabled()) { + // Change flag default + _feature_list[i]->update_flag(); + + // Feature will be disabled by update_flag() if flag + // is set to false by the user on the command line. + if (!_feature_list[i]->enabled()) { + continue; + } + log_debug(os, cpu)("Enabled RV64 feature \"%s\" (%ld)", _feature_list[i]->pretty(), _feature_list[i]->value()); @@ -139,8 +148,6 @@ void VM_Version::setup_cpu_available_features() { if (_feature_list[i]->feature_bit() != 0) { _features |= _feature_list[i]->feature_bit(); } - // Change flag default - _feature_list[i]->update_flag(); } i++; } From 807f21d6986312e2ef5be2d36a29f464ad33fddc Mon Sep 17 00:00:00 2001 From: Sidraya Jayagond Date: Fri, 12 Apr 2024 08:54:17 +0000 Subject: [PATCH 182/298] 8329545: [s390x] Fix garbage value being passed in Argument Register Backport-of: e0fd6c4c9e30ef107ea930c8ecc449842ae4b8d4 --- src/hotspot/cpu/s390/foreignGlobals_s390.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp index 9796ab4ffe4..67aee9af7d9 100644 --- a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp +++ b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -166,7 +166,7 @@ static void move_stack(MacroAssembler* masm, Register tmp_reg, int in_stk_bias, case StorageType::INTEGER: switch (from_reg.stack_size()) { case 8: __ mem2reg_opt(as_Register(to_reg), from_addr, true);break; - case 4: __ mem2reg_opt(as_Register(to_reg), from_addr, false);break; + case 4: __ mem2reg_signed_opt(as_Register(to_reg), from_addr);break; default: ShouldNotReachHere(); } break; From eec41a48a87cf8bd559b5e3803afb820b095178b Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 15 Apr 2024 07:39:08 +0000 Subject: [PATCH 183/298] 8328589: unify os::breakpoint among posix platforms Backport-of: 93d1700f23d42cb35b6028c5d7d029c035711acf --- src/hotspot/os/aix/os_aix.cpp | 11 ----------- src/hotspot/os/bsd/os_bsd.cpp | 11 ----------- src/hotspot/os/linux/os_linux.cpp | 11 ----------- src/hotspot/os/posix/os_posix.cpp | 11 +++++++++++ 4 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index a8938c71fe8..d73a847b2b6 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -590,17 +590,6 @@ void os::init_system_properties_values() { #undef EXTENSIONS_DIR } -//////////////////////////////////////////////////////////////////////////////// -// breakpoint support - -void os::breakpoint() { - BREAKPOINT; -} - -extern "C" void breakpoint() { - // use debugger to set breakpoint here -} - // retrieve memory information. // Returns false if something went wrong; // content of pmi undefined in this case. diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 4a2922cb728..e2c5c5b9819 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -506,17 +506,6 @@ void os::init_system_properties_values() { #undef EXTENSIONS_DIR } -//////////////////////////////////////////////////////////////////////////////// -// breakpoint support - -void os::breakpoint() { - BREAKPOINT; -} - -extern "C" void breakpoint() { - // use debugger to set breakpoint here -} - ////////////////////////////////////////////////////////////////////////////// // create new thread diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index fcd3bbff9d1..7646c54c104 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -584,17 +584,6 @@ void os::init_system_properties_values() { #undef EXTENSIONS_DIR } -//////////////////////////////////////////////////////////////////////////////// -// breakpoint support - -void os::breakpoint() { - BREAKPOINT; -} - -extern "C" void breakpoint() { - // use debugger to set breakpoint here -} - ////////////////////////////////////////////////////////////////////////////// // detecting pthread library diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 56f6d32bd4d..f21c72453a9 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -194,6 +194,17 @@ size_t os::lasterror(char *buf, size_t len) { return n; } +//////////////////////////////////////////////////////////////////////////////// +// breakpoint support + +void os::breakpoint() { + BREAKPOINT; +} + +extern "C" void breakpoint() { + // use debugger to set breakpoint here +} + // Return true if user is running as root. bool os::have_special_privileges() { static bool privileges = (getuid() != geteuid()) || (getgid() != getegid()); From f5c0d7824fac3ceb45ad405ee242b6f5909dd25e Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Mon, 15 Apr 2024 08:24:02 +0000 Subject: [PATCH 184/298] 8329961: Buffer overflow in os::Linux::kernel_version Backport-of: 279ed0ddd505fb3052b818f755b4b220ed5557e6 --- src/hotspot/os/linux/os_linux.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 7646c54c104..b3aee9b24bc 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -321,16 +321,9 @@ void os::Linux::kernel_version(long* major, long* minor) { log_warning(os)("uname(2) failed to get kernel version: %s", os::errno_name(ret)); return; } - - char* walker = buffer.release; - long* set_v = major; - while (*minor == -1 && walker != nullptr) { - if (isdigit(walker[0])) { - *set_v = strtol(walker, &walker, 10); - set_v = minor; - } else { - ++walker; - } + int nr_matched = sscanf(buffer.release, "%ld.%ld", major, minor); + if (nr_matched != 2) { + log_warning(os)("Parsing kernel version failed, expected 2 version numbers, only matched %d", nr_matched); } } From 0dd4808640cc934caa02031f1aae6daee985008a Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Tue, 16 Apr 2024 01:57:57 +0000 Subject: [PATCH 185/298] 8328540: test javax/swing/JSplitPane/4885629/bug4885629.java fails on windows hidpi Backport-of: fa823bd21c6676c67c42275efb59868200409b38 --- test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java b/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java index c7e980081cf..fa6c1f21063 100644 --- a/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java +++ b/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -104,9 +104,9 @@ public void run() { SwingUtilities.convertPointToScreen(p, sp); - for (int i = 0; i < rect.width; i++) { + for (int i = 1; i < rect.width - 1; i++) { if (!BGCOLOR.equals(robot.getPixelColor(p.x + i, p.y + rect.height - 1))) { - throw new Error("The divider's area has incorrect color."); + throw new Error("The divider's area has incorrect color. i=" + i); } } } From f95de5b2020ecd8f947711c70cfd30723f2f7078 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 16 Apr 2024 08:25:15 +0000 Subject: [PATCH 186/298] 8320714: java/util/Locale/LocaleProvidersRun.java and java/util/ResourceBundle/modules/visibility/VisibilityTest.java timeout after passing Backport-of: 69c0b24386d0bcf2f2d623ccef0192a54753f916 --- test/jdk/java/util/Locale/LocaleProvidersRun.java | 5 +++-- .../ResourceBundle/modules/visibility/VisibilityTest.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/util/Locale/LocaleProvidersRun.java b/test/jdk/java/util/Locale/LocaleProvidersRun.java index aae8ff03c11..947633a8e21 100644 --- a/test/jdk/java/util/Locale/LocaleProvidersRun.java +++ b/test/jdk/java/util/Locale/LocaleProvidersRun.java @@ -28,6 +28,7 @@ * 8150432 8215913 8220227 8228465 8232871 8232860 8236495 8245241 * 8246721 8248695 8257964 8261919 * @summary tests for "java.locale.providers" system property + * @requires vm.flagless * @library /test/lib * @build LocaleProviders * providersrc.spi.src.tznp @@ -179,8 +180,8 @@ public static void main(String[] args) throws Throwable { private static void testRun(String prefList, String methodName, String param1, String param2, String param3) throws Throwable { - // Build process (with VM flags) - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + // Build process (without VM flags) + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( "-ea", "-esa", "-cp", Utils.TEST_CLASS_PATH, "-Djava.util.logging.config.class=LocaleProviders$LogConfig", diff --git a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java index b81c69a4269..e0fdb9a93ab 100644 --- a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java +++ b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java @@ -26,6 +26,7 @@ * @bug 8137317 8139238 8210408 * @summary Visibility tests for ResourceBundle.getBundle with and without * an unnamed module argument. + * @requires vm.flagless * @library /test/lib * .. * @build jdk.test.lib.JDKToolLauncher @@ -330,8 +331,8 @@ public void RunWithPkgRes(List argsList) throws Throwable { } private int runCmd(List argsList) throws Throwable { - // Build process (with VM flags) - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + // Build process (without VM flags) + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( Stream.concat(Stream.of("-ea", "-esa"), argsList.stream()).toList()); // Evaluate process status return ProcessTools.executeCommand(pb).getExitValue(); From e9e042b2d9fadfbbecc60c38c30b3453061b91cc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 16 Apr 2024 08:26:38 +0000 Subject: [PATCH 187/298] 8327631: Update IANA Language Subtag Registry to Version 2024-03-07 Backport-of: d5b95a0ed38b10ed9f51d20255e06eb38fdd8b82 --- .../data/lsrdata/language-subtag-registry.txt | 78 ++++++++++++++++++- .../Locale/LanguageSubtagRegistryTest.java | 5 +- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/data/lsrdata/language-subtag-registry.txt b/src/java.base/share/data/lsrdata/language-subtag-registry.txt index c6937ee80f1..4737c50e425 100644 --- a/src/java.base/share/data/lsrdata/language-subtag-registry.txt +++ b/src/java.base/share/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2023-10-16 +File-Date: 2024-03-07 %% Type: language Subtag: aa @@ -882,6 +882,7 @@ Type: language Subtag: sa Description: Sanskrit Added: 2005-10-16 +Scope: macrolanguage %% Type: language Subtag: sc @@ -8028,6 +8029,12 @@ Description: Lowland Oaxaca Chontal Added: 2009-07-29 %% Type: language +Subtag: cls +Description: Classical Sanskrit +Added: 2024-03-04 +Macrolanguage: sa +%% +Type: language Subtag: clt Description: Lautu Chin Added: 2012-08-12 @@ -30916,6 +30923,11 @@ Description: Ririo Added: 2009-07-29 %% Type: language +Subtag: rrm +Description: Moriori +Added: 2024-03-04 +%% +Type: language Subtag: rro Description: Waima Added: 2009-07-29 @@ -37660,6 +37672,12 @@ Description: Venezuelan Sign Language Added: 2009-07-29 %% Type: language +Subtag: vsn +Description: Vedic Sanskrit +Added: 2024-03-04 +Macrolanguage: sa +%% +Type: language Subtag: vsv Description: Valencian Sign Language Description: Llengua de signes valenciana @@ -47559,6 +47577,13 @@ Comments: Aluku dialect of the "Busi Nenge Tongo" English-based Creole continuum in Eastern Suriname and Western French Guiana %% Type: variant +Subtag: anpezo +Description: Anpezo standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Anpezo +%% +Type: variant Subtag: ao1990 Description: Portuguese Language Orthographic Agreement of 1990 (Acordo Ortográfico da Língua Portuguesa de 1990) @@ -47779,6 +47804,22 @@ Added: 2012-02-05 Prefix: en %% Type: variant +Subtag: fascia +Description: Fascia standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Fascia which + unified the three subvarieties Cazet, Brach and Moenat +%% +Type: variant +Subtag: fodom +Description: Fodom standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Livinallongo + and Colle Santa Lucia +%% +Type: variant Subtag: fonipa Description: International Phonetic Alphabet Added: 2006-12-11 @@ -47819,6 +47860,13 @@ Prefix: oc Comments: Occitan variant spoken in Gascony %% Type: variant +Subtag: gherd +Description: Gherdëina standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Gherdëina +%% +Type: variant Subtag: grclass Description: Classical Occitan orthography Added: 2018-04-22 @@ -48120,6 +48168,15 @@ Comments: Peano’s Interlingua, created in 1903 by Giuseppe Peano as an Added: 2020-03-12 %% Type: variant +Subtag: pehoeji +Description: Hokkien Vernacular Romanization System +Description: Pe̍h-ōe-jī orthography/romanization +Added: 2024-03-04 +Prefix: nan-Latn +Comments: Modern Hokkien Vernacular Romanization System, evolved from + the New Dictionary in the Amoy by John Van Nest Talmage in 1894 +%% +Type: variant Subtag: petr1708 Description: Petrine orthography Added: 2010-10-10 @@ -48254,6 +48311,16 @@ Added: 2021-07-17 Prefix: da %% Type: variant +Subtag: tailo +Description: Taiwanese Hokkien Romanization System for Hokkien + languages +Description: Tâi-lô orthography/romanization +Added: 2024-03-04 +Prefix: nan-Latn +Comments: Taiwanese Hokkien Romanization System (Tâi-lô) published in + 2006 by the Taiwan Ministry of Education +%% +Type: variant Subtag: tarask Description: Belarusian in Taraskievica orthography Added: 2007-04-27 @@ -48317,6 +48384,15 @@ Comments: The most ancient dialect of Sanskrit used in verse and prose composed until about the 4th century B.C.E. %% Type: variant +Subtag: valbadia +Description: Val Badia standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in the Val + Badia, unifying the three variants Marô, Mesaval and Badiot spoken + in this valley +%% +Type: variant Subtag: valencia Description: Valencian Added: 2007-03-06 diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index d0141b304a8..04a6e89db7b 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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,8 +25,9 @@ * @test * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322 + * 8327631 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2023-10-16) with Locale and Locale.LanguageRange + * (LSR Revision: 2024-03-07) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ From b980e1c5d6bb0047e4ea8af627bc8a7a59b0e466 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 16 Apr 2024 08:27:51 +0000 Subject: [PATCH 188/298] 8328988: [macos14] Problem list LightweightEventTest.java which fails due to macOS bug described in JDK-8322653 Backport-of: 2374d1e334ba0528b39239a01fe52d5843e678df --- test/jdk/ProblemList.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index cbad8670a83..04c2778461a 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -177,7 +177,7 @@ java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all java/awt/Toolkit/RealSync/Test.java 6849383 linux-all -java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all +java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252,8324782 windows-all,macosx-all java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8072110 macosx-all java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-all From fc7d8f80d9fcfb10f5ee4249b2b7b302b0db67eb Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Tue, 16 Apr 2024 15:09:33 +0000 Subject: [PATCH 189/298] 8326521: JFR: CompilerPhase event test fails on windows 32 bit Backport-of: 96530bcc07514c3eda40fd6ffa74f197fe541dea --- test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java index 0df2b5802cf..d1b325833c6 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java @@ -42,6 +42,7 @@ * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. + * -XX:-NeverActAsServerClassMachine * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:CompileOnly=jdk.jfr.event.compiler.TestCompilerPhase::dummyMethod * -XX:+SegmentedCodeCache -Xbootclasspath/a:. From 8fa8e02de980c51ab6793db6584a3e31ff59dd57 Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Tue, 16 Apr 2024 15:10:52 +0000 Subject: [PATCH 190/298] 8305931: jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java failed with "Expected chains but found none" Backport-of: 65be5e0c547d74ca7de288b164aa9bd6d6855685 --- .../jfr/jcmd/TestJcmdDumpPathToGCRoots.java | 71 ++++++++++--------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java index abbd6fb5201..5d469c698c1 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -74,43 +74,50 @@ public static void main(String[] args) throws Exception { } private static void testDump(String pathToGcRoots, Map settings, boolean expectedChains) throws Exception { - try (Recording r = new Recording()) { - Map p = new HashMap<>(settings); - p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); - r.setName("dodo"); - r.setSettings(p); - r.setToDisk(true); - r.start(); - clearLeak(); - System.out.println("Recording id: " + r.getId()); - System.out.println("Settings: " + settings.toString()); - System.out.println("Command: JFR.dump " + pathToGcRoots); - System.out.println("Chains expected: " + expectedChains); - buildLeak(); - System.gc(); - System.gc(); - File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); - recording.delete(); - JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); - r.setSettings(Collections.emptyMap()); - List events = RecordingFile.readAllEvents(recording.toPath()); - if (events.isEmpty()) { - throw new Exception("No events found in recoding"); - } - boolean chains = hasChains(events); - if (expectedChains && !chains) { - System.out.println(events); - throw new Exception("Expected chains but found none"); - } - if (!expectedChains && chains) { - System.out.println(events); - throw new Exception("Didn't expect chains but found some"); + while (true) { + try (Recording r = new Recording()) { + Map p = new HashMap<>(settings); + p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); + r.setName("dodo"); + r.setSettings(p); + r.setToDisk(true); + r.start(); + clearLeak(); + System.out.println("Recording id: " + r.getId()); + System.out.println("Settings: " + settings.toString()); + System.out.println("Command: JFR.dump " + pathToGcRoots); + System.out.println("Chains expected: " + expectedChains); + buildLeak(); + System.gc(); + System.gc(); + File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); + recording.delete(); + JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); + r.setSettings(Collections.emptyMap()); + List events = RecordingFile.readAllEvents(recording.toPath()); + if (events.isEmpty()) { + System.out.println("No events found in recording. Retrying."); + continue; + } + boolean chains = hasChains(events); + if (expectedChains && !chains) { + System.out.println(events); + System.out.println("Expected chains but found none. Retrying."); + continue; + } + if (!expectedChains && chains) { + System.out.println(events); + System.out.println("Didn't expect chains but found some. Retrying."); + continue; + } + return; // Success } } } private static void clearLeak() { leak.clear(); + System.gc(); } private static boolean hasChains(List events) throws IOException { From f0f2e70f84ee4ddb2e2af97d68713c8952b7928f Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Fri, 19 Apr 2024 09:46:54 +0000 Subject: [PATCH 191/298] 8326936: RISC-V: Shenandoah GC crashes due to incorrect atomic memory operations 8316186: RISC-V: Remove PlatformCmpxchg<4> 8330242: RISC-V: Simplify and remove CORRECT_COMPILER_ATOMIC_SUPPORT in atomic_linux_riscv.hpp Reviewed-by: fyang Backport-of: a089ed2b9289eeda73bba47ac87e5bc81a4af9dc --- .../os_cpu/linux_riscv/atomic_linux_riscv.hpp | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp index fdb8b340ab9..b3e35d6cc10 100644 --- a/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp +++ b/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp @@ -35,7 +35,7 @@ #if defined(__clang_major__) #define FULL_COMPILER_ATOMIC_SUPPORT -#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ >= 2)) +#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ > 2)) #define FULL_COMPILER_ATOMIC_SUPPORT #endif @@ -114,6 +114,44 @@ inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest __attribute__(( } #endif +#ifndef FULL_COMPILER_ATOMIC_SUPPORT +// The implementation of `__atomic_compare_exchange` lacks sign extensions +// in GCC 13.2 and lower when using with 32-bit unsigned integers on RV64, +// so we should implement it manually. +// GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114130. +// See also JDK-8326936. +template<> +template +inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest __attribute__((unused)), + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(4 == sizeof(T)); + + int32_t old_value; + uint64_t rc_temp; + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + + __asm__ __volatile__ ( + "1: lr.w %0, %2 \n\t" + " bne %0, %3, 2f \n\t" + " sc.w %1, %4, %2 \n\t" + " bnez %1, 1b \n\t" + "2: \n\t" + : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc_temp), /*%2*/"+A" (*dest) + : /*%3*/"r" ((int64_t)(int32_t)compare_value), /*%4*/"r" (exchange_value) + : "memory" ); + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + return (T)old_value; +} +#endif + template template inline T Atomic::PlatformXchg::operator()(T volatile* dest, @@ -148,54 +186,21 @@ inline T Atomic::PlatformCmpxchg::operator()(T volatile* dest __attri atomic_memory_order order) const { #ifndef FULL_COMPILER_ATOMIC_SUPPORT - STATIC_ASSERT(byte_size >= 4); + STATIC_ASSERT(byte_size > 4); #endif STATIC_ASSERT(byte_size == sizeof(T)); - T value = compare_value; if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } - __atomic_compare_exchange(dest, &value, &exchange_value, /* weak */ false, + __atomic_compare_exchange(dest, &compare_value, &exchange_value, /* weak */ false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } - return value; -} - -template<> -template -inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest __attribute__((unused)), - T compare_value, - T exchange_value, - atomic_memory_order order) const { - STATIC_ASSERT(4 == sizeof(T)); - - T old_value; - long rc; - - if (order != memory_order_relaxed) { - FULL_MEM_BARRIER; - } - - __asm__ __volatile__ ( - "1: sext.w %1, %3 \n\t" // sign-extend compare_value - " lr.w %0, %2 \n\t" - " bne %0, %1, 2f \n\t" - " sc.w %1, %4, %2 \n\t" - " bnez %1, 1b \n\t" - "2: \n\t" - : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc), /*%2*/"+A" (*dest) - : /*%3*/"r" (compare_value), /*%4*/"r" (exchange_value) - : "memory" ); - - if (order != memory_order_relaxed) { - FULL_MEM_BARRIER; - } - return old_value; + return compare_value; } template From 6c5500bba68d62040004b3157b128ae645eb60c8 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 19 Apr 2024 09:48:40 +0000 Subject: [PATCH 192/298] 8318986: Improve GenericWaitBarrier performance Backport-of: 30462f9da40d3a7ec18fcf46e2154fabb5fd4753 --- .../share/utilities/waitBarrier_generic.cpp | 261 ++++++++++++++---- .../share/utilities/waitBarrier_generic.hpp | 74 ++++- 2 files changed, 274 insertions(+), 61 deletions(-) diff --git a/src/hotspot/share/utilities/waitBarrier_generic.cpp b/src/hotspot/share/utilities/waitBarrier_generic.cpp index b5d9ff67eb7..dbf4db336c2 100644 --- a/src/hotspot/share/utilities/waitBarrier_generic.cpp +++ b/src/hotspot/share/utilities/waitBarrier_generic.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. 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,66 +30,228 @@ #include "utilities/waitBarrier_generic.hpp" #include "utilities/spinYield.hpp" +// Implements the striped semaphore wait barrier. +// +// To guarantee progress and safety, we need to make sure that new barrier tag +// starts with the completely empty set of waiters and free semaphore. This +// requires either waiting for all threads to leave wait() for current barrier +// tag on disarm(), or waiting for all threads to leave the previous tag before +// reusing the semaphore in arm(). +// +// When there are multiple threads, it is normal for some threads to take +// significant time to leave the barrier. Waiting for these threads introduces +// stalls on barrier reuse. +// +// If we wait on disarm(), this stall is nearly guaranteed to happen if some threads +// are de-scheduled by prior wait(). It would be especially bad if there are more +// waiting threads than CPUs: every thread would need to wake up and register itself +// as leaving, before we can unblock from disarm(). +// +// If we wait on arm(), we can get lucky that most threads would be able to catch up, +// exit wait(), and so we arrive to arm() with semaphore ready for reuse. However, +// that is still insufficient in practice. +// +// Therefore, this implementation goes a step further and implements the _striped_ +// semaphores. We maintain several semaphores in cells. The barrier tags are assigned +// to cells in some simple manner. Most of the current uses have sequential barrier +// tags, so simple modulo works well. We then operate on a cell like we would operate +// on a single semaphore: we wait at arm() for all threads to catch up before reusing +// the cell. For the cost of maintaining just a few cells, we have enough window for +// threads to catch up. +// +// The correctness is guaranteed by using a single atomic state variable per cell, +// with updates always done with CASes: +// +// [.......... barrier tag ..........][.......... waiters ..........] +// 63 31 0 +// +// Cell starts with zero tag and zero waiters. Arming the cell swings barrier tag from +// zero to some tag, while checking that no waiters have appeared. Disarming swings +// the barrier tag back from tag to zero. Every waiter registers itself by incrementing +// the "waiters", while checking that barrier tag is still the same. Every completing waiter +// decrements the "waiters". When all waiters complete, a cell ends up in initial state, +// ready to be armed again. This allows accurate tracking of how many signals +// to issue and does not race with disarm. +// +// The implementation uses the strongest (default) barriers for extra safety, even +// when not strictly required to do so for correctness. Extra barrier overhead is +// dominated by the actual wait/notify latency anyway. +// + void GenericWaitBarrier::arm(int barrier_tag) { - assert(_barrier_tag == 0, "Already armed"); - assert(_waiters == 0, "We left a thread hanging"); - _barrier_tag = barrier_tag; - _waiters = 0; + assert(barrier_tag != 0, "Pre arm: Should be arming with armed value"); + assert(Atomic::load(&_barrier_tag) == 0, + "Pre arm: Should not be already armed. Tag: %d", + Atomic::load(&_barrier_tag)); + Atomic::release_store(&_barrier_tag, barrier_tag); + + Cell &cell = tag_to_cell(barrier_tag); + cell.arm(barrier_tag); + + // API specifies arm() must provide a trailing fence. OrderAccess::fence(); } -int GenericWaitBarrier::wake_if_needed() { - assert(_barrier_tag == 0, "Not disarmed"); - int w = _waiters; - if (w == 0) { - // Load of _barrier_threads in caller must not pass the load of _waiters. - OrderAccess::loadload(); - return 0; - } - assert(w > 0, "Bad counting"); - // We need an exact count which never goes below zero, - // otherwise the semaphore may be signalled too many times. - if (Atomic::cmpxchg(&_waiters, w, w - 1) == w) { - _sem_barrier.signal(); - return w - 1; - } - return w; +void GenericWaitBarrier::disarm() { + int barrier_tag = Atomic::load_acquire(&_barrier_tag); + assert(barrier_tag != 0, "Pre disarm: Should be armed. Tag: %d", barrier_tag); + Atomic::release_store(&_barrier_tag, 0); + + Cell &cell = tag_to_cell(barrier_tag); + cell.disarm(barrier_tag); + + // API specifies disarm() must provide a trailing fence. + OrderAccess::fence(); } -void GenericWaitBarrier::disarm() { - assert(_barrier_tag != 0, "Not armed"); - _barrier_tag = 0; - // Loads of _barrier_threads/_waiters must not float above disarm store and - // disarm store must not sink below. +void GenericWaitBarrier::wait(int barrier_tag) { + assert(barrier_tag != 0, "Pre wait: Should be waiting on armed value"); + + Cell &cell = tag_to_cell(barrier_tag); + cell.wait(barrier_tag); + + // API specifies wait() must provide a trailing fence. OrderAccess::fence(); - int left; +} + +void GenericWaitBarrier::Cell::arm(int32_t requested_tag) { + // Before we continue to arm, we need to make sure that all threads + // have left the previous cell. + + int64_t state; + SpinYield sp; - do { - left = GenericWaitBarrier::wake_if_needed(); - if (left == 0 && _barrier_threads > 0) { - // There is no thread to wake but we still have barrier threads. + while (true) { + state = Atomic::load_acquire(&_state); + assert(decode_tag(state) == 0, + "Pre arm: Should not be armed. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + decode_tag(state), decode_waiters(state)); + if (decode_waiters(state) == 0) { + break; + } + sp.wait(); + } + + // Try to swing cell to armed. This should always succeed after the check above. + int64_t new_state = encode(requested_tag, 0); + int64_t prev_state = Atomic::cmpxchg(&_state, state, new_state); + if (prev_state != state) { + fatal("Cannot arm the wait barrier. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + decode_tag(prev_state), decode_waiters(prev_state)); + } +} + +int GenericWaitBarrier::Cell::signal_if_needed(int max) { + int signals = 0; + while (true) { + int cur = Atomic::load_acquire(&_outstanding_wakeups); + if (cur == 0) { + // All done, no more waiters. + return 0; + } + assert(cur > 0, "Sanity"); + + int prev = Atomic::cmpxchg(&_outstanding_wakeups, cur, cur - 1); + if (prev != cur) { + // Contention, return to caller for early return or backoff. + return prev; + } + + // Signal! + _sem.signal(); + + if (++signals >= max) { + // Signalled requested number of times, break out. + return prev; + } + } +} + +void GenericWaitBarrier::Cell::disarm(int32_t expected_tag) { + int32_t waiters; + + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + waiters = decode_waiters(state); + + assert((tag == expected_tag) && (waiters >= 0), + "Mid disarm: Should be armed with expected tag and have sane waiters. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(0, waiters); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Successfully disarmed. + break; + } + } + + // Wake up waiters, if we have at least one. + // Allow other threads to assist with wakeups, if possible. + if (waiters > 0) { + Atomic::release_store(&_outstanding_wakeups, waiters); + SpinYield sp; + while (signal_if_needed(INT_MAX) > 0) { sp.wait(); } - // We must loop here until there are no waiters or potential waiters. - } while (left > 0 || _barrier_threads > 0); - // API specifies disarm() must provide a trailing fence. - OrderAccess::fence(); + } + assert(Atomic::load(&_outstanding_wakeups) == 0, "Post disarm: Should not have outstanding wakeups"); } -void GenericWaitBarrier::wait(int barrier_tag) { - assert(barrier_tag != 0, "Trying to wait on disarmed value"); - if (barrier_tag != _barrier_tag) { - // API specifies wait() must provide a trailing fence. - OrderAccess::fence(); - return; +void GenericWaitBarrier::Cell::wait(int32_t expected_tag) { + // Try to register ourselves as pending waiter. + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + if (tag != expected_tag) { + // Cell tag had changed while waiting here. This means either the cell had + // been disarmed, or we are late and the cell was armed with a new tag. + // Exit without touching anything else. + return; + } + int32_t waiters = decode_waiters(state); + + assert((tag == expected_tag) && (waiters >= 0 && waiters < INT32_MAX), + "Before wait: Should be armed with expected tag and waiters are in range. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(tag, waiters + 1); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Success! Proceed to wait. + break; + } } - Atomic::add(&_barrier_threads, 1); - if (barrier_tag != 0 && barrier_tag == _barrier_tag) { - Atomic::add(&_waiters, 1); - _sem_barrier.wait(); - // We help out with posting, but we need to do so before we decrement the - // _barrier_threads otherwise we might wake threads up in next wait. - GenericWaitBarrier::wake_if_needed(); + + // Wait for notification. + _sem.wait(); + + // Unblocked! We help out with waking up two siblings. This allows to avalanche + // the wakeups for many threads, even if some threads are lagging behind. + // Note that we can only do this *before* reporting back as completed waiter, + // otherwise we might prematurely wake up threads for another barrier tag. + // Current arm() sequence protects us from this trouble by waiting until all waiters + // leave. + signal_if_needed(2); + + // Register ourselves as completed waiter before leaving. + while (true) { + int64_t state = Atomic::load_acquire(&_state); + int32_t tag = decode_tag(state); + int32_t waiters = decode_waiters(state); + + assert((tag == 0) && (waiters > 0), + "After wait: Should be not armed and have non-complete waiters. " + "Tag: " INT32_FORMAT "; Waiters: " INT32_FORMAT, + tag, waiters); + + int64_t new_state = encode(tag, waiters - 1); + if (Atomic::cmpxchg(&_state, state, new_state) == state) { + // Success! + break; + } } - Atomic::add(&_barrier_threads, -1); } diff --git a/src/hotspot/share/utilities/waitBarrier_generic.hpp b/src/hotspot/share/utilities/waitBarrier_generic.hpp index 50bfea6aebf..d3a45b33b82 100644 --- a/src/hotspot/share/utilities/waitBarrier_generic.hpp +++ b/src/hotspot/share/utilities/waitBarrier_generic.hpp @@ -26,29 +26,79 @@ #define SHARE_UTILITIES_WAITBARRIER_GENERIC_HPP #include "memory/allocation.hpp" +#include "memory/padded.hpp" #include "runtime/semaphore.hpp" #include "utilities/globalDefinitions.hpp" -// In addition to the barrier tag, it uses two counters to keep the semaphore -// count correct and not leave any late thread waiting. class GenericWaitBarrier : public CHeapObj { +private: + class Cell : public CHeapObj { + private: + // Pad out the cells to avoid interference between the cells. + // This would insulate from stalls when adjacent cells have returning + // workers and contend over the cache line for current latency-critical + // cell. + DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0); + + Semaphore _sem; + + // Cell state, tracks the arming + waiters status + volatile int64_t _state; + + // Wakeups to deliver for current waiters + volatile int _outstanding_wakeups; + + int signal_if_needed(int max); + + static int64_t encode(int32_t barrier_tag, int32_t waiters) { + int64_t val = (((int64_t) barrier_tag) << 32) | + (((int64_t) waiters) & 0xFFFFFFFF); + assert(decode_tag(val) == barrier_tag, "Encoding is reversible"); + assert(decode_waiters(val) == waiters, "Encoding is reversible"); + return val; + } + + static int32_t decode_tag(int64_t value) { + return (int32_t)(value >> 32); + } + + static int32_t decode_waiters(int64_t value) { + return (int32_t)(value & 0xFFFFFFFF); + } + + public: + Cell() : _sem(0), _state(encode(0, 0)), _outstanding_wakeups(0) {} + NONCOPYABLE(Cell); + + void arm(int32_t requested_tag); + void disarm(int32_t expected_tag); + void wait(int32_t expected_tag); + }; + + // Should be enough for most uses without exploding the footprint. + static constexpr int CELLS_COUNT = 16; + + Cell _cells[CELLS_COUNT]; + + // Trailing padding to protect the last cell. + DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0); + volatile int _barrier_tag; - // The number of threads waiting on or about to wait on the semaphore. - volatile int _waiters; - // The number of threads in the wait path, before or after the tag check. - // These threads can become waiters. - volatile int _barrier_threads; - Semaphore _sem_barrier; + + // Trailing padding to insulate the rest of the barrier from adjacent + // data structures. The leading padding is not needed, as cell padding + // handles this for us. + DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); NONCOPYABLE(GenericWaitBarrier); - int wake_if_needed(); + Cell& tag_to_cell(int tag) { return _cells[tag & (CELLS_COUNT - 1)]; } - public: - GenericWaitBarrier() : _barrier_tag(0), _waiters(0), _barrier_threads(0), _sem_barrier(0) {} +public: + GenericWaitBarrier() : _cells(), _barrier_tag(0) {} ~GenericWaitBarrier() {} - const char* description() { return "semaphore"; } + const char* description() { return "striped semaphore"; } void arm(int barrier_tag); void disarm(); From 686399a5be1289b4a9f82467292e71cfda5ba0c3 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Fri, 19 Apr 2024 09:50:37 +0000 Subject: [PATCH 193/298] 8318599: HttpURLConnection cache issues leading to crashes in JGSS w/ native GSS introduced by 8303809 Backport-of: f1a24f6d4827f9b8648dd2afe6d606dab67d51fe --- .../sun/net/www/protocol/http/NegotiateAuthentication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 1021503318e..7881a1480c9 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -152,7 +152,7 @@ private static HashMap getCache() { @Override protected boolean useAuthCache() { - return super.useAuthCache() && cacheSPNEGO; + return false; } /** From e63addbc4d3f77e5c93b18c92243be72bf1eb9cd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:14:36 +0000 Subject: [PATCH 194/298] 8315503: G1: Code root scan causes long GC pauses due to imbalanced iteration 8317440: Lock rank checking fails when code root set is modified with the Servicelock held after JDK-8315503 8318720: G1: Memory leak in G1CodeRootSet after JDK-8315503 Reviewed-by: sgehwolf, shade Backport-of: 795e5dcc856491031b87a1f2a942681a582673ab --- src/hotspot/share/gc/g1/g1CodeRootSet.cpp | 293 ++++++++++++++---- src/hotspot/share/gc/g1/g1CodeRootSet.hpp | 24 +- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 3 +- src/hotspot/share/gc/g1/g1Policy.cpp | 2 +- src/hotspot/share/gc/g1/g1RemSet.cpp | 27 +- .../share/gc/g1/g1RemSetTrackingPolicy.cpp | 2 +- src/hotspot/share/gc/g1/heapRegion.cpp | 21 +- src/hotspot/share/gc/g1/heapRegion.hpp | 1 - src/hotspot/share/gc/g1/heapRegionRemSet.cpp | 31 +- src/hotspot/share/gc/g1/heapRegionRemSet.hpp | 3 - src/hotspot/share/runtime/mutexLocker.cpp | 2 +- .../utilities/concurrentHashTable.inline.hpp | 2 +- .../gtest/gc/g1/test_g1CodeRootSet.cpp | 17 +- 13 files changed, 267 insertions(+), 161 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp index bbb1f3b9006..59d877554ea 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp @@ -28,82 +28,261 @@ #include "code/nmethod.hpp" #include "gc/g1/g1CodeRootSet.hpp" #include "gc/g1/heapRegion.hpp" +#include "memory/allocation.hpp" #include "oops/oop.inline.hpp" +#include "runtime/atomic.hpp" +#include "utilities/concurrentHashTable.inline.hpp" +#include "utilities/concurrentHashTableTasks.inline.hpp" -void G1CodeRootSet::add(nmethod* nm) { - assert(_is_iterating == false, "should not mutate while iterating the table"); - bool added = false; - if (_table == nullptr) { - _table = new (mtGC) Table(SmallSize, LargeSize); +class G1CodeRootSetHashTableConfig : public StackObj { +public: + using Value = nmethod*; + + static uintx get_hash(Value const& value, bool* is_dead); + + static void* allocate_node(void* context, size_t size, Value const& value) { + return AllocateHeap(size, mtGC); } - added = _table->put(nm, nm); - if (added && _table->table_size() == SmallSize && length() == Threshold) { - _table->resize(LargeSize); + + static void free_node(void* context, void* memory, Value const& value) { + FreeHeap(memory); } +}; + +// Storage container for the code root set. +class G1CodeRootSetHashTable : public CHeapObj { + using HashTable = ConcurrentHashTable; + using HashTableScanTask = HashTable::ScanTask; + + // Default (log2) number of buckets; small since typically we do not expect many + // entries. + static const size_t Log2DefaultNumBuckets = 2; + static const uint BucketClaimSize = 16; + + HashTable _table; + HashTableScanTask _table_scanner; + + size_t volatile _num_entries; + + bool is_empty() const { return number_of_entries() == 0; } + + class HashTableLookUp : public StackObj { + nmethod* _nmethod; + + public: + explicit HashTableLookUp(nmethod* nmethod) : _nmethod(nmethod) { } + uintx get_hash() const; + bool equals(nmethod** value); + bool is_dead(nmethod** value) const { return false; } + }; + + class HashTableIgnore : public StackObj { + public: + HashTableIgnore() { } + void operator()(nmethod** value) { /* do nothing */ } + }; + +public: + G1CodeRootSetHashTable() : + _table(Log2DefaultNumBuckets, + HashTable::DEFAULT_MAX_SIZE_LOG2), + _table_scanner(&_table, BucketClaimSize), _num_entries(0) { + clear(); + } + + // Robert Jenkins 1996 & Thomas Wang 1997 + // http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm + static uint32_t hash(uint32_t key) { + key = ~key + (key << 15); + key = key ^ (key >> 12); + key = key + (key << 2); + key = key ^ (key >> 4); + key = key * 2057; + key = key ^ (key >> 16); + return key; + } + + static uintx get_hash(nmethod* nmethod) { + uintptr_t value = (uintptr_t)nmethod; + // The CHT only uses the bits smaller than HashTable::DEFAULT_MAX_SIZE_LOG2, so + // try to increase the randomness by incorporating the upper bits of the + // address too. + STATIC_ASSERT(HashTable::DEFAULT_MAX_SIZE_LOG2 <= sizeof(uint32_t) * BitsPerByte); +#ifdef _LP64 + return hash((uint32_t)value ^ (uint32_t(value >> 32))); +#else + return hash((uint32_t)value); +#endif + } + + void insert(nmethod* method) { + HashTableLookUp lookup(method); + bool grow_hint = false; + bool inserted = _table.insert(Thread::current(), lookup, method, &grow_hint); + if (inserted) { + Atomic::inc(&_num_entries); + } + if (grow_hint) { + _table.grow(Thread::current()); + } + } + + bool remove(nmethod* method) { + HashTableLookUp lookup(method); + bool removed = _table.remove(Thread::current(), lookup); + if (removed) { + Atomic::dec(&_num_entries); + } + return removed; + } + + bool contains(nmethod* method) { + HashTableLookUp lookup(method); + HashTableIgnore ignore; + return _table.get(Thread::current(), lookup, ignore); + } + + void clear() { + // Remove all entries. + auto always_true = [] (nmethod** value) { + return true; + }; + clean(always_true); + } + + void iterate_at_safepoint(CodeBlobClosure* blk) { + assert_at_safepoint(); + // A lot of code root sets are typically empty. + if (is_empty()) { + return; + } + + auto do_value = + [&] (nmethod** value) { + blk->do_code_blob(*value); + return true; + }; + _table_scanner.do_safepoint_scan(do_value); + } + + // Removes entries as indicated by the given EVAL closure. + template + void clean(EVAL& eval) { + // A lot of code root sets are typically empty. + if (is_empty()) { + return; + } + + size_t num_deleted = 0; + auto do_delete = + [&] (nmethod** value) { + num_deleted++; + }; + bool succeeded = _table.try_bulk_delete(Thread::current(), eval, do_delete); + guarantee(succeeded, "unable to clean table"); + + if (num_deleted != 0) { + size_t current_size = Atomic::sub(&_num_entries, num_deleted); + shrink_to_match(current_size); + } + } + + // Calculate the log2 of the table size we want to shrink to. + size_t log2_target_shrink_size(size_t current_size) const { + // A table with the new size should be at most filled by this factor. Otherwise + // we would grow again quickly. + const float WantedLoadFactor = 0.5; + size_t min_expected_size = checked_cast(ceil(current_size / WantedLoadFactor)); + + size_t result = Log2DefaultNumBuckets; + if (min_expected_size != 0) { + size_t log2_bound = checked_cast(log2i_exact(round_up_power_of_2(min_expected_size))); + result = clamp(log2_bound, Log2DefaultNumBuckets, HashTable::DEFAULT_MAX_SIZE_LOG2); + } + return result; + } + + // Shrink to keep table size appropriate to the given number of entries. + void shrink_to_match(size_t current_size) { + size_t prev_log2size = _table.get_size_log2(Thread::current()); + size_t new_log2_table_size = log2_target_shrink_size(current_size); + if (new_log2_table_size < prev_log2size) { + _table.shrink(Thread::current(), new_log2_table_size); + } + } + + void reset_table_scanner() { + _table_scanner.set(&_table, BucketClaimSize); + } + + size_t mem_size() { return sizeof(*this) + _table.get_mem_size(Thread::current()); } + + size_t number_of_entries() const { return Atomic::load(&_num_entries); } +}; + +uintx G1CodeRootSetHashTable::HashTableLookUp::get_hash() const { + return G1CodeRootSetHashTable::get_hash(_nmethod); +} + +bool G1CodeRootSetHashTable::HashTableLookUp::equals(nmethod** value) { + return *value == _nmethod; +} + +uintx G1CodeRootSetHashTableConfig::get_hash(Value const& value, bool* is_dead) { + *is_dead = false; + return G1CodeRootSetHashTable::get_hash(value); } +size_t G1CodeRootSet::length() const { return _table->number_of_entries(); } + +void G1CodeRootSet::add(nmethod* method) { + if (!contains(method)) { + assert(!_is_iterating, "must be"); + _table->insert(method); + } +} + +G1CodeRootSet::G1CodeRootSet() : + _table(new G1CodeRootSetHashTable()) + DEBUG_ONLY(COMMA _is_iterating(false)) { } + G1CodeRootSet::~G1CodeRootSet() { delete _table; } bool G1CodeRootSet::remove(nmethod* method) { - assert(_is_iterating == false, "should not mutate while iterating the table"); - bool removed = false; - if (_table != nullptr) { - removed = _table->remove(method); - } - if (removed) { - if (length() == 0) { - clear(); - } - } - return removed; + assert(!_is_iterating, "should not mutate while iterating the table"); + return _table->remove(method); } bool G1CodeRootSet::contains(nmethod* method) { - if (_table != nullptr) { - return _table->contains(method); - } - return false; + return _table->contains(method); } void G1CodeRootSet::clear() { - assert(_is_iterating == false, "should not mutate while iterating the table"); - delete _table; - _table = nullptr; + assert(!_is_iterating, "should not mutate while iterating the table"); + _table->clear(); } size_t G1CodeRootSet::mem_size() { - return (_table == nullptr) - ? sizeof(*this) - : sizeof(*this) + _table->mem_size(); + return sizeof(*this) + _table->mem_size(); +} + +void G1CodeRootSet::reset_table_scanner() { + _table->reset_table_scanner(); } void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const { DEBUG_ONLY(_is_iterating = true;) - if (_table != nullptr) { - _table->iterate_all([&](nmethod* nm, nmethod* _) { - blk->do_code_blob(nm); - }); - } + _table->iterate_at_safepoint(blk); DEBUG_ONLY(_is_iterating = false;) } class CleanCallback : public StackObj { NONCOPYABLE(CleanCallback); // can not copy, _blobs will point to old copy + class PointsIntoHRDetectionClosure : public OopClosure { HeapRegion* _hr; - public: - bool _points_into; - PointsIntoHRDetectionClosure(HeapRegion* hr) : _hr(hr), _points_into(false) {} - - void do_oop(narrowOop* o) { - do_oop_work(o); - } - - void do_oop(oop* o) { - do_oop_work(o); - } template void do_oop_work(T* p) { @@ -111,6 +290,14 @@ class CleanCallback : public StackObj { _points_into = true; } } + + public: + bool _points_into; + PointsIntoHRDetectionClosure(HeapRegion* hr) : _hr(hr), _points_into(false) {} + + void do_oop(narrowOop* o) { do_oop_work(o); } + + void do_oop(oop* o) { do_oop_work(o); } }; PointsIntoHRDetectionClosure _detector; @@ -119,20 +306,16 @@ class CleanCallback : public StackObj { public: CleanCallback(HeapRegion* hr) : _detector(hr), _blobs(&_detector, !CodeBlobToOopClosure::FixRelocations) {} - bool do_entry(nmethod* nm, nmethod* _) { + bool operator()(nmethod** value) { _detector._points_into = false; - _blobs.do_code_blob(nm); + _blobs.do_code_blob(*value); return !_detector._points_into; } }; void G1CodeRootSet::clean(HeapRegion* owner) { - assert(_is_iterating == false, "should not mutate while iterating the table"); - CleanCallback should_clean(owner); - if (_table != nullptr) { - _table->unlink(&should_clean); - } - if (length() == 0) { - clear(); - } + assert(!_is_iterating, "should not mutate while iterating the table"); + + CleanCallback eval(owner); + _table->clean(eval); } diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.hpp b/src/hotspot/share/gc/g1/g1CodeRootSet.hpp index 087c3635cf0..d1051e6e42e 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.hpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.hpp @@ -27,43 +27,37 @@ #include "code/codeCache.hpp" #include "utilities/globalDefinitions.hpp" -#include "utilities/resizeableResourceHash.hpp" +class G1CodeRootSetHashTable; class HeapRegion; class nmethod; // Implements storage for a set of code roots. -// This class is not thread safe, locks are needed. +// This class is thread safe. class G1CodeRootSet { - friend class G1CodeRootSetTest; - friend class G1CodeRootSetTest_g1_code_cache_rem_set_vm_Test; - - private: - const static size_t SmallSize = 32; - const static size_t Threshold = 24; - const static size_t LargeSize = 512; - - using Table = ResizeableResourceHashtable; - Table* _table; + G1CodeRootSetHashTable* _table; DEBUG_ONLY(mutable bool _is_iterating;) public: - G1CodeRootSet() : _table(nullptr) DEBUG_ONLY(COMMA _is_iterating(false)) {} + G1CodeRootSet(); ~G1CodeRootSet(); void add(nmethod* method); bool remove(nmethod* method); bool contains(nmethod* method); void clear(); + + // Prepare for MT iteration. Must be called before nmethods_do. + void reset_table_scanner(); void nmethods_do(CodeBlobClosure* blk) const; - // Remove all nmethods which no longer contain pointers into our "owner" region + // Remove all nmethods which no longer contain pointers into our "owner" region. void clean(HeapRegion* owner); bool is_empty() { return length() == 0;} // Length in elements - size_t length() const { return _table == nullptr ? 0 : _table->number_of_entries(); } + size_t length() const; // Memory size in bytes taken by this set. size_t mem_size(); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index eeaa54cee85..03eafb1a323 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -3008,8 +3008,7 @@ class RegisterNMethodOopClosure: public OopClosure { " starting at " HR_FORMAT, p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - // HeapRegion::add_code_root_locked() avoids adding duplicate entries. - hr->add_code_root_locked(_nm); + hr->add_code_root(_nm); } } diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index 92c83301c2a..5f19861e8fb 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -1276,7 +1276,7 @@ void G1Policy::abandon_collection_set_candidates() { // Clear remembered sets of remaining candidate regions and the actual candidate // set. for (HeapRegion* r : *candidates()) { - r->rem_set()->clear_locked(true /* only_cardset */); + r->rem_set()->clear(true /* only_cardset */); } _collection_set->abandon_all_candidates(); } diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 49d1fac634a..58adb87f86c 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -257,7 +257,6 @@ class G1RemSetScanState : public CHeapObj { public: G1RemSetScanState() : _max_reserved_regions(0), - _collection_set_iter_state(nullptr), _card_table_scan_state(nullptr), _scan_chunks_per_region(G1CollectedHeap::get_chunks_per_region()), _log_scan_chunks_per_region(log2i(_scan_chunks_per_region)), @@ -270,16 +269,14 @@ class G1RemSetScanState : public CHeapObj { } ~G1RemSetScanState() { - FREE_C_HEAP_ARRAY(G1RemsetIterState, _collection_set_iter_state); FREE_C_HEAP_ARRAY(uint, _card_table_scan_state); FREE_C_HEAP_ARRAY(bool, _region_scan_chunks); FREE_C_HEAP_ARRAY(HeapWord*, _scan_top); } void initialize(size_t max_reserved_regions) { - assert(_collection_set_iter_state == nullptr, "Must not be initialized twice"); + assert(_card_table_scan_state == nullptr, "Must not be initialized twice"); _max_reserved_regions = max_reserved_regions; - _collection_set_iter_state = NEW_C_HEAP_ARRAY(G1RemsetIterState, max_reserved_regions, mtGC); _card_table_scan_state = NEW_C_HEAP_ARRAY(uint, max_reserved_regions, mtGC); _num_total_scan_chunks = max_reserved_regions * _scan_chunks_per_region; _region_scan_chunks = NEW_C_HEAP_ARRAY(bool, _num_total_scan_chunks, mtGC); @@ -294,7 +291,6 @@ class G1RemSetScanState : public CHeapObj { // become used during the collection these values must be valid // for those regions as well. for (size_t i = 0; i < _max_reserved_regions; i++) { - reset_region_claim((uint)i); clear_scan_top((uint)i); } @@ -399,20 +395,6 @@ class G1RemSetScanState : public CHeapObj { } while (cur != start_pos); } - void reset_region_claim(uint region_idx) { - _collection_set_iter_state[region_idx] = false; - } - - // Attempt to claim the given region in the collection set for iteration. Returns true - // if this call caused the transition from Unclaimed to Claimed. - inline bool claim_collection_set_region(uint region) { - assert(region < _max_reserved_regions, "Tried to access invalid region %u", region); - if (_collection_set_iter_state[region]) { - return false; - } - return !Atomic::cmpxchg(&_collection_set_iter_state[region], false, true); - } - bool has_cards_to_scan(uint region) { assert(region < _max_reserved_regions, "Tried to access invalid region %u", region); return _card_table_scan_state[region] < HeapRegion::CardsPerRegion; @@ -829,8 +811,6 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { _rem_set_opt_trim_partially_time() { } bool do_heap_region(HeapRegion* r) { - uint const region_idx = r->hrm_index(); - // The individual references for the optional remembered set are per-worker, so we // always need to scan them. if (r->has_index_in_opt_cset()) { @@ -841,7 +821,8 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_scan_phase)); } - if (_scan_state->claim_collection_set_region(region_idx)) { + // Scan code root remembered sets. + { EventGCPhaseParallel event; G1EvacPhaseWithTrimTimeTracker timer(_pss, _code_root_scan_time, _code_trim_partially_time); G1ScanAndCountCodeBlobClosure cl(_pss->closures()->weak_codeblobs()); @@ -1210,7 +1191,7 @@ class G1MergeHeapRootsTask : public WorkerTask { // implicitly rebuild anything else during eager reclaim. Note that at the moment // (and probably never) we do not enter this path if there are other kind of // remembered sets for this region. - r->rem_set()->clear_locked(true /* only_cardset */); + r->rem_set()->clear(true /* only_cardset */); // Clear_locked() above sets the state to Empty. However we want to continue // collecting remembered set entries for humongous regions that were not // reclaimed. diff --git a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp index 6d1633786e6..0a91f2aea50 100644 --- a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp @@ -142,7 +142,7 @@ void G1RemSetTrackingPolicy::update_after_rebuild(HeapRegion* r) { [&] (HeapRegion* r) { assert(!r->is_continues_humongous() || r->rem_set()->is_empty(), "Continues humongous region %u remset should be empty", r->hrm_index()); - r->rem_set()->clear_locked(true /* only_cardset */); + r->rem_set()->clear(true /* only_cardset */); }); } G1ConcurrentMark* cm = G1CollectedHeap::heap()->concurrent_mark(); diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index a79977d2545..a34d6b85458 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -107,7 +107,7 @@ void HeapRegion::handle_evacuation_failure() { move_to_old(); _rem_set->clean_code_roots(this); - _rem_set->clear_locked(true /* only_cardset */); + _rem_set->clear(true /* only_cardset */); } void HeapRegion::unlink_from_list() { @@ -124,7 +124,7 @@ void HeapRegion::hr_clear(bool clear_space) { set_free(); reset_pre_dummy_top(); - rem_set()->clear_locked(); + rem_set()->clear(); init_top_at_mark_start(); if (clear_space) clear(SpaceDecorator::Mangle); @@ -207,7 +207,7 @@ void HeapRegion::clear_humongous() { } void HeapRegion::prepare_remset_for_scan() { - return _rem_set->reset_table_scanner(); + _rem_set->reset_table_scanner(); } HeapRegion::HeapRegion(uint hrm_index, @@ -288,24 +288,15 @@ void HeapRegion::note_self_forward_chunk_done(size_t garbage_bytes) { // Code roots support void HeapRegion::add_code_root(nmethod* nm) { - HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_code_root(nm); -} - -void HeapRegion::add_code_root_locked(nmethod* nm) { - assert_locked_or_safepoint(CodeCache_lock); - HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_code_root_locked(nm); + rem_set()->add_code_root(nm); } void HeapRegion::remove_code_root(nmethod* nm) { - HeapRegionRemSet* hrrs = rem_set(); - hrrs->remove_code_root(nm); + rem_set()->remove_code_root(nm); } void HeapRegion::code_roots_do(CodeBlobClosure* blk) const { - HeapRegionRemSet* hrrs = rem_set(); - hrrs->code_roots_do(blk); + rem_set()->code_roots_do(blk); } class VerifyCodeRootOopClosure: public OopClosure { diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index 05a3299889b..ce49e62c939 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -549,7 +549,6 @@ class HeapRegion : public CHeapObj { // Routines for managing a list of code roots (attached to the // this region's RSet) that point into this heap region. void add_code_root(nmethod* nm); - void add_code_root_locked(nmethod* nm); void remove_code_root(nmethod* nm); // Applies blk->do_code_blob() to each of the entries in diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp index 8289cdf553b..a805108537a 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp @@ -57,7 +57,6 @@ void HeapRegionRemSet::initialize(MemRegion reserved) { HeapRegionRemSet::HeapRegionRemSet(HeapRegion* hr, G1CardSetConfiguration* config) : - _m(Mutex::service - 1, FormatBuffer<128>("HeapRegionRemSet#%u_lock", hr->hrm_index())), _code_roots(), _card_set_mm(config, G1CollectedHeap::heap()->card_set_freelist_pool()), _card_set(config, &_card_set_mm), @@ -69,11 +68,6 @@ void HeapRegionRemSet::clear_fcc() { } void HeapRegionRemSet::clear(bool only_cardset) { - MutexLocker x(&_m, Mutex::_no_safepoint_check_flag); - clear_locked(only_cardset); -} - -void HeapRegionRemSet::clear_locked(bool only_cardset) { if (!only_cardset) { _code_roots.clear(); } @@ -84,6 +78,7 @@ void HeapRegionRemSet::clear_locked(bool only_cardset) { } void HeapRegionRemSet::reset_table_scanner() { + _code_roots.reset_table_scanner(); _card_set.reset_table_scanner(); } @@ -103,34 +98,12 @@ void HeapRegionRemSet::print_static_mem_size(outputStream* out) { // When not at safepoint the CodeCache_lock must be held during modifications. void HeapRegionRemSet::add_code_root(nmethod* nm) { - assert(nm != nullptr, "sanity"); - assert((!CodeCache_lock->owned_by_self() || SafepointSynchronize::is_at_safepoint()), - "should call add_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s", - BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint())); - - MutexLocker ml(&_m, Mutex::_no_safepoint_check_flag); - add_code_root_locked(nm); -} - -void HeapRegionRemSet::add_code_root_locked(nmethod* nm) { - assert(nm != nullptr, "sanity"); - assert((CodeCache_lock->owned_by_self() || - (SafepointSynchronize::is_at_safepoint() && - (_m.owned_by_self() || Thread::current()->is_VM_thread()))), - "not safely locked. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s, _m.owned_by_self(): %s, Thread::current()->is_VM_thread(): %s", - BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()), - BOOL_TO_STR(_m.owned_by_self()), BOOL_TO_STR(Thread::current()->is_VM_thread())); - - if (!_code_roots.contains(nm)) { // with this test, we can assert that we do not modify the hash table while iterating over it - _code_roots.add(nm); - } + _code_roots.add(nm); } void HeapRegionRemSet::remove_code_root(nmethod* nm) { assert(nm != nullptr, "sanity"); - assert_locked_or_safepoint(CodeCache_lock); - MutexLocker ml(CodeCache_lock->owned_by_self() ? nullptr : &_m, Mutex::_no_safepoint_check_flag); _code_roots.remove(nm); // Check that there were no duplicates diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp index 584275e9d8b..15c472d0ac9 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp @@ -40,7 +40,6 @@ class outputStream; class HeapRegionRemSet : public CHeapObj { friend class VMStructs; - Mutex _m; // A set of code blobs (nmethods) whose code contains pointers into // the region that owns this RSet. G1CodeRootSet _code_roots; @@ -118,7 +117,6 @@ class HeapRegionRemSet : public CHeapObj { // The region is being reclaimed; clear its remset, and any mention of // entries for this region in other remsets. void clear(bool only_cardset = false); - void clear_locked(bool only_cardset = false); void reset_table_scanner(); @@ -167,7 +165,6 @@ class HeapRegionRemSet : public CHeapObj { // Returns true if the code roots contains the given // nmethod. bool code_roots_list_contains(nmethod* nm) { - MutexLocker ml(&_m, Mutex::_no_safepoint_check_flag); return _code_roots.contains(nm); } diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index e62b29a328c..d25fd8fd5b4 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -304,7 +304,7 @@ void mutex_init() { MUTEX_DEFN(ContinuationRelativize_lock , PaddedMonitor, nosafepoint-3); MUTEX_DEFN(CodeHeapStateAnalytics_lock , PaddedMutex , safepoint); - MUTEX_DEFN(ThreadsSMRDelete_lock , PaddedMonitor, nosafepoint-3); // Holds ConcurrentHashTableResize_lock + MUTEX_DEFN(ThreadsSMRDelete_lock , PaddedMonitor, service-2); // Holds ConcurrentHashTableResize_lock MUTEX_DEFN(ThreadIdTableCreate_lock , PaddedMutex , safepoint); MUTEX_DEFN(SharedDecoder_lock , PaddedMutex , tty-1); MUTEX_DEFN(DCmdFactory_lock , PaddedMutex , nosafepoint); diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index b222d379b72..ee9e7c4bfc8 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -1024,7 +1024,7 @@ ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bo _stats_rate = nullptr; } _resize_lock = - new Mutex(Mutex::nosafepoint-2, "ConcurrentHashTableResize_lock"); + new Mutex(Mutex::service-1, "ConcurrentHashTableResize_lock"); _table = new InternalTable(log2size); assert(log2size_limit >= log2size, "bad ergo"); _size_limit_reached = _table->_log2_size == _log2_size_limit; diff --git a/test/hotspot/gtest/gc/g1/test_g1CodeRootSet.cpp b/test/hotspot/gtest/gc/g1/test_g1CodeRootSet.cpp index 8ab1c60954d..2a8f52ec0d1 100644 --- a/test/hotspot/gtest/gc/g1/test_g1CodeRootSet.cpp +++ b/test/hotspot/gtest/gc/g1/test_g1CodeRootSet.cpp @@ -25,15 +25,7 @@ #include "gc/g1/g1CodeRootSet.hpp" #include "unittest.hpp" -class G1CodeRootSetTest : public ::testing::Test { - public: - - size_t threshold() { - return G1CodeRootSet::Threshold; - } -}; - -TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) { +TEST_VM(G1CodeRootSet, g1_code_cache_rem_set) { G1CodeRootSet root_set; ASSERT_TRUE(root_set.is_empty()) << "Code root set must be initially empty " @@ -43,7 +35,7 @@ TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) { ASSERT_EQ(root_set.length(), (size_t) 1) << "Added exactly one element, but" " set contains " << root_set.length() << " elements"; - const size_t num_to_add = (size_t) threshold() + 1; + const size_t num_to_add = 1000; for (size_t i = 1; i <= num_to_add; i++) { root_set.add((nmethod*) 1); @@ -60,9 +52,6 @@ TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) { << "After adding in total " << num_to_add << " distinct code roots, " "they need to be in the set, but there are only " << root_set.length(); - ASSERT_EQ(root_set._table->table_size(), 512u) - << "should have grown to large hashtable"; - size_t num_popped = 0; for (size_t i = 1; i <= num_to_add; i++) { bool removed = root_set.remove((nmethod*) i); @@ -76,5 +65,5 @@ TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) { << "Managed to pop " << num_popped << " code roots, but only " << num_to_add << " were added"; ASSERT_EQ(root_set.length(), 0u) - << "should have grown to large hashtable"; + << "should be empty"; } From f341621cc7225a610cb95035bfdeabb4e3c17368 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:47:23 +0000 Subject: [PATCH 195/298] 8323685: PrintSystemDictionaryAtExit has mutex rank assert Backport-of: 2865afe759fd5362abd0947fd4c1f5c8d3519ca3 --- src/hotspot/share/gc/g1/g1CardSet.cpp | 7 +++- src/hotspot/share/gc/g1/g1CodeRootSet.cpp | 8 ++-- .../share/utilities/concurrentHashTable.hpp | 8 ++-- .../utilities/concurrentHashTable.inline.hpp | 7 ++-- .../utilities/test_concurrentHashtable.cpp | 4 +- .../ClassfilePrintingTests.java} | 37 ++++++++++++++++--- 6 files changed, 51 insertions(+), 20 deletions(-) rename test/hotspot/jtreg/runtime/{PrintStringTableStats/PrintStringTableStatsTest.java => PrintingTests/ClassfilePrintingTests.java} (57%) diff --git a/src/hotspot/share/gc/g1/g1CardSet.cpp b/src/hotspot/share/gc/g1/g1CardSet.cpp index f39e2066739..98cd1943224 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.cpp +++ b/src/hotspot/share/gc/g1/g1CardSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -286,7 +286,10 @@ class G1CardSetHashTable : public CHeapObj { size_t initial_log_table_size = InitialLogTableSize) : _inserted_card(false), _mm(mm), - _table(mm, initial_log_table_size, false), + _table(Mutex::service-1, + mm, + initial_log_table_size, + false /* enable_statistics */), _table_scanner(&_table, BucketClaimSize) { } diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp index 59d877554ea..af369e68088 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -84,8 +84,10 @@ class G1CodeRootSetHashTable : public CHeapObj { public: G1CodeRootSetHashTable() : - _table(Log2DefaultNumBuckets, - HashTable::DEFAULT_MAX_SIZE_LOG2), + _table(Mutex::service-1, + nullptr, + Log2DefaultNumBuckets, + false /* enable_statistics */), _table_scanner(&_table, BucketClaimSize), _num_entries(0) { clear(); } diff --git a/src/hotspot/share/utilities/concurrentHashTable.hpp b/src/hotspot/share/utilities/concurrentHashTable.hpp index 0336f06916b..fe6fdb0a95e 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -26,6 +26,7 @@ #define SHARE_UTILITIES_CONCURRENTHASHTABLE_HPP #include "memory/allocation.hpp" +#include "runtime/mutex.hpp" #include "utilities/globalCounter.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" @@ -406,10 +407,11 @@ class ConcurrentHashTable : public CHeapObj { size_t log2size_limit = DEFAULT_MAX_SIZE_LOG2, size_t grow_hint = DEFAULT_GROW_HINT, bool enable_statistics = DEFAULT_ENABLE_STATISTICS, + Mutex::Rank rank = Mutex::nosafepoint-2, void* context = nullptr); - explicit ConcurrentHashTable(void* context, size_t log2size = DEFAULT_START_SIZE_LOG2, bool enable_statistics = DEFAULT_ENABLE_STATISTICS) : - ConcurrentHashTable(log2size, DEFAULT_MAX_SIZE_LOG2, DEFAULT_GROW_HINT, enable_statistics, context) {} + explicit ConcurrentHashTable(Mutex::Rank rank, void* context, size_t log2size = DEFAULT_START_SIZE_LOG2, bool enable_statistics = DEFAULT_ENABLE_STATISTICS) : + ConcurrentHashTable(log2size, DEFAULT_MAX_SIZE_LOG2, DEFAULT_GROW_HINT, enable_statistics, rank, context) {} ~ConcurrentHashTable(); diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index ee9e7c4bfc8..13c219da212 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -1012,7 +1012,7 @@ inline size_t ConcurrentHashTable:: // Constructor template inline ConcurrentHashTable:: -ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bool enable_statistics, void* context) +ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bool enable_statistics, Mutex::Rank rank, void* context) : _context(context), _new_table(nullptr), _log2_size_limit(log2size_limit), _log2_start_size(log2size), _grow_hint(grow_hint), _size_limit_reached(false), _resize_lock_owner(nullptr), @@ -1023,8 +1023,7 @@ ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bo } else { _stats_rate = nullptr; } - _resize_lock = - new Mutex(Mutex::service-1, "ConcurrentHashTableResize_lock"); + _resize_lock = new Mutex(rank, "ConcurrentHashTableResize_lock"); _table = new InternalTable(log2size); assert(log2size_limit >= log2size, "bad ergo"); _size_limit_reached = _table->_log2_size == _log2_size_limit; diff --git a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp index ca41fc6b0f1..277b2c37b61 100644 --- a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp +++ b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -322,7 +322,7 @@ static void cht_reset_shrink(Thread* thr) { Allocator mem_allocator; const uint initial_log_table_size = 4; - CustomTestTable* cht = new CustomTestTable(&mem_allocator); + CustomTestTable* cht = new CustomTestTable(Mutex::nosafepoint-2, &mem_allocator); cht_insert_and_find(thr, cht, val1); cht_insert_and_find(thr, cht, val2); diff --git a/test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java b/test/hotspot/jtreg/runtime/PrintingTests/ClassfilePrintingTests.java similarity index 57% rename from test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java rename to test/hotspot/jtreg/runtime/PrintingTests/ClassfilePrintingTests.java index 4dfde2f1d0b..175d28cc56e 100644 --- a/test/hotspot/jtreg/runtime/PrintStringTableStats/PrintStringTableStatsTest.java +++ b/test/hotspot/jtreg/runtime/PrintingTests/ClassfilePrintingTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -23,17 +23,25 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Platform; /* - * @test PrintStringTableStatsTest - * @bug 8211821 + * @test + * @summary Test various printing functions in classfile directory + * @bug 8211821 8323685 * @requires vm.flagless * @library /test/lib - * @run driver PrintStringTableStatsTest + * @run driver ClassfilePrintingTests */ -public class PrintStringTableStatsTest { - public static void main(String... args) throws Exception { +class SampleClass { + public static void main(java.lang.String[] unused) { + System.out.println("Hello from the sample class"); + } +} + +public class ClassfilePrintingTests { + private static void printStringTableStatsTest() throws Exception { ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( "-XX:+PrintStringTableStatistics", "--version"); @@ -41,4 +49,21 @@ public static void main(String... args) throws Exception { output.shouldContain("Number of buckets"); output.shouldHaveExitValue(0); } + + private static void printSystemDictionaryAtExitTest() throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:+PrintSystemDictionaryAtExit", + "SampleClass"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain(SampleClass.class.getName()); + output.shouldContain("jdk/internal/loader/ClassLoaders$AppClassLoader"); + output.shouldHaveExitValue(0); + } + + public static void main(String... args) throws Exception { + printStringTableStatsTest(); + if (Platform.isDebugBuild()) { + printSystemDictionaryAtExitTest(); + } + } } From 41c8606efb95b8d4663a996c0a22363fb15a5704 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:51:55 +0000 Subject: [PATCH 196/298] 8316959: Improve InlineCacheBuffer pending queue management Reviewed-by: roland Backport-of: c9985720b91cf6ad2938e9be12da08c5193f83af --- src/hotspot/share/code/icBuffer.cpp | 37 +++++++++++++++------ src/hotspot/share/code/icBuffer.hpp | 6 ++-- src/hotspot/share/oops/compiledICHolder.cpp | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/code/icBuffer.cpp b/src/hotspot/share/code/icBuffer.cpp index 520a8c75259..dbceefb7c8e 100644 --- a/src/hotspot/share/code/icBuffer.cpp +++ b/src/hotspot/share/code/icBuffer.cpp @@ -34,6 +34,7 @@ #include "memory/resourceArea.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaThread.hpp" #include "runtime/mutexLocker.hpp" @@ -44,8 +45,8 @@ DEF_STUB_INTERFACE(ICStub); StubQueue* InlineCacheBuffer::_buffer = nullptr; -CompiledICHolder* InlineCacheBuffer::_pending_released = nullptr; -int InlineCacheBuffer::_pending_count = 0; +CompiledICHolder* volatile InlineCacheBuffer::_pending_released = nullptr; +volatile int InlineCacheBuffer::_pending_count = 0; #ifdef ASSERT ICRefillVerifier::ICRefillVerifier() @@ -247,26 +248,42 @@ void* InlineCacheBuffer::cached_value_for(CompiledIC *ic) { // Free CompiledICHolder*s that are no longer in use void InlineCacheBuffer::release_pending_icholders() { assert(SafepointSynchronize::is_at_safepoint(), "should only be called during a safepoint"); - CompiledICHolder* holder = _pending_released; + CompiledICHolder* holder = Atomic::load(&_pending_released); _pending_released = nullptr; + int count = 0; while (holder != nullptr) { CompiledICHolder* next = holder->next(); delete holder; holder = next; - _pending_count--; + count++; } - assert(_pending_count == 0, "wrong count"); + assert(pending_icholder_count() == count, "wrong count"); + Atomic::store(&_pending_count, 0); } // Enqueue this icholder for release during the next safepoint. It's -// not safe to free them until them since they might be visible to +// not safe to free them until then since they might be visible to // another thread. void InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) { - MutexLocker mex(InlineCacheBuffer_lock, Mutex::_no_safepoint_check_flag); - icholder->set_next(_pending_released); - _pending_released = icholder; - _pending_count++; + assert(icholder->next() == nullptr, "multiple enqueue?"); + + CompiledICHolder* old = Atomic::load(&_pending_released); + for (;;) { + icholder->set_next(old); + // The only reader runs at a safepoint serially so there is no need for a more strict atomic. + CompiledICHolder* cur = Atomic::cmpxchg(&_pending_released, old, icholder, memory_order_relaxed); + if (cur == old) { + break; + } + old = cur; + } + Atomic::inc(&_pending_count, memory_order_relaxed); + if (TraceICBuffer) { tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", p2i(icholder)); } } + +int InlineCacheBuffer::pending_icholder_count() { + return Atomic::load(&_pending_count); +} diff --git a/src/hotspot/share/code/icBuffer.hpp b/src/hotspot/share/code/icBuffer.hpp index d385b99d59d..c2da3abdca3 100644 --- a/src/hotspot/share/code/icBuffer.hpp +++ b/src/hotspot/share/code/icBuffer.hpp @@ -146,8 +146,8 @@ class InlineCacheBuffer: public AllStatic { static StubQueue* _buffer; - static CompiledICHolder* _pending_released; - static int _pending_count; + static CompiledICHolder* volatile _pending_released; + static volatile int _pending_count; static StubQueue* buffer() { return _buffer; } @@ -176,7 +176,7 @@ class InlineCacheBuffer: public AllStatic { static void release_pending_icholders(); static void queue_for_release(CompiledICHolder* icholder); - static int pending_icholder_count() { return _pending_count; } + static int pending_icholder_count(); // New interface static bool create_transition_stub(CompiledIC *ic, void* cached_value, address entry); diff --git a/src/hotspot/share/oops/compiledICHolder.cpp b/src/hotspot/share/oops/compiledICHolder.cpp index c6ca6be2030..8bfa55bcce7 100644 --- a/src/hotspot/share/oops/compiledICHolder.cpp +++ b/src/hotspot/share/oops/compiledICHolder.cpp @@ -32,7 +32,7 @@ volatile int CompiledICHolder::_live_not_claimed_count; #endif CompiledICHolder::CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method) - : _holder_metadata(metadata), _holder_klass(klass), _is_metadata_method(is_method) { + : _holder_metadata(metadata), _holder_klass(klass), _next(nullptr), _is_metadata_method(is_method) { #ifdef ASSERT Atomic::inc(&_live_count); Atomic::inc(&_live_not_claimed_count); From 5a94e48505cb0f83b18bd0b14fd3a226e8119fb7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:53:13 +0000 Subject: [PATCH 197/298] 8317600: VtableStubs::stub_containing() table load not ordered wrt to stores Reviewed-by: adinn Backport-of: c566dfccf8aa0d5cd53a6e4de61a1bca9f1367b5 --- src/hotspot/share/code/vtableStubs.cpp | 34 ++++++++++++-------------- src/hotspot/share/code/vtableStubs.hpp | 6 ++--- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/hotspot/share/code/vtableStubs.cpp b/src/hotspot/share/code/vtableStubs.cpp index 3c07bdba733..eed3dc8e787 100644 --- a/src/hotspot/share/code/vtableStubs.cpp +++ b/src/hotspot/share/code/vtableStubs.cpp @@ -95,8 +95,7 @@ void VtableStub::print() const { print_on(tty); } // hash value). Each list is anchored in a little hash _table, indexed // by that hash value. -VtableStub* VtableStubs::_table[VtableStubs::N]; -int VtableStubs::_number_of_vtable_stubs = 0; +VtableStub* volatile VtableStubs::_table[VtableStubs::N]; int VtableStubs::_vtab_stub_size = 0; int VtableStubs::_itab_stub_size = 0; @@ -126,13 +125,13 @@ int VtableStubs::_itab_stub_size = 0; void VtableStubs::initialize() { + assert(VtableStub::_receiver_location == VMRegImpl::Bad(), "initialized multiple times?"); + VtableStub::_receiver_location = SharedRuntime::name_for_receiver(); { MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); - assert(_number_of_vtable_stubs == 0, "potential performance bug: VtableStubs initialized more than once"); - assert(is_power_of_2(int(N)), "N must be a power of 2"); for (int i = 0; i < N; i++) { - _table[i] = nullptr; + Atomic::store(&_table[i], (VtableStub*)nullptr); } } } @@ -259,7 +258,7 @@ inline uint VtableStubs::hash(bool is_vtable_stub, int vtable_index){ VtableStub* VtableStubs::lookup(bool is_vtable_stub, int vtable_index) { assert_lock_strong(VtableStubs_lock); unsigned hash = VtableStubs::hash(is_vtable_stub, vtable_index); - VtableStub* s = _table[hash]; + VtableStub* s = Atomic::load(&_table[hash]); while( s && !s->matches(is_vtable_stub, vtable_index)) s = s->next(); return s; } @@ -269,10 +268,10 @@ void VtableStubs::enter(bool is_vtable_stub, int vtable_index, VtableStub* s) { assert_lock_strong(VtableStubs_lock); assert(s->matches(is_vtable_stub, vtable_index), "bad vtable stub"); unsigned int h = VtableStubs::hash(is_vtable_stub, vtable_index); - // enter s at the beginning of the corresponding list - s->set_next(_table[h]); - _table[h] = s; - _number_of_vtable_stubs++; + // Insert s at the beginning of the corresponding list. + s->set_next(Atomic::load(&_table[h])); + // Make sure that concurrent readers not taking the mutex observe the writing of "next". + Atomic::release_store(&_table[h], s); } VtableStub* VtableStubs::entry_point(address pc) { @@ -280,7 +279,7 @@ VtableStub* VtableStubs::entry_point(address pc) { VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index()); VtableStub* s; - for (s = _table[hash]; s != nullptr && s != stub; s = s->next()) {} + for (s = Atomic::load(&_table[hash]); s != nullptr && s != stub; s = s->next()) {} return (s == stub) ? s : nullptr; } @@ -299,11 +298,8 @@ bool VtableStubs::contains(address pc) { VtableStub* VtableStubs::stub_containing(address pc) { - // Note: No locking needed since any change to the data structure - // happens with an atomic store into it (we don't care about - // consistency with the _number_of_vtable_stubs counter). for (int i = 0; i < N; i++) { - for (VtableStub* s = _table[i]; s != nullptr; s = s->next()) { + for (VtableStub* s = Atomic::load_acquire(&_table[i]); s != nullptr; s = s->next()) { if (s->contains(pc)) return s; } } @@ -315,11 +311,11 @@ void vtableStubs_init() { } void VtableStubs::vtable_stub_do(void f(VtableStub*)) { - for (int i = 0; i < N; i++) { - for (VtableStub* s = _table[i]; s != nullptr; s = s->next()) { - f(s); - } + for (int i = 0; i < N; i++) { + for (VtableStub* s = Atomic::load_acquire(&_table[i]); s != nullptr; s = s->next()) { + f(s); } + } } diff --git a/src/hotspot/share/code/vtableStubs.hpp b/src/hotspot/share/code/vtableStubs.hpp index a2bb24f34ce..0a7308d9038 100644 --- a/src/hotspot/share/code/vtableStubs.hpp +++ b/src/hotspot/share/code/vtableStubs.hpp @@ -79,10 +79,11 @@ class VtableStubs : AllStatic { mask = N - 1 }; + static_assert(is_power_of_2((int)N), "N must be a power of 2"); + private: friend class VtableStub; - static VtableStub* _table[N]; // table of existing stubs - static int _number_of_vtable_stubs; // number of stubs created so far (for statistics) + static VtableStub* volatile _table[N]; // table of existing stubs static int _vtab_stub_size; // current size estimate for vtable stub (quasi-constant) static int _itab_stub_size; // current size estimate for itable stub (quasi-constant) @@ -108,7 +109,6 @@ class VtableStubs : AllStatic { static bool is_icholder_entry(address pc); // is the blob containing pc (which must be a vtable blob) an icholder? static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or nullptr - static int number_of_vtable_stubs() { return _number_of_vtable_stubs; } static void initialize(); static void vtable_stub_do(void f(VtableStub*)); // iterates over all vtable stubs }; From 2a3c4fc1e4da52f0587fcc2d3d2efc74f249ada0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:54:43 +0000 Subject: [PATCH 198/298] 8318109: Writing JFR records while a CHT has taken its lock asserts in rank checking Reviewed-by: mbaesken, sgehwolf Backport-of: 9f767aa44b4699ed5404b934ac751f2cdd0ba824 --- src/hotspot/share/runtime/mutexLocker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index d25fd8fd5b4..f7587bc6723 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -294,7 +294,7 @@ void mutex_init() { #if INCLUDE_JFR MUTEX_DEFN(JfrBuffer_lock , PaddedMutex , event); MUTEX_DEFN(JfrMsg_lock , PaddedMonitor, event); - MUTEX_DEFN(JfrStacktrace_lock , PaddedMutex , stackwatermark-1); + MUTEX_DEFN(JfrStacktrace_lock , PaddedMutex , event); MUTEX_DEFN(JfrThreadSampler_lock , PaddedMonitor, nosafepoint); #endif From 7c6379146e3b5c5625ff25f1585d3d14d778ed70 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 19 Apr 2024 10:56:07 +0000 Subject: [PATCH 199/298] 8319955: Improve dependencies removal during class unloading Reviewed-by: stuefe Backport-of: fbe19378c38decaff221f6570d1b78bb801a5e5d --- src/hotspot/share/code/dependencyContext.cpp | 43 ++++++++++++++++++-- src/hotspot/share/code/dependencyContext.hpp | 1 + 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/code/dependencyContext.cpp b/src/hotspot/share/code/dependencyContext.cpp index a6697ba366a..d7ce8e92acf 100644 --- a/src/hotspot/share/code/dependencyContext.cpp +++ b/src/hotspot/share/code/dependencyContext.cpp @@ -111,8 +111,7 @@ void DependencyContext::add_dependent_nmethod(nmethod* nm) { } void DependencyContext::release(nmethodBucket* b) { - bool expunge = Atomic::load(&_cleaning_epoch) == 0; - if (expunge) { + if (delete_on_release()) { assert_locked_or_safepoint(CodeCache_lock); delete b; if (UsePerfData) { @@ -178,9 +177,41 @@ nmethodBucket* DependencyContext::release_and_get_next_not_unloading(nmethodBuck // // Invalidate all dependencies in the context void DependencyContext::remove_all_dependents() { - nmethodBucket* b = dependencies_not_unloading(); + // Assume that the dependency is not deleted immediately but moved into the + // purge list when calling this. + assert(!delete_on_release(), "should not delete on release"); + + nmethodBucket* first = Atomic::load_acquire(_dependency_context_addr); + if (first == nullptr) { + return; + } + + nmethodBucket* cur = first; + nmethodBucket* last = cur; + jlong count = 0; + for (; cur != nullptr; cur = cur->next()) { + assert(cur->get_nmethod()->is_unloading(), "must be"); + last = cur; + count++; + } + + // Add the whole list to the purge list at once. + nmethodBucket* old_purge_list_head = Atomic::load(&_purge_list); + for (;;) { + last->set_purge_list_next(old_purge_list_head); + nmethodBucket* next_purge_list_head = Atomic::cmpxchg(&_purge_list, old_purge_list_head, first); + if (old_purge_list_head == next_purge_list_head) { + break; + } + old_purge_list_head = next_purge_list_head; + } + + if (UsePerfData) { + _perf_total_buckets_stale_count->inc(count); + _perf_total_buckets_stale_acc_count->inc(count); + } + set_dependencies(nullptr); - assert(b == nullptr, "All dependents should be unloading"); } void DependencyContext::remove_and_mark_for_deoptimization_all_dependents(DeoptimizationScope* deopt_scope) { @@ -234,6 +265,10 @@ bool DependencyContext::claim_cleanup() { return Atomic::cmpxchg(_last_cleanup_addr, last_cleanup, cleaning_epoch) == last_cleanup; } +bool DependencyContext::delete_on_release() { + return Atomic::load(&_cleaning_epoch) == 0; +} + // Retrieve the first nmethodBucket that has a dependent that does not correspond to // an is_unloading nmethod. Any nmethodBucket entries observed from the original head // that is_unloading() will be unlinked and placed on the purge list. diff --git a/src/hotspot/share/code/dependencyContext.hpp b/src/hotspot/share/code/dependencyContext.hpp index 630311c2e1e..e8d2ac41d0d 100644 --- a/src/hotspot/share/code/dependencyContext.hpp +++ b/src/hotspot/share/code/dependencyContext.hpp @@ -75,6 +75,7 @@ class DependencyContext : public StackObj { volatile uint64_t* _last_cleanup_addr; bool claim_cleanup(); + static bool delete_on_release(); void set_dependencies(nmethodBucket* b); nmethodBucket* dependencies(); nmethodBucket* dependencies_not_unloading(); From 515783b86c5efae1f5385b4bc869869af58cb5bc Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 22 Apr 2024 07:47:02 +0000 Subject: [PATCH 200/298] 8328166: Epsilon: 'EpsilonHeap::allocate_work' misuses the parameter 'size' as size in bytes Backport-of: 90ab52e598f74ed872fe404130d57f6596430727 --- src/hotspot/share/gc/epsilon/epsilonHeap.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp index 3907d904e2f..c44baa3cc04 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -124,14 +124,15 @@ HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) { } // Expand and loop back if space is available + size_t size_in_bytes = size * HeapWordSize; size_t space_left = max_capacity() - capacity(); - size_t want_space = MAX2(size, EpsilonMinHeapExpand); + size_t want_space = MAX2(size_in_bytes, EpsilonMinHeapExpand); if (want_space < space_left) { // Enough space to expand in bulk: bool expand = _virtual_space.expand_by(want_space); assert(expand, "Should be able to expand"); - } else if (size < space_left) { + } else if (size_in_bytes < space_left) { // No space to expand in bulk, and this allocation is still possible, // take all the remaining space: bool expand = _virtual_space.expand_by(space_left); From 667513aeb1ffdab3ada8595d55ff955b8d3d77c3 Mon Sep 17 00:00:00 2001 From: Vladimir Petko Date: Mon, 22 Apr 2024 08:53:37 +0000 Subject: [PATCH 201/298] 8325028: (ch) Pipe channels should lazily set socket to non-blocking mode on first use by virtual thread Backport-of: d1099033ac63b9dd0dd6e3a7341db929e9e0e56e --- .../classes/sun/nio/ch/SinkChannelImpl.java | 47 ++++++++++++++++--- .../classes/sun/nio/ch/SourceChannelImpl.java | 47 ++++++++++++++++--- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java index b49b699fdce..d72a4892ef0 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -66,6 +66,13 @@ class SinkChannelImpl // ID of native thread doing write, for signalling private long thread; + // True if the channel's socket has been forced into non-blocking mode + // by a virtual thread. It cannot be reset. When the channel is in + // blocking mode and the channel's socket is in non-blocking mode then + // operations that don't complete immediately will poll the socket and + // preserve the semantics of blocking operations. + private volatile boolean forcedNonBlocking; + // -- End of fields protected by stateLock @@ -79,11 +86,34 @@ public int getFDVal() { SinkChannelImpl(SelectorProvider sp, FileDescriptor fd) throws IOException { super(sp); - IOUtil.configureBlocking(fd, false); this.fd = fd; this.fdVal = IOUtil.fdVal(fd); } + /** + * Checks that the channel is open. + * + * @throws ClosedChannelException if channel is closed (or closing) + */ + private void ensureOpen() throws ClosedChannelException { + if (!isOpen()) + throw new ClosedChannelException(); + } + + /** + * Ensures that the socket is configured non-blocking when on a virtual thread. + */ + private void configureSocketNonBlockingIfVirtualThread() throws IOException { + assert writeLock.isHeldByCurrentThread(); + if (!forcedNonBlocking && Thread.currentThread().isVirtual()) { + synchronized (stateLock) { + ensureOpen(); + IOUtil.configureBlocking(fd, false); + forcedNonBlocking = true; + } + } + } + /** * Closes the write end of the pipe if there are no write operation in * progress and the channel is not registered with a Selector. @@ -183,9 +213,11 @@ protected void implConfigureBlocking(boolean block) throws IOException { writeLock.lock(); try { synchronized (stateLock) { - if (!isOpen()) - throw new ClosedChannelException(); - IOUtil.configureBlocking(fd, block); + ensureOpen(); + // do nothing if virtual thread has forced the socket to be non-blocking + if (!forcedNonBlocking) { + IOUtil.configureBlocking(fd, block); + } } } finally { writeLock.unlock(); @@ -241,8 +273,7 @@ private void beginWrite(boolean blocking) throws ClosedChannelException { begin(); } synchronized (stateLock) { - if (!isOpen()) - throw new ClosedChannelException(); + ensureOpen(); if (blocking) thread = NativeThread.current(); } @@ -279,6 +310,7 @@ public int write(ByteBuffer src) throws IOException { int n = 0; try { beginWrite(blocking); + configureSocketNonBlockingIfVirtualThread(); n = IOUtil.write(fd, src, -1, nd); if (blocking) { while (IOStatus.okayToRetry(n) && isOpen()) { @@ -306,6 +338,7 @@ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException long n = 0; try { beginWrite(blocking); + configureSocketNonBlockingIfVirtualThread(); n = IOUtil.write(fd, srcs, offset, length, nd); if (blocking) { while (IOStatus.okayToRetry(n) && isOpen()) { diff --git a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java index 7c2791609a7..7be17040b4c 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -66,6 +66,13 @@ class SourceChannelImpl // ID of native thread doing read, for signalling private long thread; + // True if the channel's socket has been forced into non-blocking mode + // by a virtual thread. It cannot be reset. When the channel is in + // blocking mode and the channel's socket is in non-blocking mode then + // operations that don't complete immediately will poll the socket and + // preserve the semantics of blocking operations. + private volatile boolean forcedNonBlocking; + // -- End of fields protected by stateLock @@ -79,11 +86,34 @@ public int getFDVal() { SourceChannelImpl(SelectorProvider sp, FileDescriptor fd) throws IOException { super(sp); - IOUtil.configureBlocking(fd, false); this.fd = fd; this.fdVal = IOUtil.fdVal(fd); } + /** + * Checks that the channel is open. + * + * @throws ClosedChannelException if channel is closed (or closing) + */ + private void ensureOpen() throws ClosedChannelException { + if (!isOpen()) + throw new ClosedChannelException(); + } + + /** + * Ensures that the socket is configured non-blocking when on a virtual thread. + */ + private void configureSocketNonBlockingIfVirtualThread() throws IOException { + assert readLock.isHeldByCurrentThread(); + if (!forcedNonBlocking && Thread.currentThread().isVirtual()) { + synchronized (stateLock) { + ensureOpen(); + IOUtil.configureBlocking(fd, false); + forcedNonBlocking = true; + } + } + } + /** * Closes the read end of the pipe if there are no read operation in * progress and the channel is not registered with a Selector. @@ -183,9 +213,11 @@ protected void implConfigureBlocking(boolean block) throws IOException { readLock.lock(); try { synchronized (stateLock) { - if (!isOpen()) - throw new ClosedChannelException(); - IOUtil.configureBlocking(fd, block); + ensureOpen(); + // do nothing if virtual thread has forced the socket to be non-blocking + if (!forcedNonBlocking) { + IOUtil.configureBlocking(fd, block); + } } } finally { readLock.unlock(); @@ -241,8 +273,7 @@ private void beginRead(boolean blocking) throws ClosedChannelException { begin(); } synchronized (stateLock) { - if (!isOpen()) - throw new ClosedChannelException(); + ensureOpen(); if (blocking) thread = NativeThread.current(); } @@ -279,6 +310,7 @@ public int read(ByteBuffer dst) throws IOException { int n = 0; try { beginRead(blocking); + configureSocketNonBlockingIfVirtualThread(); n = IOUtil.read(fd, dst, -1, nd); if (blocking) { while (IOStatus.okayToRetry(n) && isOpen()) { @@ -306,6 +338,7 @@ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { long n = 0; try { beginRead(blocking); + configureSocketNonBlockingIfVirtualThread(); n = IOUtil.read(fd, dsts, offset, length, nd); if (blocking) { while (IOStatus.okayToRetry(n) && isOpen()) { From d19b1a4cccc697039907731bcc358e8aed3ce5df Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 22 Apr 2024 13:55:30 +0000 Subject: [PATCH 202/298] 8327486: java/util/Properties/PropertiesStoreTest.java fails "Text 'xxx' could not be parsed at index 20" after 8174269 Backport-of: e21da4caacb464827270d20b8fc62a50a1706316 --- test/jdk/java/util/Properties/PropertiesStoreTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/util/Properties/PropertiesStoreTest.java b/test/jdk/java/util/Properties/PropertiesStoreTest.java index ab58ea78903..b5a5b5a45aa 100644 --- a/test/jdk/java/util/Properties/PropertiesStoreTest.java +++ b/test/jdk/java/util/Properties/PropertiesStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -55,9 +55,9 @@ public class PropertiesStoreTest { private static final String DATE_FORMAT_PATTERN = "EEE MMM dd HH:mm:ss zzz uuuu"; - // use a neutral locale, since when the date comment was written by Properties.store(...), - // it internally calls the Date.toString() which always writes in a locale insensitive manner - private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_PATTERN, Locale.ROOT); + // use Locale.US, since when the date comment was written by Properties.store(...), + // it internally calls the Date.toString() which uses Locale.US for time zone names + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_PATTERN, Locale.US); private static final Locale PREV_LOCALE = Locale.getDefault(); @DataProvider(name = "propsProvider") From 9b04df20e005e27bc1887650ed4de4ca6089d09d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 22 Apr 2024 13:57:10 +0000 Subject: [PATCH 203/298] 8327180: Failed: java/io/ObjectStreamClass/ObjectStreamClassCaching.java#G1 Backport-of: 85fc47c81af81a595dc88e61454d8ba2d860f301 --- .../ObjectStreamClassCaching.java | 40 ++++--------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java index 9868c4611b5..115481243f7 100644 --- a/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java +++ b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -49,8 +49,12 @@ */ /* - * Disabled for ZGC Generational. - * TODO: Find correct appropriate solution to the flakiness of this test. + * @test id=ZGenerational + * @requires vm.gc.ZGenerational + * @bug 8277072 8327180 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive (ZGC) + * @run testng/othervm -Xmx64m -XX:+UseZGC -XX:+ZGenerational ObjectStreamClassCaching */ /* @@ -65,41 +69,13 @@ /* * @test id=Serial * @requires vm.gc.Serial - * @bug 8277072 + * @bug 8277072 8327180 * @library /test/lib/ * @summary ObjectStreamClass caches keep ClassLoaders alive (Serial GC) * @run testng/othervm -Xmx64m -XX:+UseSerialGC ObjectStreamClassCaching */ public class ObjectStreamClassCaching { - /** - * Test methods execute in same VM and are ordered by name. - * We test effectiveness 1st which is sensitive to previous allocations when ZGC is used. - */ - @Test - public void test1CacheEffectiveness() throws Exception { - var list = new ArrayList<>(); - var ref1 = lookupObjectStreamClass(TestClass1.class); - var ref2 = newWeakRef(); - boolean oome = false; - try { - while (!ref2.refersTo(null)) { - list.add(new byte[1024 * 1024 * 1]); // 1 MiB chunks - System.out.println("1MiB allocated..."); - Thread.sleep(5L); - } - } catch (OutOfMemoryError e) { - // release - list = null; - oome = true; - } - assertFalse(oome, "WeakReference was not cleared although memory was pressed hard"); - assertFalse(ref1.refersTo(null), - "Cache lost entry together with WeakReference being cleared although memory was not under pressure"); - System.gc(); - Thread.sleep(100L); - } - @Test public void test2CacheReleaseUnderMemoryPressure() throws Exception { var list = new ArrayList<>(); From 62993e7a1b1ea76386c24ae6b3dbc34bd08a3c92 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 22 Apr 2024 13:59:03 +0000 Subject: [PATCH 204/298] 8328555: hidpi problems for test java/awt/Dialog/DialogAnotherThread/JaWSTest.java Backport-of: 23ebd9c3c69d09e6afe672d00b43da2ccc493480 --- test/jdk/java/awt/Dialog/JaWSTest.java | 148 +++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/JaWSTest.java diff --git a/test/jdk/java/awt/Dialog/JaWSTest.java b/test/jdk/java/awt/Dialog/JaWSTest.java new file mode 100644 index 00000000000..8b7e8838258 --- /dev/null +++ b/test/jdk/java/awt/Dialog/JaWSTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2002, 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. + */ + +/* + @test + @bug 4690465 + @summary Tests that after dialog is hidden on another EDT, owning EDT gets notified. + @modules java.desktop/sun.awt + @key headful + @run main JaWSTest +*/ + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import sun.awt.SunToolkit; +import sun.awt.AppContext; + +public class JaWSTest implements ActionListener, Runnable { + + static volatile Frame frame; + static volatile JaWSTest worker; + static volatile Dialog dummyDialog; + static final Object signalObject = new Object(); + static volatile AppContext appContextObject = null; + static volatile Button button = null; + static final CountDownLatch dialogFinished = new CountDownLatch(1); + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(JaWSTest::createUI); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + Point buttonLocation = button.getLocationOnScreen(); + robot.mouseMove(buttonLocation.x + button.getWidth()/2, + buttonLocation.y + button.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + if (!dialogFinished.await(5, TimeUnit.SECONDS)) { + throw new RuntimeException("Dialog thread is blocked"); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + static void createUI() { + worker = new JaWSTest(); + frame = new Frame("JaWSTest Main User Frame"); + button = new Button("Press To Save"); + button.addActionListener(worker); + frame.add(button); + frame.pack(); + frame.setVisible(true); + } + + public void actionPerformed(ActionEvent ae) { + System.err.println("Action Performed"); + synchronized (signalObject) { + ThreadGroup askUser = new ThreadGroup("askUser"); + final Thread handler = new Thread(askUser, worker, "userDialog"); + + dummyDialog = new Dialog(frame, "Dummy Modal Dialog", true); + dummyDialog.setBounds(200, 200, 100, 100); + dummyDialog.addWindowListener(new WindowAdapter() { + public void windowOpened(WindowEvent we) { + System.err.println("handler is started"); + handler.start(); + } + public void windowClosing(WindowEvent e) { + dummyDialog.setVisible(false); + } + }); + dummyDialog.setResizable(false); + dummyDialog.toBack(); + System.err.println("Before First Modal"); + dummyDialog.setVisible(true); + System.err.println("After First Modal"); + try { + signalObject.wait(); + } catch (Exception e) { + e.printStackTrace(); + dummyDialog.setVisible(false); + } + if (appContextObject != null) { + appContextObject = null; + } + dummyDialog.dispose(); + } + System.err.println("Show Something"); + dialogFinished.countDown(); + } + + public void run() { + System.err.println("Running"); + try { + appContextObject = SunToolkit.createNewAppContext(); + } finally { + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + System.err.println("Before Hiding 1"); + dummyDialog.setVisible(false); + System.err.println("Before Synchronized"); + synchronized (signalObject) { + System.err.println("In Synchronized"); + signalObject.notify(); + System.err.println("After Notify"); + } + } + System.err.println("Stop Running"); + } +} From af6c5854235573a29b6b418e9f759e2564bca63a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 22 Apr 2024 14:01:24 +0000 Subject: [PATCH 205/298] 8327474: Review use of java.io.tmpdir in jdk tests Backport-of: 375bfac8e7ff3f871e2d986876f91a5fba200c83 --- .../HotSpotDiagnosticMXBean/CheckOrigin.java | 5 +- test/jdk/java/io/File/CheckPermission.java | 6 +- .../io/FileInputStream/NegativeAvailable.java | 41 ++++++----- .../java/nio/channels/unixdomain/Bind.java | 72 ++++++++++++------- .../unixdomain/NonBlockingAccept.java | 11 ++- test/jdk/java/util/zip/ZipFile/ZeroDate.java | 58 ++++++++------- .../api/consumer/filestream/TestOrdered.java | 6 +- .../api/consumer/filestream/TestReuse.java | 5 +- .../jfr/threading/TestManyVirtualThreads.java | 5 +- test/jdk/jdk/nio/zipfs/ZeroDate.java | 58 ++++++++------- .../jdk/sun/security/pkcs12/P12SecretKey.java | 40 ++++++----- 11 files changed, 180 insertions(+), 127 deletions(-) diff --git a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java index d0557e630f0..8f938575f5d 100644 --- a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java +++ b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -41,6 +41,7 @@ import java.io.InputStream; import java.io.PrintWriter; import java.lang.management.ManagementFactory; +import java.nio.file.Path; import java.util.Map; import jdk.test.lib.process.ProcessTools; import sun.tools.attach.HotSpotVirtualMachine; @@ -53,7 +54,7 @@ public static void main(String... args) throws Exception { if (args.length == 0) { // start a process that has options set in a number of different ways - File flagsFile = File.createTempFile("CheckOriginFlags", null); + File flagsFile = File.createTempFile("CheckOriginFlags", null, Path.of(".").toFile()); try (PrintWriter pw = new PrintWriter(new FileWriter(flagsFile))) { pw.println("+PrintCodeCache"); diff --git a/test/jdk/java/io/File/CheckPermission.java b/test/jdk/java/io/File/CheckPermission.java index f6126a08843..b1976c84b46 100644 --- a/test/jdk/java/io/File/CheckPermission.java +++ b/test/jdk/java/io/File/CheckPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -362,13 +362,13 @@ public boolean accept(File file) { "getFileSystemAttributes"); prepare(); - File tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null); + File tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null, new File(".")); assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE)); tmpFile.delete(); assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE)); prepare(); - tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null, null); + tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null, new File(".")); assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE)); tmpFile.delete(); assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE)); diff --git a/test/jdk/java/io/FileInputStream/NegativeAvailable.java b/test/jdk/java/io/FileInputStream/NegativeAvailable.java index a0e0e999231..27e1309f4ee 100644 --- a/test/jdk/java/io/FileInputStream/NegativeAvailable.java +++ b/test/jdk/java/io/FileInputStream/NegativeAvailable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -46,28 +46,31 @@ public static void main(String[] args) throws IOException { // Create a temporary file with size of 10 bytes. Path tmp = Files.createTempFile(null, null); - try (BufferedWriter writer = - Files.newBufferedWriter(tmp, Charset.defaultCharset())) { - for (int i = 0; i < SIZE; i++) { - writer.write('1'); + try { + try (BufferedWriter writer = + Files.newBufferedWriter(tmp, Charset.defaultCharset())) { + for (int i = 0; i < SIZE; i++) { + writer.write('1'); + } } - } - File tempFile = tmp.toFile(); - try (FileInputStream fis = new FileInputStream(tempFile)) { - if (tempFile.length() != SIZE) { - throw new RuntimeException("unexpected file size = " - + tempFile.length()); + File tempFile = tmp.toFile(); + try (FileInputStream fis = new FileInputStream(tempFile)) { + if (tempFile.length() != SIZE) { + throw new RuntimeException("unexpected file size = " + + tempFile.length()); + } + long space = skipBytes(fis, SKIP, SIZE); + space = skipBytes(fis, NEGATIVE_SKIP, space); + space = skipBytes(fis, SKIP, space); + space = skipBytes(fis, SKIP, space); + space = skipBytes(fis, SKIP, space); + space = skipBytes(fis, NEGATIVE_SKIP, space); + space = skipBytes(fis, NEGATIVE_SKIP, space); } - long space = skipBytes(fis, SKIP, SIZE); - space = skipBytes(fis, NEGATIVE_SKIP, space); - space = skipBytes(fis, SKIP, space); - space = skipBytes(fis, SKIP, space); - space = skipBytes(fis, SKIP, space); - space = skipBytes(fis, NEGATIVE_SKIP, space); - space = skipBytes(fis, NEGATIVE_SKIP, space); + } finally { + Files.deleteIfExists(tmp); } - Files.deleteIfExists(tmp); } /** diff --git a/test/jdk/java/nio/channels/unixdomain/Bind.java b/test/jdk/java/nio/channels/unixdomain/Bind.java index 47fc24ae1af..4f4e146a94f 100644 --- a/test/jdk/java/nio/channels/unixdomain/Bind.java +++ b/test/jdk/java/nio/channels/unixdomain/Bind.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -159,13 +159,17 @@ public static void runTests() throws IOException { }); // address with space should work checkNormal(() -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - UnixDomainSocketAddress usa = UnixDomainSocketAddress.of("with space"); // relative to CWD + UnixDomainSocketAddress usa = UnixDomainSocketAddress.of("with space"); Files.deleteIfExists(usa.getPath()); - server.bind(usa); - client = SocketChannel.open(usa); - Files.delete(usa.getPath()); - assertAddress(client.getRemoteAddress(), usa, "address"); + try { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + // relative to CWD + server.bind(usa); + client = SocketChannel.open(usa); + assertAddress(client.getRemoteAddress(), usa, "address"); + } finally { + Files.deleteIfExists(usa.getPath()); + } }); // client bind to null: allowed checkNormal(() -> { @@ -185,12 +189,19 @@ public static void runTests() throws IOException { }); // server bind to null: should bind to a local address checkNormal(() -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.bind(null); - UnixDomainSocketAddress usa = (UnixDomainSocketAddress)server.getLocalAddress(); - if (usa.getPath().toString().isEmpty()) - throw new RuntimeException("expected non zero address length"); - System.out.println("Null server address: " + server.getLocalAddress()); + UnixDomainSocketAddress usa = null; + try { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.bind(null); + usa = (UnixDomainSocketAddress) server.getLocalAddress(); + if (usa.getPath().toString().isEmpty()) + throw new RuntimeException("expected non zero address length"); + System.out.println("Null server address: " + server.getLocalAddress()); + } finally { + if (usa != null) { + Files.deleteIfExists(usa.getPath()); + } + } }); // server no bind : not allowed checkException( @@ -307,23 +318,32 @@ public static void runTests() throws IOException { Arrays.fill(chars, 'x'); String name = new String(chars); UnixDomainSocketAddress address = UnixDomainSocketAddress.of(name); - ServerSocketChannel server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.bind(address); - SocketChannel client = SocketChannel.open(address); - assertAddress(server.getLocalAddress(), address, "server"); - assertAddress(client.getRemoteAddress(), address, "client"); - Files.delete(address.getPath()); + try { + ServerSocketChannel server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.bind(address); + SocketChannel client = SocketChannel.open(address); + assertAddress(server.getLocalAddress(), address, "server"); + assertAddress(client.getRemoteAddress(), address, "client"); + } finally { + Files.deleteIfExists(address.getPath()); + } }); // implicit server bind checkNormal(() -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.bind(null); - UnixDomainSocketAddress usa = (UnixDomainSocketAddress)server.getLocalAddress(); - client = SocketChannel.open(usa); - accept1 = server.accept(); - assertAddress(client.getRemoteAddress(), usa, "server"); - Files.delete(usa.getPath()); + UnixDomainSocketAddress usa = null; + try { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.bind(null); + usa = (UnixDomainSocketAddress) server.getLocalAddress(); + client = SocketChannel.open(usa); + accept1 = server.accept(); + assertAddress(client.getRemoteAddress(), usa, "server"); + } finally { + if (usa != null) { + Files.deleteIfExists(usa.getPath()); + } + } }); } } diff --git a/test/jdk/java/nio/channels/unixdomain/NonBlockingAccept.java b/test/jdk/java/nio/channels/unixdomain/NonBlockingAccept.java index 62b21a98d60..f5cea54dbb8 100644 --- a/test/jdk/java/nio/channels/unixdomain/NonBlockingAccept.java +++ b/test/jdk/java/nio/channels/unixdomain/NonBlockingAccept.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -29,8 +29,11 @@ */ import java.net.StandardProtocolFamily; +import java.net.UnixDomainSocketAddress; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.file.Files; + import jtreg.SkippedException; public class NonBlockingAccept { @@ -48,17 +51,23 @@ static void checkSupported() { public static void main(String[] args) throws Exception { checkSupported(); + UnixDomainSocketAddress addr = null; try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX)) { //non blocking mode serverSocketChannel.configureBlocking(false); serverSocketChannel.bind(null); + addr = (UnixDomainSocketAddress) serverSocketChannel.getLocalAddress(); SocketChannel socketChannel = serverSocketChannel.accept(); System.out.println("The socketChannel is : expected Null " + socketChannel); if (socketChannel != null) throw new RuntimeException("expected null"); // or exception could be thrown otherwise + } finally { + if (addr != null) { + Files.deleteIfExists(addr.getPath()); + } } } } diff --git a/test/jdk/java/util/zip/ZipFile/ZeroDate.java b/test/jdk/java/util/zip/ZipFile/ZeroDate.java index d0e7263fc19..441ef88cd2a 100644 --- a/test/jdk/java/util/zip/ZipFile/ZeroDate.java +++ b/test/jdk/java/util/zip/ZipFile/ZeroDate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -40,41 +40,47 @@ import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; +import jdk.test.lib.Utils; + /* @test * @bug 8184940 8188869 * @summary JDK 9 rejects zip files where the modified day or month is 0 * or otherwise represent an invalid date, such as 1980-02-30 24:60:60 * @author Liam Miller-Cushon + * @library /test/lib */ public class ZeroDate { public static void main(String[] args) throws Exception { // create a zip file, and read it in as a byte array - Path path = Files.createTempFile("bad", ".zip"); - try (OutputStream os = Files.newOutputStream(path); - ZipOutputStream zos = new ZipOutputStream(os)) { - ZipEntry e = new ZipEntry("x"); - zos.putNextEntry(e); - zos.write((int) 'x'); - } - int len = (int) Files.size(path); - byte[] data = new byte[len]; - try (InputStream is = Files.newInputStream(path)) { - is.read(data); - } - Files.delete(path); + Path path = Utils.createTempFile("bad", ".zip"); + try { + try (OutputStream os = Files.newOutputStream(path); + ZipOutputStream zos = new ZipOutputStream(os)) { + ZipEntry e = new ZipEntry("x"); + zos.putNextEntry(e); + zos.write((int) 'x'); + } + int len = (int) Files.size(path); + byte[] data = new byte[len]; + try (InputStream is = Files.newInputStream(path)) { + is.read(data); + } - // year, month, day are zero - testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay()); - // only year is zero - testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay()); - // month is greater than 12 - testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay()); - // 30th of February - testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay()); - // 30th of February, 24:60:60 - testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1, - LocalDateTime.of(1980, 3, 2, 1, 1, 0)); + // year, month, day are zero + testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay()); + // only year is zero + testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay()); + // month is greater than 12 + testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay()); + // 30th of February + testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay()); + // 30th of February, 24:60:60 + testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1, + LocalDateTime.of(1980, 3, 2, 1, 1, 0)); + } finally { + Files.delete(path); + } } private static void testDate(byte[] data, int date, LocalDateTime expected) throws IOException { @@ -86,7 +92,7 @@ private static void testDate(byte[] data, int date, LocalDateTime expected) thro writeU32(data, locpos + LOCTIM, date); // ensure that the archive is still readable, and the date is 1979-11-30 - Path path = Files.createTempFile("out", ".zip"); + Path path = Utils.createTempFile("out", ".zip"); try (OutputStream os = Files.newOutputStream(path)) { os.write(data); } diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java index 8ddc5357b37..94383298ddc 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -23,7 +23,6 @@ package jdk.jfr.api.consumer.filestream; -import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; @@ -35,6 +34,7 @@ import jdk.jfr.Event; import jdk.jfr.Recording; import jdk.jfr.consumer.EventStream; +import jdk.test.lib.Utils; /** * @test @@ -148,7 +148,7 @@ private static Path makeUnorderedRecording() throws Exception { e.join(); } r.stop(); - Path p = Files.createTempFile("recording", ".jfr"); + Path p = Utils.createTempFile("recording", ".jfr"); r.dump(p); return p; } diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java index 3dbe26eea16..ff26fd7269d 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -34,6 +34,7 @@ import jdk.jfr.Recording; import jdk.jfr.consumer.EventStream; import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Utils; /** * @test @@ -118,7 +119,7 @@ private static Path makeRecording() throws IOException { } r.stop(); rotation.close(); - Path p = Files.createTempFile("recording", ".jfr"); + Path p = Utils.createTempFile("recording", ".jfr"); r.dump(p); return p; } diff --git a/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java b/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java index 1a2ea5238c9..f0c3b52cf14 100644 --- a/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java +++ b/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -35,6 +35,7 @@ import jdk.jfr.consumer.RecordedThread; import jdk.jfr.consumer.RecordingFile; import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; /** * @test @@ -78,7 +79,7 @@ public static void main(String... args) throws Exception { } r.stop(); - Path p = Files.createTempFile("test", ".jfr"); + Path p = Utils.createTempFile("test", ".jfr"); r.dump(p); long size = Files.size(p); Asserts.assertLessThan(size, 100_000_000L, "Size of recording looks suspiciously large"); diff --git a/test/jdk/jdk/nio/zipfs/ZeroDate.java b/test/jdk/jdk/nio/zipfs/ZeroDate.java index 4f40f192f43..ff702f63488 100644 --- a/test/jdk/jdk/nio/zipfs/ZeroDate.java +++ b/test/jdk/jdk/nio/zipfs/ZeroDate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -44,42 +44,48 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import jdk.test.lib.Utils; + /* @test * @bug 8184940 8186227 8188869 * @summary JDK 9 rejects zip files where the modified day or month is 0 * or otherwise represent an invalid date, such as 1980-02-30 24:60:60 * @author Liam Miller-Cushon * @modules jdk.zipfs + * @library /test/lib */ public class ZeroDate { public static void main(String[] args) throws Exception { // create a zip file, and read it in as a byte array - Path path = Files.createTempFile("bad", ".zip"); - try (OutputStream os = Files.newOutputStream(path); - ZipOutputStream zos = new ZipOutputStream(os)) { - ZipEntry e = new ZipEntry("x"); - zos.putNextEntry(e); - zos.write((int) 'x'); - } - int len = (int) Files.size(path); - byte[] data = new byte[len]; - try (InputStream is = Files.newInputStream(path)) { - is.read(data); - } - Files.delete(path); + Path path = Utils.createTempFile("bad", ".zip"); + try { + try (OutputStream os = Files.newOutputStream(path); + ZipOutputStream zos = new ZipOutputStream(os)) { + ZipEntry e = new ZipEntry("x"); + zos.putNextEntry(e); + zos.write((int) 'x'); + } + int len = (int) Files.size(path); + byte[] data = new byte[len]; + try (InputStream is = Files.newInputStream(path)) { + is.read(data); + } - // year, month, day are zero - testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay()); - // only year is zero - testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay()); - // month is greater than 12 - testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay()); - // 30th of February - testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay()); - // 30th of February, 24:60:60 - testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1, - LocalDateTime.of(1980, 3, 2, 1, 1, 0)); + // year, month, day are zero + testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay()); + // only year is zero + testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay()); + // month is greater than 12 + testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay()); + // 30th of February + testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay()); + // 30th of February, 24:60:60 + testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1, + LocalDateTime.of(1980, 3, 2, 1, 1, 0)); + } finally { + Files.delete(path); + } } private static void testDate(byte[] data, int date, LocalDateTime expected) throws IOException { @@ -91,7 +97,7 @@ private static void testDate(byte[] data, int date, LocalDateTime expected) thro writeU32(data, locpos + LOCTIM, date); // ensure that the archive is still readable, and the date is 1979-11-30 - Path path = Files.createTempFile("out", ".zip"); + Path path = Utils.createTempFile("out", ".zip"); try (OutputStream os = Files.newOutputStream(path)) { os.write(data); } diff --git a/test/jdk/sun/security/pkcs12/P12SecretKey.java b/test/jdk/sun/security/pkcs12/P12SecretKey.java index 34c90d638c8..ed599a55962 100644 --- a/test/jdk/sun/security/pkcs12/P12SecretKey.java +++ b/test/jdk/sun/security/pkcs12/P12SecretKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -33,6 +33,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.nio.file.Files; import java.security.KeyStore; import java.security.cert.CertificateException; import java.util.Arrays; @@ -66,24 +67,29 @@ private void run(String keystoreType, String algName, int keySize) throws Except ks.setEntry(ALIAS, ske, kspp); File ksFile = File.createTempFile("test", ".test"); - try (FileOutputStream fos = new FileOutputStream(ksFile)) { - ks.store(fos, pw); - fos.flush(); - } - // now see if we can get it back - try (FileInputStream fis = new FileInputStream(ksFile)) { - KeyStore ks2 = KeyStore.getInstance(keystoreType); - ks2.load(fis, pw); - KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp); - SecretKey keyIn = ((KeyStore.SecretKeyEntry)entry).getSecretKey(); - if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) { - System.err.println("OK: worked just fine with " + keystoreType + - " keystore"); - } else { - System.err.println("ERROR: keys are NOT equal after storing in " - + keystoreType + " keystore"); + try { + try (FileOutputStream fos = new FileOutputStream(ksFile)) { + ks.store(fos, pw); + fos.flush(); + } + + // now see if we can get it back + try (FileInputStream fis = new FileInputStream(ksFile)) { + KeyStore ks2 = KeyStore.getInstance(keystoreType); + ks2.load(fis, pw); + KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp); + SecretKey keyIn = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); + if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) { + System.err.println("OK: worked just fine with " + keystoreType + + " keystore"); + } else { + System.err.println("ERROR: keys are NOT equal after storing in " + + keystoreType + " keystore"); + } } + } finally { + Files.deleteIfExists(ksFile.toPath()); } } } From a6931db9eee44a7b0468504e4c4ada81bcbbbdc0 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:13:37 +0000 Subject: [PATCH 206/298] 8315071: Modify TrayIconScalingTest.java, PrintLatinCJKTest.java to use new PassFailJFrame's builder pattern usage Backport-of: 31e26814db5d5ad5018fb6ed2e8160e8a01938ab --- test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java | 13 ++++++++++--- .../awt/print/PrinterJob/PrintLatinCJKTest.java | 11 ++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java index e5c082ac6d2..ec878c10c20 100644 --- a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java +++ b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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,8 +85,15 @@ public static void main(String[] args) System.out.println("SystemTray is not supported"); return; } - PassFailJFrame passFailJFrame = new PassFailJFrame("TrayIcon " + - "Test Instructions", INSTRUCTIONS, 8, 25, 85); + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("TrayIcon Test Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(8) + .rows(25) + .columns(70) + .screenCapture() + .build(); + createAndShowGUI(); // does not have a test window, // hence only the instruction frame is positioned diff --git a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java index 785855749a8..f6221aa5706 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -98,8 +98,13 @@ public int print(Graphics g, PageFormat pf, int pageIndex) } public static void main(String[] args) throws InterruptedException, InvocationTargetException { - PassFailJFrame passFailJFrame = new PassFailJFrame("Test Instruction" + - "Frame", info, 10, 10, 45); + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("Test Instructions Frame") + .instructions(info) + .testTimeOut(10) + .rows(10) + .columns(45) + .build(); showFrame(); passFailJFrame.awaitAndCheck(); } From 1f43e2f864b2d9751f60eddbac4a12c3fef7ab9a Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:14:16 +0000 Subject: [PATCH 207/298] 8326006: Allow TEST_VM_FLAGLESS to set flagless mode Backport-of: d10f277bd39bb5ac9bd48939c916de607fef8ace --- test/jtreg-ext/requires/VMProps.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 16b078410f0..b4b79fab23a 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -621,14 +621,15 @@ private String jdkContainerized() { * Checks if we are in almost out-of-box configuration, i.e. the flags * which JVM is started with don't affect its behavior "significantly". * {@code TEST_VM_FLAGLESS} enviroment variable can be used to force this - * method to return true and allow any flags. + * method to return true or false and allow or reject any flags. * * @return true if there are no JVM flags */ private String isFlagless() { boolean result = true; - if (System.getenv("TEST_VM_FLAGLESS") != null) { - return "" + result; + String flagless = System.getenv("TEST_VM_FLAGLESS"); + if (flagless != null) { + return "" + "true".equalsIgnoreCase(flagless); } List allFlags = allFlags().toList(); From 8e438ab8c7e1781c06c389565321d8b8f412cacf Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:14:53 +0000 Subject: [PATCH 208/298] 8315824: Open source several Swing Text/HTML related tests Backport-of: c11f8352e96a01b39e54080716030ec96f717cae --- .../text/StyledEditorKit/bug4253334.java | 87 +++++++++++++++ .../text/StyledEditorKit/bug4329418.java | 101 ++++++++++++++++++ test/jdk/javax/swing/text/bug4739057.java | 53 +++++++++ test/jdk/javax/swing/text/bug4763466.java | 51 +++++++++ .../jdk/javax/swing/text/html/bug4210307.java | 96 +++++++++++++++++ .../jdk/javax/swing/text/html/bug4839739.java | 97 +++++++++++++++++ 6 files changed, 485 insertions(+) create mode 100644 test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java create mode 100644 test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java create mode 100644 test/jdk/javax/swing/text/bug4739057.java create mode 100644 test/jdk/javax/swing/text/bug4763466.java create mode 100644 test/jdk/javax/swing/text/html/bug4210307.java create mode 100644 test/jdk/javax/swing/text/html/bug4839739.java diff --git a/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java b/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java new file mode 100644 index 00000000000..625b47055c0 --- /dev/null +++ b/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.Action; +import javax.swing.JEditorPane; +import javax.swing.text.AttributeSet; +import javax.swing.text.Caret; +import javax.swing.text.Element; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.event.ActionEvent; +import java.io.StringReader; + +/* + * @test + * @bug 4253334 + * @summary Tests that bold attribute unsets properly + */ + +public class bug4253334 { + + public static void main(String[] args) throws Exception { + JEditorPane ep = new JEditorPane(); + ep.setEditable(true); + ep.setContentType("text/html"); + + HTMLEditorKit kit = (HTMLEditorKit)ep.getEditorKit(); + HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument(); + ep.setDocument(doc); + String text = "somesampletext"; + kit.read(new StringReader(text), doc, 0); + + // make some text bold & italic + MutableAttributeSet attrs = new SimpleAttributeSet(); + StyleConstants.setBold(attrs, true); + StyleConstants.setItalic(attrs, true); + doc.setCharacterAttributes(3, 9, attrs, false); + + Action[] as = kit.getActions(); + Action boldAction = null; + + for (Action a : as) { + String s = (String) (a.getValue(Action.NAME)); + if (s.equals("font-bold")) { + boldAction = a; + } + } + Caret caret = ep.getCaret(); + ActionEvent event = new ActionEvent(ep, ActionEvent.ACTION_PERFORMED, + "font-bold"); + caret.setDot(3); + caret.moveDot(7); + boldAction.actionPerformed(event); + caret.setDot(7); + caret.moveDot(12); + boldAction.actionPerformed(event); + + Element elem = doc.getCharacterElement(9); + AttributeSet at = elem.getAttributes(); + if (StyleConstants.isBold(at)) { + throw new RuntimeException("Test Failed: bold attribute set"); + } + } +} diff --git a/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java b/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java new file mode 100644 index 00000000000..e06c9d36aa7 --- /dev/null +++ b/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000, 2023, 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.Robot; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.Document; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledEditorKit; + +/* + * @test + * @bug 4329418 + * @key headful + * @summary Tests if setCharacterAttributes() is maintained + * after return in J(Editor/Text)Pane + */ + +public class bug4329418 { + private static JFrame jf; + private static StyledEditorKit sek; + + private static volatile boolean passed = false; + private static final int FONT_SIZE = 36; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + + SwingUtilities.invokeAndWait(bug4329418::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.delay(300); + + if (!passed) { + throw new RuntimeException("Test failed." + + " setCharacterAttributes() does not work correctly"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jf != null) { + jf.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + jf = new JFrame("setCharacterAttributes Test"); + sek = new StyledEditorKit(); + JEditorPane jep = new JEditorPane(); + jep.setEditorKit(sek); + + MutableAttributeSet attrs = sek.getInputAttributes(); + StyleConstants.setFontSize(attrs, FONT_SIZE); + + jep.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent e) { + MutableAttributeSet attrs = sek.getInputAttributes(); + passed = (StyleConstants.getFontSize(attrs) == FONT_SIZE); + } + }); + + jep.setText("aaa"); + Document doc = jep.getDocument(); + jep.setCaretPosition(doc.getLength()); + + jf.getContentPane().add(jep); + jf.setLocationRelativeTo(null); + jf.setSize(200, 200); + jf.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/text/bug4739057.java b/test/jdk/javax/swing/text/bug4739057.java new file mode 100644 index 00000000000..904ea8de18f --- /dev/null +++ b/test/jdk/javax/swing/text/bug4739057.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.SwingUtilities; +import javax.swing.text.MaskFormatter; +import java.text.ParseException; + +/* + * @test + * @bug 4739057 + * @summary replaceSelection() method fails on JFormattedTextField + */ + +public class bug4739057 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + MaskFormatter formatter; + try { + formatter = new MaskFormatter("(###) ###-####"); + } catch (ParseException e) { + throw new RuntimeException(e); + } + formatter.setPlaceholderCharacter('#'); + JFormattedTextField textField = new JFormattedTextField(formatter); + textField.replaceSelection("12345"); + if (!textField.getText().equals("(123) 45#-####")) { + throw new RuntimeException("Test Failed! replaceSelection() didn't replace text properly"); + } + }); + } +} diff --git a/test/jdk/javax/swing/text/bug4763466.java b/test/jdk/javax/swing/text/bug4763466.java new file mode 100644 index 00000000000..db2a914cb8b --- /dev/null +++ b/test/jdk/javax/swing/text/bug4763466.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.text.NumberFormatter; +import java.text.DecimalFormat; + +/* + * @test + * @bug 4763466 + * @summary JFormattedTextField and the - sign + */ + +public class bug4763466 { + + public static void main(String[] args) throws Exception { + DecimalFormat decimalFormat = new DecimalFormat("##0.00"); + NumberFormatter textFormatter = new NumberFormatter(decimalFormat); + textFormatter.setAllowsInvalid(false); + textFormatter.setValueClass(Double.class); + + JFormattedTextField ftf = new JFormattedTextField(textFormatter); + ftf.setCaretPosition(0); + ftf.setValue((double) -1); + + if (ftf.getCaretPosition() == 0) { + throw new RuntimeException("Test Failed. Caret position shouldn't be 0" + + " as the sign is literal"); + } + } +} diff --git a/test/jdk/javax/swing/text/html/bug4210307.java b/test/jdk/javax/swing/text/html/bug4210307.java new file mode 100644 index 00000000000..6af4e62f805 --- /dev/null +++ b/test/jdk/javax/swing/text/html/bug4210307.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.JButton; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.html.FormView; + +/* + * @test + * @bug 4210307 4210308 + * @summary Tests that FormView button text is internationalized + */ + +public class bug4210307 { + private static final String RESET_PROPERTY = "TEST RESET"; + private static final String SUBMIT_PROPERTY = "TEST SUBMIT"; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + Object oldReset = UIManager.put("FormView.resetButtonText", + RESET_PROPERTY); + Object oldSubmit = UIManager.put("FormView.submitButtonText", + SUBMIT_PROPERTY); + + try { + JEditorPane ep = new JEditorPane("text/html", + ""); + Document doc = ep.getDocument(); + Element elem = findInputElement(doc.getDefaultRootElement()); + TestView view = new TestView(elem); + view.test(SUBMIT_PROPERTY); + + ep = new JEditorPane("text/html", + ""); + doc = ep.getDocument(); + elem = findInputElement(doc.getDefaultRootElement()); + view = new TestView(elem); + view.test(RESET_PROPERTY); + } finally { + UIManager.put("FormView.resetButtonText", oldReset); + UIManager.put("FormView.submitButtonText", oldSubmit); + } + }); + } + + private static Element findInputElement(Element root) { + for (int i = 0; i < root.getElementCount(); i++) { + Element elem = root.getElement(i); + if (elem.getName().equals("input")) { + return elem; + } else { + Element e = findInputElement(elem); + if (e != null) return e; + } + } + return null; + } + + static class TestView extends FormView { + public TestView(Element elem) { + super(elem); + } + + public void test(String caption) { + JButton comp = (JButton) createComponent(); + if (!comp.getText().equals(caption)) { + throw new RuntimeException("Failed: '" + comp.getText() + + "' instead of `" + caption + "'"); + } + } + } +} diff --git a/test/jdk/javax/swing/text/html/bug4839739.java b/test/jdk/javax/swing/text/html/bug4839739.java new file mode 100644 index 00000000000..1dc5fbef123 --- /dev/null +++ b/test/jdk/javax/swing/text/html/bug4839739.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +/* + * @test + * @bug 4839739 + * @key headful + * @summary Tests if JEditorPane works correctly with HTML comments. + */ + +public class bug4839739 { + + private static JFrame jFrame; + private static JEditorPane jep; + private static volatile Point p; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(50); + + SwingUtilities.invokeAndWait(bug4839739::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> p = jep.getLocationOnScreen()); + robot.delay(200); + + robot.mouseMove(p.x + 20, p.y + 20); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.delay(300); + + Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (!(comp instanceof JEditorPane)) { + throw new RuntimeException("Test failed." + + " JEditorPane doesn't work as expected with HTML comments"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jFrame != null) { + jFrame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + String text = "" + + "some always visible text"; + + jFrame = new JFrame("JEditorPane With HTML"); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + jFrame.getContentPane().add(jep); + jFrame.setSize(200,200); + jFrame.setLocationRelativeTo(null); + jFrame.setVisible(true); + } +} From b56b6f53ae7a25661251b20d32d8eff3f47bf267 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:15:34 +0000 Subject: [PATCH 209/298] 8327136: javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java fails on libgraal Backport-of: 8f0fb27decec28f32e4d88341237189ba4a340fb --- .../remote/mandatory/notif/NotifReconnectDeadlockTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java index 3f16ed00369..72ae5766307 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java @@ -176,7 +176,7 @@ public void handleNotification(Notification n, Object hb) { // serverTimeout increased to avoid occasional problems with initial connect. // Not using Utils.adjustTimeout to avoid accidentally making it too long. - private static final long serverTimeout = 2000; + private static final long serverTimeout = 3000; private static final long listenerSleep = serverTimeout*6; private volatile static String clientState = null; From 5880551e785b24728de1e719738d4719ea54c509 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:16:59 +0000 Subject: [PATCH 210/298] 8318854: [macos14] Running any AWT app prints Secure coding warning Backport-of: 940f67c1a62c6f9462266f3a108649aca114cffa --- .../native/libawt_lwawt/awt/AWTWindow.m | 4 +- .../libawt_lwawt/awt/ApplicationDelegate.m | 61 +++++++++++++------ .../macosx/native/libawt_lwawt/awt/CMenuBar.m | 8 ++- .../libosxapp/QueuingApplicationDelegate.m | 15 +++++ 4 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m index 73009468fa4..33b986a0d18 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m @@ -841,7 +841,7 @@ - (void) activateWindowMenuBar { isDisabled = !awtWindow.isEnabled; } - if (menuBar == nil) { + if (menuBar == nil && [ApplicationDelegate sharedDelegate] != nil) { menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; isDisabled = NO; } @@ -1230,7 +1230,7 @@ + (AWTWindow *) lastKeyWindow { window.javaMenuBar = menuBar; CMenuBar* actualMenuBar = menuBar; - if (actualMenuBar == nil) { + if (actualMenuBar == nil && [ApplicationDelegate sharedDelegate] != nil) { actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m index 590ed56e0c6..a8a821423de 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m @@ -116,8 +116,9 @@ + (ApplicationDelegate *)sharedDelegate { // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari BOOL shouldInstall = NO; + BOOL overrideDelegate = (getenv("AWT_OVERRIDE_NSDELEGATE") != NULL); if (NSApp != nil) { - if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES; + if ([NSApp isMemberOfClass:[NSApplication class]] && overrideDelegate) shouldInstall = YES; if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES; } checked = YES; @@ -409,6 +410,19 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app { return NSTerminateLater; } +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app { + static BOOL checked = NO; + static BOOL supportsSecureState = YES; + + if (checked == NO) { + checked = YES; + if (getenv("AWT_DISABLE_NSDELEGATE_SECURE_SAVE") != NULL) { + supportsSecureState = NO; + } + } + return supportsSecureState; +} + + (void)_systemWillPowerOff { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SHUTDOWN]; } @@ -506,8 +520,10 @@ + (void)_setDockIconImage:(NSImage *)image { [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown]; [dockImageView setImage:image]; - [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview]; - [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator]; + if ([ApplicationDelegate sharedDelegate] != nil) { + [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview]; + [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator]; + } // add it to the NSDockTile [dockTile setContentView: dockImageView]; @@ -520,14 +536,15 @@ + (void)_setDockIconProgress:(NSNumber *)value { AWT_ASSERT_APPKIT_THREAD; ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate]; - if ([value doubleValue] >= 0 && [value doubleValue] <=100) { - [delegate.fProgressIndicator setDoubleValue:[value doubleValue]]; - [delegate.fProgressIndicator setHidden:NO]; - } else { - [delegate.fProgressIndicator setHidden:YES]; + if (delegate != nil) { + if ([value doubleValue] >= 0 && [value doubleValue] <=100) { + [delegate.fProgressIndicator setDoubleValue:[value doubleValue]]; + [delegate.fProgressIndicator setHidden:NO]; + } else { + [delegate.fProgressIndicator setHidden:YES]; + } + [[NSApp dockTile] display]; } - - [[NSApp dockTile] display]; } // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon @@ -638,7 +655,9 @@ + (NSImage *)_dockIconImage { NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - [ApplicationDelegate sharedDelegate].fDockMenu = menu; + if ([ApplicationDelegate sharedDelegate] != nil) { + [ApplicationDelegate sharedDelegate].fDockMenu = menu; + } }]; JNI_COCOA_EXIT(env); @@ -818,13 +837,15 @@ + (NSImage *)_dockIconImage { [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate]; - switch (menuID) { - case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT: - [delegate _updateAboutMenu:visible enabled:enabled]; - break; - case com_apple_eawt__AppMenuBarHandler_MENU_PREFS: - [delegate _updatePreferencesMenu:visible enabled:enabled]; - break; + if (delegate != nil) { + switch (menuID) { + case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT: + [delegate _updateAboutMenu:visible enabled:enabled]; + break; + case com_apple_eawt__AppMenuBarHandler_MENU_PREFS: + [delegate _updatePreferencesMenu:visible enabled:enabled]; + break; + } } }]; @@ -843,7 +864,9 @@ + (NSImage *)_dockIconImage { CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ - [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu; + if ([ApplicationDelegate sharedDelegate] != nil) { + [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu; + } }]; JNI_COCOA_EXIT(env); diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m index 49a6a80da21..b02cc818063 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m @@ -210,9 +210,11 @@ -(void) deactivate { // In theory, this might cause flickering if the window gaining focus // has its own menu. However, I couldn't reproduce it on practice, so // perhaps this is a non issue. - CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; - if (defaultMenu != nil) { - [CMenuBar activate:defaultMenu modallyDisabled:NO]; + if ([ApplicationDelegate sharedDelegate] != nil) { + CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar]; + if (defaultMenu != nil) { + [CMenuBar activate:defaultMenu modallyDisabled:NO]; + } } } } diff --git a/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m b/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m index 034a990ebc8..ced48c72a36 100644 --- a/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m +++ b/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m @@ -200,6 +200,21 @@ - (void)_appDidUnhide } copy]]; } + +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app +{ + static BOOL checked = NO; + static BOOL supportsSecureState = YES; + + if (checked == NO) { + checked = YES; + if (getenv("AWT_DISABLE_NSDELEGATE_SECURE_SAVE") != NULL) { + supportsSecureState = NO; + } + } + return supportsSecureState; +} + - (void)processQueuedEventsWithTargetDelegate:(id )delegate { self.realDelegate = delegate; From d11a0654057c172adfbce53a3927df578b746fc7 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Tue, 23 Apr 2024 07:17:34 +0000 Subject: [PATCH 211/298] 8187759: Background not refreshed when painting over a transparent JFrame Backport-of: 04d43c435d3ede519df169053dd9d724aa2312eb --- .../swing/BufferStrategyPaintManager.java | 9 + .../JFrame/JFrameBackgroundRefreshTest.java | 210 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java diff --git a/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java b/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java index a21745e9b76..598c90ff8c7 100644 --- a/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java +++ b/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java @@ -243,6 +243,15 @@ public boolean paint(JComponent paintingComponent, ((SunGraphics2D)bsg).constrain(xOffset + cx, yOffset + cy, x + w, y + h); bsg.setClip(x, y, w, h); + + if (!bufferComponent.isOpaque()) { + final SunGraphics2D g2d = (SunGraphics2D) bsg; + final Color oldBg = g2d.getBackground(); + g2d.setBackground(paintingComponent.getBackground()); + g2d.clearRect(x, y, w, h); + g2d.setBackground(oldBg); + } + paintingComponent.paintToOffscreen(bsg, x, y, w, h, x + w, y + h); accumulate(xOffset + x, yOffset + y, w, h); diff --git a/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java b/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java new file mode 100644 index 00000000000..cb2e0051216 --- /dev/null +++ b/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023, 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.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + * @test + * @key headful + * @bug 8187759 + * @summary Test to check if JFrame background is refreshed in Linux. + * @requires (os.family == "linux") + * @run main JFrameBackgroundRefreshTest + */ + +public class JFrameBackgroundRefreshTest { + public static JFrame frame; + private static final BufferedImage test = generateImage(); + private static Point p = new Point(); + private static Robot robot; + private static JFrame whiteFrame; + private static Point frameLocation; + private static int frameCenterX, frameCenterY, awayX, awayY; + private static int imageCenterX, imageCenterY; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + try { + JFrameBackgroundRefreshTest.initialize(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + SwingUtilities.invokeAndWait(() -> { + frameLocation = whiteFrame.getLocationOnScreen(); + frameCenterX = frameLocation.x + whiteFrame.getWidth() / 2; + frameCenterY = frameLocation.y + whiteFrame.getHeight() / 2; + awayX = frameLocation.x + whiteFrame.getWidth() + 100; + awayY = frameLocation.y + whiteFrame.getHeight() / 2; + imageCenterX = p.x + test.getWidth() / 2; + imageCenterY = p.y + test.getHeight() / 2; + }); + robot.delay(100); + robot.waitForIdle(); + robot.mouseMove(imageCenterX, imageCenterY); + robot.delay(100); + robot.waitForIdle(); + moveMouseSlowly(frameCenterX, frameCenterY); + robot.delay(1000); + robot.waitForIdle(); + + moveMouseSlowly(awayX, awayY); + robot.delay(100); + robot.waitForIdle(); + Rectangle screenCaptureRect = new Rectangle(frameCenterX - 50, + frameCenterY - 50, 100, 100); + BufferedImage bufferedImage = robot.createScreenCapture(screenCaptureRect); + + if (!compareImages(bufferedImage)) { + try { + ImageIO.write(bufferedImage, "png", + new File("FailureImage.png")); + } catch (IOException e) { + e.printStackTrace(); + } + throw new RuntimeException("Test Failed!"); + } + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (whiteFrame != null) { + whiteFrame.dispose(); + } + }); + } + } + + private static void moveMouseSlowly( int targetX, int targetY) { + Point currentMousePos = MouseInfo.getPointerInfo().getLocation(); + int currentX = currentMousePos.x; + int currentY = currentMousePos.y; + int deltaX = targetX - currentX; + int deltaY = targetY - currentY; + int steps = 50; + double stepX = (double) deltaX / steps; + double stepY = (double) deltaY / steps; + for (int i = 1; i <= steps; i++) { + int nextX = currentX + (int) Math.round(i * stepX); + int nextY = currentY + (int) Math.round(i * stepY); + robot.mouseMove(nextX, nextY); + robot.delay(10); + } + robot.mouseMove(targetX, targetY); + } + + private static boolean compareImages(BufferedImage bufferedImage) { + int sampleRGB = bufferedImage.getRGB(0,0); + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + if (bufferedImage.getRGB(x, y) != sampleRGB) { + return false; + } + } + } + return true; + } + + public static void initialize() throws Exception { + frame = new JFrame("JFrame Background refresh test"); + whiteFrame = new JFrame("White Frame"); + robot = new Robot(); + whiteFrame.setSize(200, 200); + whiteFrame.setBackground(Color.WHITE); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setUndecorated(true); + frame.setExtendedState(JFrame.MAXIMIZED_BOTH); + frame.setBackground(new Color(0, 0, 0, 0)); + frame.setContentPane(new TranslucentPane()); + frame.addMouseMotionListener(new MouseDragListener()); + whiteFrame.setLocationRelativeTo(null); + whiteFrame.setVisible(true); + frame.setVisible(true); + frame.setAlwaysOnTop(true); + } + private static class MouseDragListener extends MouseAdapter { + @Override + public void mouseMoved(MouseEvent e) { + p = e.getPoint(); + frame.repaint(); + } + } + + /** Capture an image of any component **/ + private static BufferedImage getImage(Component c) { + if (c == null) { + return null; + } + BufferedImage image = new BufferedImage(c.getWidth(), + c.getHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + c.printAll(g); + g.dispose(); + return image; + } + + /** Generates a dummy image to be painted on the frame **/ + private static BufferedImage generateImage() { + JLabel label = new JLabel("test"); + label.setFont(new Font("Arial", Font.BOLD, 24)); + label.setSize(label.getPreferredSize()); + return getImage(label); + } + + public static class TranslucentPane extends JPanel { + public TranslucentPane() { + setOpaque(false); + } + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g.create(); + g2d.setColor(new Color(0,0,0,0)); + g2d.fillRect(0, 0, getWidth(), getHeight()); + g2d.drawImage(test, p.x, p.y, this); + g2d.dispose(); + } + } +} From ffdde9c2fec4f0f79ebb20b186bf5ad1bd232d49 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 23 Apr 2024 07:32:07 +0000 Subject: [PATCH 212/298] 8320331: G1 Full GC Heap verification relies on metadata not reset before verification Backport-of: 1629a9059bd2e0f07559a384be4276c7dc13eff2 --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 2 +- src/hotspot/share/gc/g1/g1FullCollector.cpp | 1 + src/hotspot/share/gc/g1/heapRegion.hpp | 17 ++++++++++++----- src/hotspot/share/gc/g1/heapRegion.inline.hpp | 9 ++++++++- .../runtime/Metaspace/FragmentMetaspace.java | 12 +++++++++++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 03eafb1a323..1f95f2a9ea9 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -2761,7 +2761,7 @@ bool G1CollectedHeap::check_young_list_empty() { // Remove the given HeapRegion from the appropriate region set. void G1CollectedHeap::prepare_region_for_full_compaction(HeapRegion* hr) { - if (hr->is_humongous()) { + if (hr->is_humongous()) { _humongous_set.remove(hr); } else if (hr->is_old()) { _old_set.remove(hr); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 039f13019ab..62e7cdfabd4 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -171,6 +171,7 @@ class PrepareRegionsClosure : public HeapRegionClosure { PrepareRegionsClosure(G1FullCollector* collector) : _collector(collector) { } bool do_heap_region(HeapRegion* hr) { + hr->prepare_for_full_gc(); G1CollectedHeap::heap()->prepare_region_for_full_compaction(hr); _collector->before_marking_update_attribute_table(hr); return false; diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index ce49e62c939..195b7e9d911 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -174,6 +174,7 @@ class HeapRegion : public CHeapObj { void update_bot_for_block(HeapWord* start, HeapWord* end); + void prepare_for_full_gc(); // Update heap region that has been compacted to be consistent after Full GC. void reset_compacted_after_full_gc(HeapWord* new_top); // Update skip-compacting heap region to be consistent after Full GC. @@ -233,11 +234,17 @@ class HeapRegion : public CHeapObj { HeapWord* volatile _top_at_mark_start; // The area above this limit is fully parsable. This limit - // is equal to bottom except from Remark and until the region has been - // scrubbed concurrently. The scrubbing ensures that all dead objects (with - // possibly unloaded classes) have beenreplaced with filler objects that - // are parsable. Below this limit the marking bitmap must be used to - // determine size and liveness. + // is equal to bottom except + // + // * from Remark and until the region has been scrubbed concurrently. The + // scrubbing ensures that all dead objects (with possibly unloaded classes) + // have been replaced with filler objects that are parsable. + // * after the marking phase in the Full GC pause until the objects have been + // moved. Some (debug) code iterates over the heap after marking but before + // compaction. + // + // Below this limit the marking bitmap must be used to determine size and + // liveness. HeapWord* volatile _parsable_bottom; // Amount of dead data in the region. diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index 5109c6a1e58..f28ff13c460 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -180,6 +180,13 @@ inline size_t HeapRegion::block_size(const HeapWord* p, HeapWord* const pb) cons return cast_to_oop(p)->size(); } +inline void HeapRegion::prepare_for_full_gc() { + // After marking and class unloading the heap temporarily contains dead objects + // with unloaded klasses. Moving parsable_bottom makes some (debug) code correctly + // skip dead objects. + _parsable_bottom = top(); +} + inline void HeapRegion::reset_compacted_after_full_gc(HeapWord* new_top) { set_top(new_top); // After a compaction the mark bitmap in a movable region is invalid. @@ -201,7 +208,7 @@ inline void HeapRegion::reset_skip_compacting_after_full_gc() { inline void HeapRegion::reset_after_full_gc_common() { // Everything above bottom() is parsable and live. - _parsable_bottom = bottom(); + reset_parsable_bottom(); // Clear unused heap memory in debug builds. if (ZapUnusedHeapArea) { diff --git a/test/hotspot/jtreg/runtime/Metaspace/FragmentMetaspace.java b/test/hotspot/jtreg/runtime/Metaspace/FragmentMetaspace.java index 61cebb528b4..8dcc83a1122 100644 --- a/test/hotspot/jtreg/runtime/Metaspace/FragmentMetaspace.java +++ b/test/hotspot/jtreg/runtime/Metaspace/FragmentMetaspace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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,16 @@ * @run main/othervm/timeout=200 -Xmx1g FragmentMetaspace */ +/** + * @test id=8320331 + * @bug 8320331 + * @requires vm.debug + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @modules java.compiler + * @run main/othervm/timeout=200 -XX:+UnlockDiagnosticVMOptions -XX:+VerifyDuringGC -Xmx1g FragmentMetaspace + */ + import java.io.IOException; import jdk.test.lib.classloader.GeneratingCompilingClassLoader; From bb046b70fb2d49d6e95e82676a688e6a4b6353b0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 23 Apr 2024 07:34:12 +0000 Subject: [PATCH 213/298] 8320525: G1: G1UpdateRemSetTrackingBeforeRebuild::distribute_marked_bytes accesses partially unloaded klass Backport-of: 21d361e944a599e82e5ed93aa81ad485b4601843 --- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 8930f97af6a..b040c1f4656 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1121,13 +1121,10 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public WorkerTask { // Distribute the given marked bytes across the humongous object starting // with hr and note end of marking for these regions. void distribute_marked_bytes(HeapRegion* hr, size_t marked_bytes) { - size_t const obj_size_in_words = cast_to_oop(hr->bottom())->size(); - - // "Distributing" zero words means that we only note end of marking for these - // regions. - assert(marked_bytes == 0 || obj_size_in_words * HeapWordSize == marked_bytes, + // Dead humongous objects (marked_bytes == 0) may have already been unloaded. + assert(marked_bytes == 0 || cast_to_oop(hr->bottom())->size() * HeapWordSize == marked_bytes, "Marked bytes should either be 0 or the same as humongous object (%zu) but is %zu", - obj_size_in_words * HeapWordSize, marked_bytes); + cast_to_oop(hr->bottom())->size() * HeapWordSize, marked_bytes); auto distribute_bytes = [&] (HeapRegion* r) { size_t const bytes_to_add = MIN2(HeapRegion::GrainBytes, marked_bytes); @@ -1138,10 +1135,6 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public WorkerTask { marked_bytes -= bytes_to_add; }; _g1h->humongous_obj_regions_iterate(hr, distribute_bytes); - - assert(marked_bytes == 0, - "%zu bytes left after distributing space across %zu regions", - marked_bytes, G1CollectedHeap::humongous_obj_size_in_regions(obj_size_in_words)); } void update_marked_bytes(HeapRegion* hr) { From a36d3deaec6e643a87997442002ebd35b6cdd97b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 23 Apr 2024 07:36:01 +0000 Subject: [PATCH 214/298] 8328957: Update PKCS11Test.java to not use hardcoded path Backport-of: 16576b87b7267aaa99c41f77993287e3479577aa --- test/jdk/sun/security/pkcs11/PKCS11Test.java | 54 ++++++++++---------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java index 8ca47f718ef..b2609e61988 100644 --- a/test/jdk/sun/security/pkcs11/PKCS11Test.java +++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -54,9 +54,7 @@ import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; @@ -261,19 +259,13 @@ private static Path getNSSLibPath() throws Exception { static Path getNSSLibPath(String library) throws Exception { String osid = getOsId(); - String nssLibDir = fetchNssLib(osid); - if (nssLibDir == null) { + Path libraryName = Path.of(System.mapLibraryName(library)); + Path nssLibPath = fetchNssLib(osid, libraryName); + if (nssLibPath == null) { throw new SkippedException("Warning: unsupported OS: " + osid + ", please initialize NSS library location, skipping test"); } - - String libraryName = System.mapLibraryName(library); - Path libPath = Paths.get(nssLibDir).resolve(libraryName); - if (!Files.exists(libPath)) { - throw new SkippedException("NSS library \"" + libraryName + "\" was not found in " + nssLibDir); - } - - return libPath; + return nssLibPath; } private static String getOsId() { @@ -735,42 +727,42 @@ static byte[] generateData(int length) { return data; } - private static String fetchNssLib(String osId) { + private static Path fetchNssLib(String osId, Path libraryName) { switch (osId) { case "Windows-amd64-64": - return fetchNssLib(WINDOWS_X64.class); + return fetchNssLib(WINDOWS_X64.class, libraryName); case "MacOSX-x86_64-64": - return fetchNssLib(MACOSX_X64.class); + return fetchNssLib(MACOSX_X64.class, libraryName); case "MacOSX-aarch64-64": - return fetchNssLib(MACOSX_AARCH64.class); + return fetchNssLib(MACOSX_AARCH64.class, libraryName); case "Linux-amd64-64": if (Platform.isOracleLinux7()) { throw new SkippedException("Skipping Oracle Linux prior to v8"); } else { - return fetchNssLib(LINUX_X64.class); + return fetchNssLib(LINUX_X64.class, libraryName); } case "Linux-aarch64-64": if (Platform.isOracleLinux7()) { throw new SkippedException("Skipping Oracle Linux prior to v8"); } else { - return fetchNssLib(LINUX_AARCH64.class); + return fetchNssLib(LINUX_AARCH64.class, libraryName); } default: return null; } } - private static String fetchNssLib(Class clazz) { - String path = null; + private static Path fetchNssLib(Class clazz, Path libraryName) { + Path path = null; try { - path = ArtifactResolver.resolve(clazz).entrySet().stream() - .findAny().get().getValue() + File.separator + "nss" - + File.separator + "lib" + File.separator; - } catch (ArtifactResolverException e) { + Path p = ArtifactResolver.resolve(clazz).entrySet().stream() + .findAny().get().getValue(); + path = findNSSLibrary(p, libraryName); + } catch (ArtifactResolverException | IOException e) { Throwable cause = e.getCause(); if (cause == null) { System.out.println("Cannot resolve artifact, " @@ -784,6 +776,16 @@ private static String fetchNssLib(Class clazz) { return path; } + private static Path findNSSLibrary(Path path, Path libraryName) throws IOException { + try(Stream files = Files.find(path, 10, + (tp, attr) -> tp.getFileName().equals(libraryName))) { + + return files.findAny() + .orElseThrow(() -> new SkippedException( + "NSS library \"" + libraryName + "\" was not found in " + path)); + } + } + public abstract void main(Provider p) throws Exception; protected boolean skipTest(Provider p) { From 18616558d357a526323e3e8106d928ac631951f2 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Tue, 23 Apr 2024 10:45:34 +0000 Subject: [PATCH 215/298] 8316154: Opensource JTextArea manual tests Backport-of: 33c62e4fffe33a7593fd0c01de53507bfd01dc3b --- .../jdk/javax/swing/JTextArea/bug4265784.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 test/jdk/javax/swing/JTextArea/bug4265784.java diff --git a/test/jdk/javax/swing/JTextArea/bug4265784.java b/test/jdk/javax/swing/JTextArea/bug4265784.java new file mode 100644 index 00000000000..3465fced595 --- /dev/null +++ b/test/jdk/javax/swing/JTextArea/bug4265784.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4265784 4267291 + * @summary Tests work of TAB key in JTextArea + * @key headful + * @run main bug4265784 + */ + +import javax.swing.JFrame; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class bug4265784 { + static JFrame frame; + static JTextArea ta; + static volatile Point p; + static volatile int pos; + static volatile int pos1; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4265784"); + ta = new JTextArea(); + frame.getContentPane().add(ta); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = ta.getLocationOnScreen(); + }); + robot.mouseMove(p.x + 10, p.y + 10); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SwingUtilities.invokeAndWait(() -> { + pos = ta.getCaretPosition(); + }); + System.out.println(pos); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pos1 = ta.getCaretPosition(); + }); + System.out.println(pos1); + if (pos == pos1) { + throw new RuntimeException("TAB ignored"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From febbf357f5f26a43a30cbcf2e88ed171b01b918a Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Tue, 23 Apr 2024 10:45:50 +0000 Subject: [PATCH 216/298] 8316242: Opensource SwingGraphics manual test Backport-of: a57b9dab6c02c313f3975f47d502dae270c67508 --- .../swing/SwingGraphics/TranslateTest.java | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 test/jdk/javax/swing/SwingGraphics/TranslateTest.java diff --git a/test/jdk/javax/swing/SwingGraphics/TranslateTest.java b/test/jdk/javax/swing/SwingGraphics/TranslateTest.java new file mode 100644 index 00000000000..305b5c0b3a4 --- /dev/null +++ b/test/jdk/javax/swing/SwingGraphics/TranslateTest.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4207383 + * @summary This tests, in a round about manner, that SwingGraphics does + * not wrongly translate the original graphics when disposed. While + * this test seems rather ugly, it was possible to get this to happen + * in real world apps. This test is really only valid for 1.1.x. + * @key headful + * @run main TranslateTest + */ + +import java.io.File; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.plaf.ComponentUI; +import javax.imageio.ImageIO; + +public class TranslateTest { + static JFrame frame; + static volatile Point pt; + static volatile Dimension dim; + static final int WIDTH = 200; + static final int HEIGHT = 200; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("TranslateTest"); + + // paintComponent() triggers create swing graphics which will + // be invoked on child. + MyPanel panel = new MyPanel(); + panel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + panel.test(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pt = frame.getLocationOnScreen(); + dim = frame.getSize(); + }); + BufferedImage img = robot.createScreenCapture( + new Rectangle(pt.x + dim.width / 2, + pt.y + dim.height / 2, + WIDTH / 2, HEIGHT / 2)); + robot.waitForIdle(); + robot.delay(500); + Color c = new Color(img.getRGB(img.getWidth() / 2, img.getHeight() / 2)); + if (c.getRed() < 250) { + ImageIO.write(img, "png", new File("image.png")); + System.out.println("Color " + c); + throw new RuntimeException("Translated Color is not red"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + + static class MyPanel extends JPanel { + int state; + Graphics realG; + Image image; + + public void test() { + image = createImage(TranslateTest.WIDTH, TranslateTest.HEIGHT); + Graphics g = image.getGraphics(); + g.setClip(0, 0, TranslateTest.WIDTH, TranslateTest.HEIGHT); + realG = g; + state = 1; + paintComponent(g); + state = 3; + paintComponent(g); + state = 4; + } + + + public void paint(Graphics g) { + if (state == 0) { + test(); + } + super.paint(g); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + } + + public void updateUI() { + setUI(new ComponentUI() { + public void paint(Graphics g, JComponent c) { + if (state == 1) { + // g is the first SwingGraphics, when it is disposed + // translateX/translateY will be wrong + //System.out.println("FIRST:" + g); + g.translate(100, 100); + state = 2; + paintComponent(realG); + } + else if (state == 2) { + // g is the first SwingGraphics, when it is disposed + // translateX/translateY will be wrong + g.translate(100, 100); + //System.out.println("Second:" + g); + } + else if (state == 3) { + // g should be the same as the first, with the wrong + // translate. + // otherG should be the second graphics, again with + // the wrong translation, disposing the second will + // cause g to be translated to -100, -100, which + // should not happen. + Graphics otherG = g.create(0, 0, 100, 100); + //System.out.println("THIRD:" + g); + otherG.dispose(); + g.setColor(Color.red); + //System.out.println("LAST: " + g); + g.fillRect(100, 100, 100, 100); + } + else if (state == 4) { + g.drawImage(image, 0, 0, null); + } + } + }); + } + } +} From ac402fb4ba32557c9a94a9f7811c4e14c23366e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Arias=20de=20Reyna?= Date: Tue, 23 Apr 2024 10:54:33 +0000 Subject: [PATCH 217/298] 8293850: need a largest_committed metric for each category of NMT's output Reviewed-by: stuefe Backport-of: 8647f001bbb804503e8491d10f77aa0f34d66bf2 --- src/hotspot/share/services/memReporter.cpp | 22 +++++++++++-------- src/hotspot/share/services/memReporter.hpp | 6 ++--- .../share/services/virtualMemoryTracker.cpp | 14 ++++++++++++ .../share/services/virtualMemoryTracker.hpp | 13 ++++++++++- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/hotspot/share/services/memReporter.cpp b/src/hotspot/share/services/memReporter.cpp index 717699d84ea..dcad285c63a 100644 --- a/src/hotspot/share/services/memReporter.cpp +++ b/src/hotspot/share/services/memReporter.cpp @@ -50,10 +50,13 @@ size_t MemReporterBase::committed_total(const MallocMemory* malloc, const Virtua return malloc->malloc_size() + malloc->arena_size() + vm->committed(); } -void MemReporterBase::print_total(size_t reserved, size_t committed) const { +void MemReporterBase::print_total(size_t reserved, size_t committed, size_t peak) const { const char* scale = current_scale(); output()->print("reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s", amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); + if (peak != 0) { + output()->print(", largest_committed=" SIZE_FORMAT "%s", amount_in_current_scale(peak), scale); + } } void MemReporterBase::print_malloc(const MemoryCounter* c, MEMFLAGS flag) const { @@ -89,10 +92,10 @@ void MemReporterBase::print_malloc(const MemoryCounter* c, MEMFLAGS flag) const } } -void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed) const { +void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed, size_t peak) const { const char* scale = current_scale(); - output()->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s)", - amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); + output()->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s, largest_committed=" SIZE_FORMAT "%s)", + amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale, amount_in_current_scale(peak), scale); } void MemReporterBase::print_malloc_line(const MemoryCounter* c) const { @@ -101,9 +104,9 @@ void MemReporterBase::print_malloc_line(const MemoryCounter* c) const { output()->print_cr(" "); } -void MemReporterBase::print_virtual_memory_line(size_t reserved, size_t committed) const { +void MemReporterBase::print_virtual_memory_line(size_t reserved, size_t committed, size_t peak) const { output()->print("%28s", " "); - print_virtual_memory(reserved, committed); + print_virtual_memory(reserved, committed, peak); output()->print_cr(" "); } @@ -228,7 +231,7 @@ void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag, // report thread count out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", ThreadStackTracker::thread_count()); out->print("%27s (stack: ", " "); - print_total(thread_stack_usage->reserved(), thread_stack_usage->committed()); + print_total(thread_stack_usage->reserved(), thread_stack_usage->committed(), thread_stack_usage->peak_size()); } else { MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack); const char* scale = current_scale(); @@ -246,8 +249,9 @@ void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag, print_malloc_line(malloc_memory->malloc_counter()); } - if (amount_in_current_scale(virtual_memory->reserved()) > 0) { - print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed()); + if (amount_in_current_scale(virtual_memory->reserved()) > 0 + DEBUG_ONLY(|| amount_in_current_scale(virtual_memory->peak_size()) > 0)) { + print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed(), virtual_memory->peak_size()); } if (amount_in_current_scale(malloc_memory->arena_size()) > 0 diff --git a/src/hotspot/share/services/memReporter.hpp b/src/hotspot/share/services/memReporter.hpp index affc97098dc..b9e31d4bc4b 100644 --- a/src/hotspot/share/services/memReporter.hpp +++ b/src/hotspot/share/services/memReporter.hpp @@ -107,12 +107,12 @@ class MemReporterBase : public StackObj { } // Print summary total, malloc and virtual memory - void print_total(size_t reserved, size_t committed) const; + void print_total(size_t reserved, size_t committed, size_t peak = 0) const; void print_malloc(const MemoryCounter* c, MEMFLAGS flag = mtNone) const; - void print_virtual_memory(size_t reserved, size_t committed) const; + void print_virtual_memory(size_t reserved, size_t committed, size_t peak) const; void print_malloc_line(const MemoryCounter* c) const; - void print_virtual_memory_line(size_t reserved, size_t committed) const; + void print_virtual_memory_line(size_t reserved, size_t committed, size_t peak) const; void print_arena_line(const MemoryCounter* c) const; void print_virtual_memory_region(const char* type, address base, size_t size) const; diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index 66fdb236256..ebb32ecbeeb 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -34,6 +34,20 @@ size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)]; +#ifdef ASSERT +void VirtualMemory::update_peak(size_t size) { + size_t peak_sz = peak_size(); + while (peak_sz < size) { + size_t old_sz = Atomic::cmpxchg(&_peak_size, peak_sz, size, memory_order_relaxed); + if (old_sz == peak_sz) { + break; + } else { + peak_sz = old_sz; + } + } +} +#endif // ASSERT + void VirtualMemorySummary::initialize() { assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); // Use placement operator new to initialize static data area. diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index de1a72f65aa..41af085e248 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -43,12 +43,20 @@ class VirtualMemory { size_t _reserved; size_t _committed; +#ifdef ASSERT + volatile size_t _peak_size; + void update_peak(size_t size); +#endif // ASSERT + public: - VirtualMemory() : _reserved(0), _committed(0) { } + VirtualMemory() : _reserved(0), _committed(0) { + DEBUG_ONLY(_peak_size = 0;) + } inline void reserve_memory(size_t sz) { _reserved += sz; } inline void commit_memory (size_t sz) { _committed += sz; + DEBUG_ONLY(update_peak(sz);) assert(_committed <= _reserved, "Sanity check"); } @@ -64,6 +72,9 @@ class VirtualMemory { inline size_t reserved() const { return _reserved; } inline size_t committed() const { return _committed; } + inline size_t peak_size() const { + return DEBUG_ONLY(Atomic::load(&_peak_size)) NOT_DEBUG(0); + } }; // Virtual memory allocation site, keeps track where the virtual memory is reserved. From 324cef1ce38c80b2d5ee224ef31e29eb8633cac0 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Tue, 23 Apr 2024 10:59:24 +0000 Subject: [PATCH 218/298] 8327971: Multiple ASAN errors reported for metaspace 8327988: When running ASAN, disable dangerous NMT test Reviewed-by: stuefe, shade Backport-of: 9e566d76d1d8acca27d8f69fffcbeb0b49b060ba --- src/hotspot/share/memory/metaspace/metachunk.cpp | 8 ++++++-- src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp | 5 +++++ src/hotspot/share/runtime/os.cpp | 6 ++++++ src/hotspot/share/services/mallocTracker.cpp | 6 ++++++ src/hotspot/share/utilities/macros.hpp | 6 ++++++ test/hotspot/gtest/metaspace/test_virtualspacenode.cpp | 6 ++++++ .../gtest/nmt/test_nmt_buffer_overflow_detection.cpp | 5 +++++ test/hotspot/gtest/nmt/test_nmt_cornercases.cpp | 5 +++++ test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp | 5 +++++ 9 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/memory/metaspace/metachunk.cpp b/src/hotspot/share/memory/metaspace/metachunk.cpp index bc514c856e7..3d67aac8016 100644 --- a/src/hotspot/share/memory/metaspace/metachunk.cpp +++ b/src/hotspot/share/memory/metaspace/metachunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,6 +34,7 @@ #include "utilities/align.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #include "utilities/ostream.hpp" namespace metaspace { @@ -285,7 +286,9 @@ void Metachunk::verify() const { const size_t required_alignment = word_size() * sizeof(MetaWord); assert_is_aligned(base(), required_alignment); - // Test accessing the committed area. + // Test accessing the committed area. But not for ASAN. We don't know which portions + // of the chunk are still poisoned. +#if !INCLUDE_ASAN SOMETIMES( if (_committed_words > 0) { for (const MetaWord* p = _base; p < _base + _committed_words; p += os::vm_page_size()) { @@ -294,6 +297,7 @@ void Metachunk::verify() const { dummy = *(_base + _committed_words - 1); } ) +#endif // !INCLUDE_ASAN } #endif // ASSERT diff --git a/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp b/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp index 1ebda015eb3..099ba80f2dd 100644 --- a/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp +++ b/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp @@ -48,6 +48,7 @@ #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" #include "utilities/ostream.hpp" namespace metaspace { @@ -433,6 +434,9 @@ void VirtualSpaceNode::verify_locked() const { _commit_mask.verify(); // Verify memory against commit mask. + // Down here, from ASAN's view, this memory may be poisoned, since we only unpoison + // way up at the ChunkManager level. +#if !INCLUDE_ASAN SOMETIMES( for (MetaWord* p = base(); p < base() + used_words(); p += os::vm_page_size()) { if (_commit_mask.is_committed_address(p)) { @@ -440,6 +444,7 @@ void VirtualSpaceNode::verify_locked() const { } } ) +#endif // !INCLUDE_ASAN assert(committed_words() <= word_size(), "Sanity"); assert_is_aligned(committed_words(), Settings::commit_granule_words()); diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index a5ea07d8c64..d27d34d7a81 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -73,6 +73,7 @@ #include "utilities/count_trailing_zeros.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" +#include "utilities/macros.hpp" #include "utilities/powerOfTwo.hpp" #ifndef _WINDOWS @@ -1144,6 +1145,8 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) { return; } +#if !INCLUDE_ASAN + bool accessible = is_readable_pointer(addr); // Check if addr is a JNI handle. @@ -1230,7 +1233,10 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) { return; } +#endif // !INCLUDE_ASAN + st->print_cr(INTPTR_FORMAT " is an unknown value", p2i(addr)); + } bool is_pointer_bad(intptr_t* ptr) { diff --git a/src/hotspot/share/services/mallocTracker.cpp b/src/hotspot/share/services/mallocTracker.cpp index 5dab3837707..2e8b369d3ac 100644 --- a/src/hotspot/share/services/mallocTracker.cpp +++ b/src/hotspot/share/services/mallocTracker.cpp @@ -40,6 +40,7 @@ #include "services/mallocTracker.hpp" #include "services/memTracker.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #include "utilities/ostream.hpp" #include "utilities/vmError.hpp" @@ -198,6 +199,8 @@ void MallocTracker::deaccount(MallocHeader::FreeInfo free_info) { bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { assert(MemTracker::enabled(), "NMT not enabled"); +#if !INCLUDE_ASAN + address addr = (address)p; // Carefully feel your way upwards and try to find a malloc header. Then check if @@ -275,5 +278,8 @@ bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { } return true; } + +#endif // !INCLUDE_ASAN + return false; } diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index bfbaaa58acc..244b18ecdd4 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -635,4 +635,10 @@ #define NOT_CDS_JAVA_HEAP_RETURN_(code) { return code; } #endif +#ifdef ADDRESS_SANITIZER +#define INCLUDE_ASAN 1 +#else +#define INCLUDE_ASAN 0 +#endif + #endif // SHARE_UTILITIES_MACROS_HPP diff --git a/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp b/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp index 74e0aaa6124..6d21dbf7678 100644 --- a/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp +++ b/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp @@ -34,6 +34,7 @@ #include "memory/metaspace/virtualSpaceNode.hpp" #include "runtime/mutexLocker.hpp" #include "sanitizers/address.hpp" +#include "utilities/macros.hpp" #include "utilities/debug.hpp" //#define LOG_PLEASE #include "metaspaceGtestCommon.hpp" @@ -156,6 +157,11 @@ class VirtualSpaceNodeTest { // The chunk should be as far committed as was requested EXPECT_GE(c->committed_words(), request_commit_words); + // At the VirtualSpaceNode level, all memory is still poisoned. + // Since we bypass the normal way of allocating chunks (ChunkManager::get_chunk), we + // need to unpoison this chunk. + ASAN_UNPOISON_MEMORY_REGION(c->base(), c->committed_words() * BytesPerWord); + // Zap committed portion. DEBUG_ONLY(zap_range(c->base(), c->committed_words());) diff --git a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp index ce30fb8d61d..fe9dbb1f5da 100644 --- a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp @@ -26,11 +26,14 @@ #include "memory/allocation.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" +#include "sanitizers/address.hpp" #include "utilities/debug.hpp" #include "utilities/ostream.hpp" #include "unittest.hpp" #include "testutils.hpp" +#if !INCLUDE_ASAN + // This prefix shows up on any c heap corruption NMT detects. If unsure which assert will // come, just use this one. #define COMMON_NMT_HEAP_CORRUPTION_MESSAGE_PREFIX "NMT corruption" @@ -161,3 +164,5 @@ TEST_VM(NMT, test_realloc) { } } } + +#endif // !INCLUDE_ASAN diff --git a/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp b/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp index 695c586b1d8..b0400ccf342 100644 --- a/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_cornercases.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "memory/allocation.hpp" #include "runtime/os.hpp" +#include "sanitizers/address.hpp" #include "services/mallocHeader.inline.hpp" #include "services/mallocTracker.hpp" #include "services/memTracker.hpp" @@ -38,6 +39,9 @@ static void check_expected_malloc_header(const void* payload, MEMFLAGS type, siz EXPECT_EQ(hdr->flags(), type); } +// ASAN complains about allocating very large sizes +#if !INCLUDE_ASAN + // Check that a malloc with an overflowing size is rejected. TEST_VM(NMT, malloc_failure1) { void* p = os::malloc(SIZE_MAX, mtTest); @@ -85,6 +89,7 @@ TEST_VM(NMT, realloc_failure_overflowing_size) { TEST_VM(NMT, realloc_failure_gigantic_size) { check_failing_realloc(SIZE_MAX - M); } +#endif // !INCLUDE_ASAN static void* do_realloc(void* p, size_t old_size, size_t new_size, uint8_t old_content, bool check_nmt_header) { diff --git a/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp b/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp index 8760f22baa9..eaa909b9aaa 100644 --- a/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "memory/allocation.hpp" #include "runtime/os.hpp" +#include "sanitizers/address.hpp" #include "services/mallocHeader.inline.hpp" #include "services/memTracker.hpp" #include "unittest.hpp" @@ -33,6 +34,8 @@ //#define LOG_PLEASE #include "testutils.hpp" +#if !INCLUDE_ASAN + using ::testing::HasSubstr; static void test_pointer(const void* p, bool expected_return_code, const char* expected_message) { @@ -121,3 +124,5 @@ static void test_for_mmap(size_t sz, ssize_t offset) { TEST_VM(NMT, location_printing_mmap_1) { test_for_mmap(os::vm_page_size(), 0); } TEST_VM(NMT, location_printing_mmap_2) { test_for_mmap(os::vm_page_size(), os::vm_page_size() - 1); } + +#endif // !INCLUDE_ASAN From 031acf1c9f4e9f89ab7537eed0212b34b68fae0d Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Tue, 23 Apr 2024 13:29:53 +0000 Subject: [PATCH 219/298] 8327096: (fc) java/nio/channels/FileChannel/Size.java fails on partition incapable of creating large files Backport-of: 94b4ed5766381fdb922f9aaba02201a7fb735cb3 --- .../java/nio/channels/FileChannel/Size.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/nio/channels/FileChannel/Size.java b/test/jdk/java/nio/channels/FileChannel/Size.java index fd6e744f03f..2db86a8089e 100644 --- a/test/jdk/java/nio/channels/FileChannel/Size.java +++ b/test/jdk/java/nio/channels/FileChannel/Size.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -24,6 +24,7 @@ /* @test * @bug 4563125 * @summary Test size method of FileChannel + * @library /test/lib * @run main/othervm Size * @key randomness */ @@ -31,8 +32,10 @@ import java.io.*; import java.nio.MappedByteBuffer; import java.nio.channels.*; +import java.nio.file.FileStore; +import java.nio.file.Path; import java.util.Random; - +import jtreg.SkippedException; /** * Testing FileChannel's size method. @@ -65,6 +68,8 @@ private static void testSmallFile() throws Exception { // Test for bug 4563125 private static void testLargeFile() throws Exception { File largeFile = new File("largeFileTest"); + largeFile.deleteOnExit(); + long testSize = ((long)Integer.MAX_VALUE) * 2; initTestFile(largeFile, 10); try (FileChannel fc = new RandomAccessFile(largeFile, "rw").getChannel()) { @@ -75,8 +80,15 @@ private static void testLargeFile() throws Exception { + "Expect size " + (testSize + 10) + ", actual size " + fc.size()); } + } catch (IOException ioe) { + if ("File too large".equals(ioe.getMessage())) { + Path p = largeFile.toPath(); + FileStore store = p.getFileSystem().provider().getFileStore(p); + if ("msdos".equals(store.type())) + throw new SkippedException("file too big for FAT32"); + } + throw ioe; } - largeFile.deleteOnExit(); } /** From 955fcc11f8ec98f417e21d0e3ac0482bf064f4f3 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 08:00:19 +0000 Subject: [PATCH 220/298] 8310355: Move the stub test from initialize_final_stubs() to test/hotspot/gtest Backport-of: 4b9ec8245187a2eaccc711a6e5d3d4915dd022c9 --- src/hotspot/share/runtime/stubRoutines.cpp | 119 -------------- .../gtest/runtime/test_stubRoutines.cpp | 153 ++++++++++++++++++ 2 files changed, 153 insertions(+), 119 deletions(-) create mode 100644 test/hotspot/gtest/runtime/test_stubRoutines.cpp diff --git a/src/hotspot/share/runtime/stubRoutines.cpp b/src/hotspot/share/runtime/stubRoutines.cpp index 36dd503cd70..73be830463e 100644 --- a/src/hotspot/share/runtime/stubRoutines.cpp +++ b/src/hotspot/share/runtime/stubRoutines.cpp @@ -277,43 +277,6 @@ void StubRoutines::initialize_compiler_stubs() { } } -#ifdef ASSERT -typedef void (*arraycopy_fn)(address src, address dst, int count); - -// simple tests of generated arraycopy functions -static void test_arraycopy_func(address func, int alignment) { - int v = 0xcc; - int v2 = 0x11; - jlong lbuffer[8]; - jlong lbuffer2[8]; - address fbuffer = (address) lbuffer; - address fbuffer2 = (address) lbuffer2; - unsigned int i; - for (i = 0; i < sizeof(lbuffer); i++) { - fbuffer[i] = v; fbuffer2[i] = v2; - } - // C++ does not guarantee jlong[] array alignment to 8 bytes. - // Use middle of array to check that memory before it is not modified. - address buffer = align_up((address)&lbuffer[4], BytesPerLong); - address buffer2 = align_up((address)&lbuffer2[4], BytesPerLong); - // do an aligned copy - ((arraycopy_fn)func)(buffer, buffer2, 0); - for (i = 0; i < sizeof(lbuffer); i++) { - assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); - } - // adjust destination alignment - ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); - for (i = 0; i < sizeof(lbuffer); i++) { - assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); - } - // adjust source alignment - ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); - for (i = 0; i < sizeof(lbuffer); i++) { - assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); - } -} -#endif // ASSERT - void StubRoutines::initialize_final_stubs() { if (_final_stubs_code == nullptr) { _final_stubs_code = initialize_stubs(StubCodeGenerator::Final_stubs, @@ -322,90 +285,8 @@ void StubRoutines::initialize_final_stubs() { "StubRoutines (final stubs)", "_final_stubs_code_size"); } - -#ifdef ASSERT - - MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); - -#define TEST_ARRAYCOPY(type) \ - test_arraycopy_func( type##_arraycopy(), sizeof(type)); \ - test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \ - test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ - test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) - - // Make sure all the arraycopy stubs properly handle zero count - TEST_ARRAYCOPY(jbyte); - TEST_ARRAYCOPY(jshort); - TEST_ARRAYCOPY(jint); - TEST_ARRAYCOPY(jlong); - -#undef TEST_ARRAYCOPY - -#define TEST_FILL(type) \ - if (_##type##_fill != nullptr) { \ - union { \ - double d; \ - type body[96]; \ - } s; \ - \ - int v = 32; \ - for (int offset = -2; offset <= 2; offset++) { \ - for (int i = 0; i < 96; i++) { \ - s.body[i] = 1; \ - } \ - type* start = s.body + 8 + offset; \ - for (int aligned = 0; aligned < 2; aligned++) { \ - if (aligned) { \ - if (((intptr_t)start) % HeapWordSize == 0) { \ - ((void (*)(type*, int, int))StubRoutines::_arrayof_##type##_fill)(start, v, 80); \ - } else { \ - continue; \ - } \ - } else { \ - ((void (*)(type*, int, int))StubRoutines::_##type##_fill)(start, v, 80); \ - } \ - for (int i = 0; i < 96; i++) { \ - if (i < (8 + offset) || i >= (88 + offset)) { \ - assert(s.body[i] == 1, "what?"); \ - } else { \ - assert(s.body[i] == 32, "what?"); \ - } \ - } \ - } \ - } \ - } \ - - TEST_FILL(jbyte); - TEST_FILL(jshort); - TEST_FILL(jint); - -#undef TEST_FILL - -#define TEST_COPYRTN(type) \ - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic), sizeof(type)); \ - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type))) - - // Make sure all the copy runtime routines properly handle zero count - TEST_COPYRTN(jbyte); - TEST_COPYRTN(jshort); - TEST_COPYRTN(jint); - TEST_COPYRTN(jlong); - -#undef TEST_COPYRTN - - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord)); - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord)); - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord)); - // Aligned to BytesPerLong - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong)); - test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong)); - - MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); - -#endif } - void initial_stubs_init() { StubRoutines::initialize_initial_stubs(); } void continuation_stubs_init() { StubRoutines::initialize_continuation_stubs(); } void final_stubs_init() { StubRoutines::initialize_final_stubs(); } diff --git a/test/hotspot/gtest/runtime/test_stubRoutines.cpp b/test/hotspot/gtest/runtime/test_stubRoutines.cpp new file mode 100644 index 00000000000..1dc1d0197b5 --- /dev/null +++ b/test/hotspot/gtest/runtime/test_stubRoutines.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1997, 2023, 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. + */ + +#include "precompiled.hpp" +#include "runtime/stubRoutines.hpp" +#include "utilities/copy.hpp" +#include "unittest.hpp" + +typedef void (*arraycopy_fn)(address src, address dst, int count); + +// simple tests of generated arraycopy functions +static void test_arraycopy_func(address func, int alignment) { + int v = 0xcc; + int v2 = 0x11; + jlong lbuffer[8]; + jlong lbuffer2[8]; + address fbuffer = (address) lbuffer; + address fbuffer2 = (address) lbuffer2; + unsigned int i; + for (i = 0; i < sizeof(lbuffer); i++) { + fbuffer[i] = v; fbuffer2[i] = v2; + } + // C++ does not guarantee jlong[] array alignment to 8 bytes. + // Use middle of array to check that memory before it is not modified. + address buffer = align_up((address)&lbuffer[4], BytesPerLong); + address buffer2 = align_up((address)&lbuffer2[4], BytesPerLong); + // do an aligned copy + ((arraycopy_fn)func)(buffer, buffer2, 0); + for (i = 0; i < sizeof(lbuffer); i++) { + ASSERT_TRUE(fbuffer[i] == v && fbuffer2[i] == v2) << "shouldn't have copied anything"; + } + // adjust destination alignment + ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); + for (i = 0; i < sizeof(lbuffer); i++) { + ASSERT_TRUE(fbuffer[i] == v && fbuffer2[i] == v2) << "shouldn't have copied anything"; + } + // adjust source alignment + ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); + for (i = 0; i < sizeof(lbuffer); i++) { + ASSERT_TRUE(fbuffer[i] == v && fbuffer2[i] == v2) << "shouldn't have copied anything"; + } +} + +TEST_VM(StubRoutines, array_copy_routine) { + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); + +#define TEST_ARRAYCOPY(type) \ + test_arraycopy_func( StubRoutines::type##_arraycopy(), sizeof(type)); \ + test_arraycopy_func( StubRoutines::type##_disjoint_arraycopy(), sizeof(type)); \ + test_arraycopy_func(StubRoutines::arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ + test_arraycopy_func(StubRoutines::arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) + + // Make sure all the arraycopy stubs properly handle zero count + TEST_ARRAYCOPY(jbyte); + TEST_ARRAYCOPY(jshort); + TEST_ARRAYCOPY(jint); + TEST_ARRAYCOPY(jlong); + +#undef TEST_ARRAYCOPY + + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); +} + +TEST_VM(StubRoutines, copy_routine) { + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); + +#define TEST_COPYRTN(type) \ + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic), sizeof(type)); \ + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type))) + + // Make sure all the copy runtime routines properly handle zero count + TEST_COPYRTN(jbyte); + TEST_COPYRTN(jshort); + TEST_COPYRTN(jint); + TEST_COPYRTN(jlong); + +#undef TEST_COPYRTN + + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord)); + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord)); + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord)); + // Aligned to BytesPerLong + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong)); + test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong)); + + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); +} + +TEST_VM(StubRoutines, array_fill_routine) { + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); + +#define TEST_FILL(type) \ + if (StubRoutines::_##type##_fill != nullptr) { \ + union { \ + double d; \ + type body[96]; \ + } s; \ + \ + int v = 32; \ + for (int offset = -2; offset <= 2; offset++) { \ + for (int i = 0; i < 96; i++) { \ + s.body[i] = 1; \ + } \ + type* start = s.body + 8 + offset; \ + for (int aligned = 0; aligned < 2; aligned++) { \ + if (aligned) { \ + if (((intptr_t)start) % HeapWordSize == 0) { \ + ((void (*)(type*, int, int))StubRoutines::_arrayof_##type##_fill)(start, v, 80); \ + } else { \ + continue; \ + } \ + } else { \ + ((void (*)(type*, int, int))StubRoutines::_##type##_fill)(start, v, 80); \ + } \ + for (int i = 0; i < 96; i++) { \ + if (i < (8 + offset) || i >= (88 + offset)) { \ + ASSERT_TRUE(s.body[i] == 1) << "what?"; \ + } else { \ + ASSERT_TRUE(s.body[i] == 32) << "what?"; \ + } \ + } \ + } \ + } \ + } \ + + TEST_FILL(jbyte); + TEST_FILL(jshort); + TEST_FILL(jint); + +#undef TEST_FILL + + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); +} From 41237fce959471f9274cd122108b7c3bc2c3042d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 08:02:16 +0000 Subject: [PATCH 221/298] 8320707: Virtual thread test updates Reviewed-by: simonis Backport-of: b67b71cd87c62f15d5b73f923c300d0f77c988f5 --- .../GetThreadState/GetThreadStateTest.java | 79 +++---- .../lang/ScopedValue/StressStackOverflow.java | 2 +- .../Thread/virtual/CarrierThreadWaits.java | 42 ++-- .../virtual/GetStackTraceWhenRunnable.java | 45 ++-- .../java/lang/Thread/virtual/JfrEvents.java | 120 +++++++---- ...WaitNotify.java => MonitorWaitNotify.java} | 48 +++-- .../java/lang/Thread/virtual/StackTraces.java | 2 +- .../java/lang/Thread/virtual/ThreadAPI.java | 192 +++++++++++++++--- .../VirtualThreadPinnedEventThrows.java | 35 ++-- .../lang/Thread/virtual/stress/PinALot.java | 14 +- .../lang/Thread/virtual/stress/Skynet.java | 6 +- .../channels/Selector/SelectWithConsumer.java | 4 +- .../jdk/test/lib/thread/VThreadPinner.java | 101 +++++++++ .../jdk/test/lib/thread/VThreadRunner.java | 68 +++---- 14 files changed, 538 insertions(+), 220 deletions(-) rename test/jdk/java/lang/Thread/virtual/{WaitNotify.java => MonitorWaitNotify.java} (81%) create mode 100644 test/lib/jdk/test/lib/thread/VThreadPinner.java diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java index 17c17b9b1f5..4ee1d1a0bfc 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java @@ -25,20 +25,22 @@ * @test id=default * @bug 8312498 * @summary Basic test for JVMTI GetThreadState with virtual threads + * @library /test/lib * @run junit/othervm/native GetThreadStateTest */ /* * @test id=no-vmcontinuations * @requires vm.continuations + * @library /test/lib * @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest */ import java.util.StringJoiner; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -75,10 +77,10 @@ void testTerminated() throws Exception { */ @Test void testRunnable() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); // spin until done while (!done.get()) { @@ -87,7 +89,7 @@ void testRunnable() throws Exception { }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should be runnable int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE; @@ -107,17 +109,17 @@ void testRunnable() throws Exception { */ @Test void testMonitorEnter() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().unstarted(() -> { - latch.countDown(); + started.set(true); synchronized (lock) { } }); try { synchronized (lock) { // start thread and wait for it to start execution thread.start(); - latch.await(); + awaitTrue(started); // thread should block on monitor enter int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; @@ -137,19 +139,19 @@ void testMonitorEnter() throws Exception { */ @Test void testObjectWait() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().start(() -> { synchronized (lock) { - latch.countDown(); + started.set(true); try { lock.wait(); } catch (InterruptedException e) { } } }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should wait int expected = JVMTI_THREAD_STATE_ALIVE | @@ -179,19 +181,19 @@ void testObjectWait() throws Exception { */ @Test void testObjectWaitMillis() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); Object lock = new Object(); var thread = Thread.ofVirtual().start(() -> { synchronized (lock) { - latch.countDown(); + started.set(true); try { lock.wait(Long.MAX_VALUE); } catch (InterruptedException e) { } } }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should wait int expected = JVMTI_THREAD_STATE_ALIVE | @@ -221,17 +223,17 @@ void testObjectWaitMillis() throws Exception { */ @Test void testPark() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); while (!done.get()) { LockSupport.park(); } }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -251,17 +253,17 @@ void testPark() throws Exception { */ @Test void testParkNanos() throws Exception { - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - latch.countDown(); + started.set(true); while (!done.get()) { LockSupport.parkNanos(Long.MAX_VALUE); } }); try { // wait for thread to start execution - latch.await(); + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -281,20 +283,19 @@ void testParkNanos() throws Exception { */ @Test void testParkWhenPinned() throws Exception { - var latch = new CountDownLatch(1); - Object lock = new Object(); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { - latch.countDown(); + VThreadPinner.runPinned(() -> { + started.set(true); while (!done.get()) { LockSupport.park(); } - } + }); }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -314,20 +315,19 @@ void testParkWhenPinned() throws Exception { */ @Test void testParkNanosWhenPinned() throws Exception { - var latch = new CountDownLatch(1); - Object lock = new Object(); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); var thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { - latch.countDown(); + VThreadPinner.runPinned(() -> { + started.set(true); while (!done.get()) { LockSupport.parkNanos(Long.MAX_VALUE); } - } + }); }); try { - // wait for thread to own monitor - latch.await(); + // wait for thread to start execution + awaitTrue(started); // thread should park int expected = JVMTI_THREAD_STATE_ALIVE | @@ -342,6 +342,15 @@ void testParkNanosWhenPinned() throws Exception { } } + /** + * Waits for the boolean value to become true. + */ + private static void awaitTrue(AtomicBoolean ref) throws Exception { + while (!ref.get()) { + Thread.sleep(20); + } + } + /** * Asserts that the given thread has the expected JVMTI state. */ diff --git a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java index a1254c7fef7..863ad189c35 100644 --- a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java +++ b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java @@ -66,7 +66,7 @@ static class TestFailureException extends RuntimeException { TestFailureException(String s) { super(s); } } - static final long DURATION_IN_NANOS = Duration.ofMinutes(2).toNanos(); + static final long DURATION_IN_NANOS = Duration.ofMinutes(1).toNanos(); // Test the ScopedValue recovery mechanism for stack overflows. We implement both Callable // and Runnable interfaces. Which one gets tested depends on the constructor argument. diff --git a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java index e73d646bee8..4e0182064c5 100644 --- a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java +++ b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java @@ -40,7 +40,6 @@ import java.lang.management.LockInfo; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicBoolean; @@ -55,38 +54,53 @@ class CarrierThreadWaits { void testCarrierThreadWaiting() throws Exception { try (ForkJoinPool pool = new ForkJoinPool(1)) { var carrierRef = new AtomicReference(); + var vthreadRef = new AtomicReference(); + Executor scheduler = task -> { pool.submit(() -> { - carrierRef.set(Thread.currentThread()); + Thread carrier = Thread.currentThread(); + carrierRef.set(carrier); + Thread vthread = vthreadRef.get(); + + System.err.format("%s run task (%s) ...%n", carrier, vthread); task.run(); + System.err.format("%s task done (%s)%n", carrier, vthread); }); }; // start a virtual thread that spins and remains mounted until "done" - var latch = new CountDownLatch(1); + var started = new AtomicBoolean(); var done = new AtomicBoolean(); Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler); - Thread vthread = builder.start(() -> { - latch.countDown(); + Thread vthread = builder.unstarted(() -> { + started.set(true); while (!done.get()) { Thread.onSpinWait(); } }); - - // wait for virtual thread to execute - latch.await(); + vthreadRef.set(vthread); + vthread.start(); try { - long carrierId = carrierRef.get().threadId(); + // wait for virtual thread to start + while (!started.get()) { + Thread.sleep(10); + } + + Thread carrier = carrierRef.get(); + + long carrierId = carrier.threadId(); long vthreadId = vthread.threadId(); // carrier thread should be on WAITING on virtual thread ThreadInfo ti = ManagementFactory.getThreadMXBean().getThreadInfo(carrierId); - assertTrue(ti.getThreadState() == Thread.State.WAITING); - assertEquals(vthread.getClass().getName(), ti.getLockInfo().getClassName()); - assertTrue(ti.getLockInfo().getIdentityHashCode() == System.identityHashCode(vthread)); - assertTrue(ti.getLockOwnerId() == vthreadId); - + Thread.State state = ti.getThreadState(); + LockInfo lockInfo = ti.getLockInfo(); + assertEquals(Thread.State.WAITING, state); + assertNotNull(lockInfo); + assertEquals(vthread.getClass().getName(), lockInfo.getClassName()); + assertEquals(System.identityHashCode(vthread), lockInfo.getIdentityHashCode()); + assertEquals(vthreadId, ti.getLockOwnerId()); } finally { done.set(true); } diff --git a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java index 4cf7deecb36..38760eb52a8 100644 --- a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java +++ b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java @@ -29,35 +29,34 @@ */ import java.io.IOException; -import java.nio.channels.ClosedSelectorException; -import java.nio.channels.Selector; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; public class GetStackTraceWhenRunnable { public static void main(String[] args) throws Exception { - try (Selector sel = Selector.open()) { - // start thread1 and wait for it to park - Thread thread1 = Thread.startVirtualThread(LockSupport::park); - while (thread1.getState() != Thread.State.WAITING) { - Thread.sleep(20); - } + // start thread1 and wait for it to park + Thread thread1 = Thread.startVirtualThread(LockSupport::park); + while (thread1.getState() != Thread.State.WAITING) { + Thread.sleep(20); + } - // start thread2 to pin the carrier thread - CountDownLatch latch = new CountDownLatch(1); - Thread thread2 = Thread.startVirtualThread(() -> { - latch.countDown(); - try { - sel.select(); - } catch (ClosedSelectorException e) { - // expected - } catch (IOException ioe) { - ioe.printStackTrace(); - } - }); - latch.await(); // wait for thread2 to run + // start thread2 to pin the carrier thread + var started = new AtomicBoolean(); + var done = new AtomicBoolean(); + Thread thread2 = Thread.startVirtualThread(() -> { + started.set(true); + while (!done.get()) { + Thread.onSpinWait(); + } + }); + try { + // wait for thread2 to start + while (!started.get()) { + Thread.sleep(10); + } // unpark thread1 and check that it is "stuck" in the runnable state // (the carrier thread is pinned, no other virtual thread can run) @@ -73,6 +72,10 @@ public static void main(String[] args) throws Exception { for (StackTraceElement e : stack) { System.out.println(e); } + } finally { + done.set(true); + thread2.join(); + thread1.join(); } } diff --git a/test/jdk/java/lang/Thread/virtual/JfrEvents.java b/test/jdk/java/lang/Thread/virtual/JfrEvents.java index 0cdd6a529d1..282a8959fe8 100644 --- a/test/jdk/java/lang/Thread/virtual/JfrEvents.java +++ b/test/jdk/java/lang/Thread/virtual/JfrEvents.java @@ -26,12 +26,12 @@ * @summary Basic test for JFR jdk.VirtualThreadXXX events * @requires vm.continuations * @modules jdk.jfr java.base/java.lang:+open - * @run junit/othervm JfrEvents + * @library /test/lib + * @run junit/othervm --enable-native-access=ALL-UNNAMED JfrEvents */ import java.io.IOException; import java.nio.file.Path; -import java.time.Duration; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; @@ -39,20 +39,27 @@ import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; +import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.jfr.EventType; import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; +import jdk.test.lib.thread.VThreadPinner; +import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; class JfrEvents { - private static final Object lock = new Object(); /** * Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events. @@ -85,45 +92,90 @@ void testVirtualThreadStartAndEnd() throws Exception { } } + /** + * Arguments for testVirtualThreadPinned to test jdk.VirtualThreadPinned event. + * [0] label/description + * [1] the operation to park/wait + * [2] the Thread.State when parked/waiting + * [3] the action to unpark/notify the thread + */ + static Stream pinnedCases() { + Object lock = new Object(); + + // park with native frame on stack + var finish1 = new AtomicBoolean(); + var parkWhenPinned = Arguments.of( + "LockSupport.park when pinned", + (ThrowingRunnable) () -> { + VThreadPinner.runPinned(() -> { + while (!finish1.get()) { + LockSupport.park(); + } + }); + }, + Thread.State.WAITING, + (Consumer) t -> { + finish1.set(true); + LockSupport.unpark(t); + } + ); + + // timed park with native frame on stack + var finish2 = new AtomicBoolean(); + var timedParkWhenPinned = Arguments.of( + "LockSupport.parkNanos when pinned", + (ThrowingRunnable) () -> { + VThreadPinner.runPinned(() -> { + while (!finish2.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + }); + }, + Thread.State.TIMED_WAITING, + (Consumer) t -> { + finish2.set(true); + LockSupport.unpark(t); + } + ); + + return Stream.of(parkWhenPinned, timedParkWhenPinned); + } + /** * Test jdk.VirtualThreadPinned event. */ - @Test - void testVirtualThreadPinned() throws Exception { - Runnable[] parkers = new Runnable[] { - () -> LockSupport.park(), - () -> LockSupport.parkNanos(Duration.ofDays(1).toNanos()) - }; + @ParameterizedTest + @MethodSource("pinnedCases") + void testVirtualThreadPinned(String label, + ThrowingRunnable parker, + Thread.State expectedState, + Consumer unparker) throws Exception { try (Recording recording = new Recording()) { recording.enable("jdk.VirtualThreadPinned"); recording.start(); - try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { - for (Runnable parker : parkers) { - // execute parking task in virtual thread - var threadRef = new AtomicReference(); - executor.submit(() -> { - threadRef.set(Thread.currentThread()); - synchronized (lock) { - parker.run(); // should pin carrier - } - }); - - // wait for the task to start and the virtual thread to park - Thread thread; - while ((thread = threadRef.get()) == null) { - Thread.sleep(10); - } + try { + var exception = new AtomicReference(); + var thread = Thread.ofVirtual().start(() -> { try { - Thread.State state = thread.getState(); - while (state != Thread.State.WAITING && state != Thread.State.TIMED_WAITING) { - Thread.sleep(10); - state = thread.getState(); - } - } finally { - LockSupport.unpark(thread); + parker.run(); + } catch (Throwable e) { + exception.set(e); + } + }); + try { + // wait for thread to park/wait + Thread.State state = thread.getState(); + while (state != expectedState) { + assertTrue(state != Thread.State.TERMINATED, thread.toString()); + Thread.sleep(10); + state = thread.getState(); } + } finally { + unparker.accept(thread); + thread.join(); + assertNull(exception.get()); } } finally { recording.stop(); @@ -132,9 +184,9 @@ void testVirtualThreadPinned() throws Exception { Map events = sumEvents(recording); System.err.println(events); - // should have a pinned event for each park + // should have at least one pinned event int pinnedCount = events.getOrDefault("jdk.VirtualThreadPinned", 0); - assertEquals(parkers.length, pinnedCount); + assertTrue(pinnedCount >= 1, "Expected one or more events"); } } diff --git a/test/jdk/java/lang/Thread/virtual/WaitNotify.java b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java similarity index 81% rename from test/jdk/java/lang/Thread/virtual/WaitNotify.java rename to test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java index bc7b36b39be..1320cc8f15f 100644 --- a/test/jdk/java/lang/Thread/virtual/WaitNotify.java +++ b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java @@ -24,8 +24,9 @@ /** * @test * @summary Test virtual threads using Object.wait/notifyAll + * @modules java.base/java.lang:+open * @library /test/lib - * @run junit WaitNotify + * @run junit MonitorWaitNotify */ import java.util.concurrent.Semaphore; @@ -34,7 +35,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -class WaitNotify { +class MonitorWaitNotify { /** * Test virtual thread waits, notified by platform thread. @@ -84,24 +85,31 @@ void testWaitNotify2() throws Exception { */ @Test void testWaitNotify3() throws Exception { - var lock = new Object(); - var ready = new Semaphore(0); - var thread1 = Thread.ofVirtual().start(() -> { - synchronized (lock) { - ready.release(); - try { - lock.wait(); - } catch (InterruptedException e) { } - } - }); - var thread2 = Thread.ofVirtual().start(() -> { - ready.acquireUninterruptibly(); - synchronized (lock) { - lock.notifyAll(); - } - }); - thread1.join(); - thread2.join(); + // need at least two carrier threads due to pinning + int previousParallelism = VThreadRunner.ensureParallelism(2); + try { + var lock = new Object(); + var ready = new Semaphore(0); + var thread1 = Thread.ofVirtual().start(() -> { + synchronized (lock) { + ready.release(); + try { + lock.wait(); + } catch (InterruptedException e) { } + } + }); + var thread2 = Thread.ofVirtual().start(() -> { + ready.acquireUninterruptibly(); + synchronized (lock) { + lock.notifyAll(); + } + }); + thread1.join(); + thread2.join(); + } finally { + // restore + VThreadRunner.setParallelism(previousParallelism); + } } /** diff --git a/test/jdk/java/lang/Thread/virtual/StackTraces.java b/test/jdk/java/lang/Thread/virtual/StackTraces.java index fb5c40dc4e9..cb1877090fe 100644 --- a/test/jdk/java/lang/Thread/virtual/StackTraces.java +++ b/test/jdk/java/lang/Thread/virtual/StackTraces.java @@ -23,7 +23,7 @@ /** * @test - * @summary Test stack traces in exceptions and stack frames waslked by the StackWalker + * @summary Test stack traces in exceptions and stack frames walked by the StackWalker * API do not include the carrier stack frames * @requires vm.continuations * @modules java.management diff --git a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java index 663da9126d6..d7618684987 100644 --- a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java +++ b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java @@ -27,7 +27,7 @@ * @summary Test Thread API with virtual threads * @modules java.base/java.lang:+open * @library /test/lib - * @run junit ThreadAPI + * @run junit/othervm --enable-native-access=ALL-UNNAMED ThreadAPI */ /* @@ -35,7 +35,8 @@ * @requires vm.continuations * @modules java.base/java.lang:+open * @library /test/lib - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations ThreadAPI + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations + * --enable-native-access=ALL-UNNAMED ThreadAPI */ import java.time.Duration; @@ -61,6 +62,7 @@ import java.nio.channels.Selector; import jdk.test.lib.thread.VThreadRunner; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; @@ -755,11 +757,11 @@ void testJoin32() throws Exception { void testJoin33() throws Exception { AtomicBoolean done = new AtomicBoolean(); Thread thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { + VThreadPinner.runPinned(() -> { while (!done.get()) { LockSupport.parkNanos(Duration.ofMillis(20).toNanos()); } - } + }); }); try { assertFalse(thread.join(Duration.ofMillis(100))); @@ -1136,7 +1138,7 @@ void testSetDaemon2() throws Exception { } /** - * Test Thread.yield releases thread when not pinned. + * Test Thread.yield releases carrier thread. */ @Test void testYield1() throws Exception { @@ -1164,7 +1166,7 @@ void testYield1() throws Exception { } /** - * Test Thread.yield when thread is pinned. + * Test Thread.yield when thread is pinned by native frame. */ @Test void testYield2() throws Exception { @@ -1179,10 +1181,10 @@ void testYield2() throws Exception { list.add("B"); }); child.start(); - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.yield(); // pinned so will be a no-op list.add("A"); - } + }); try { child.join(); } catch (InterruptedException e) { } }); thread.start(); @@ -1192,7 +1194,7 @@ void testYield2() throws Exception { } /** - * Test that Thread.yield does not consume the thread's parking permit. + * Test Thread.yield does not consume the thread's parking permit. */ @Test void testYield3() throws Exception { @@ -1205,7 +1207,7 @@ void testYield3() throws Exception { } /** - * Test that Thread.yield does not make available the thread's parking permit. + * Test Thread.yield does not make available the thread's parking permit. */ @Test void testYield4() throws Exception { @@ -1406,11 +1408,9 @@ void testSleep7() throws Exception { */ @Test void testSleep8() throws Exception { - VThreadRunner.run(() -> { + VThreadPinner.runPinned(() -> { long start = millisTime(); - synchronized (lock) { - Thread.sleep(1000); - } + Thread.sleep(1000); expectDuration(start, /*min*/900, /*max*/20_000); }); } @@ -1424,9 +1424,9 @@ void testSleep9() throws Exception { Thread me = Thread.currentThread(); me.interrupt(); try { - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.sleep(2000); - } + }); fail("sleep not interrupted"); } catch (InterruptedException e) { // expected @@ -1444,9 +1444,9 @@ void testSleep10() throws Exception { Thread t = Thread.currentThread(); scheduleInterrupt(t, 100); try { - synchronized (lock) { + VThreadPinner.runPinned(() -> { Thread.sleep(20 * 1000); - } + }); fail("sleep not interrupted"); } catch (InterruptedException e) { // interrupt status should be cleared @@ -1579,8 +1579,7 @@ void testContextClassLoader5() throws Exception { @Test void testUncaughtExceptionHandler1() throws Exception { class FooException extends RuntimeException { } - var exception = new AtomicReference(); - Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc); + var handler = new CapturingUHE(); Thread thread = Thread.ofVirtual().start(() -> { Thread me = Thread.currentThread(); assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup()); @@ -1589,7 +1588,8 @@ class FooException extends RuntimeException { } throw new FooException(); }); thread.join(); - assertTrue(exception.get() instanceof FooException); + assertInstanceOf(FooException.class, handler.exception()); + assertEquals(thread, handler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } @@ -1599,8 +1599,7 @@ class FooException extends RuntimeException { } @Test void testUncaughtExceptionHandler2() throws Exception { class FooException extends RuntimeException { } - var exception = new AtomicReference(); - Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc); + var handler = new CapturingUHE(); Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(handler); Thread thread; @@ -1611,25 +1610,61 @@ class FooException extends RuntimeException { } }); thread.join(); } finally { - Thread.setDefaultUncaughtExceptionHandler(savedHandler); + Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore } - assertTrue(exception.get() instanceof FooException); + assertInstanceOf(FooException.class, handler.exception()); + assertEquals(thread, handler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } /** - * Test no UncaughtExceptionHandler set. + * Test Thread and default UncaughtExceptionHandler set. */ @Test void testUncaughtExceptionHandler3() throws Exception { class FooException extends RuntimeException { } - Thread thread = Thread.ofVirtual().start(() -> { - throw new FooException(); - }); - thread.join(); + var defaultHandler = new CapturingUHE(); + var threadHandler = new CapturingUHE(); + Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(defaultHandler); + Thread thread; + try { + thread = Thread.ofVirtual().start(() -> { + Thread me = Thread.currentThread(); + assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup()); + me.setUncaughtExceptionHandler(threadHandler); + assertTrue(me.getUncaughtExceptionHandler() == threadHandler); + throw new FooException(); + }); + thread.join(); + } finally { + Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore + } + assertInstanceOf(FooException.class, threadHandler.exception()); + assertNull(defaultHandler.exception()); + assertEquals(thread, threadHandler.thread()); assertNull(thread.getUncaughtExceptionHandler()); } + /** + * Test no Thread or default UncaughtExceptionHandler set. + */ + @Test + void testUncaughtExceptionHandler4() throws Exception { + Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(null); + try { + class FooException extends RuntimeException { } + Thread thread = Thread.ofVirtual().start(() -> { + throw new FooException(); + }); + thread.join(); + assertNull(thread.getUncaughtExceptionHandler()); + } finally { + Thread.setDefaultUncaughtExceptionHandler(savedHandler); + } + } + /** * Test Thread::threadId and getId. */ @@ -2064,10 +2099,76 @@ void testGetStackTrace5() throws Exception { } /** - * Test Thread::getStackTrace on terminated thread. + * Test Thread::getStackTrace on timed-parked thread. */ @Test void testGetStackTrace6() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + LockSupport.parkNanos(Long.MAX_VALUE); + }); + await(thread, Thread.State.TIMED_WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.parkNanos")); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on parked thread that is pinned. + */ + @Test + void testGetStackTrace7() throws Exception { + AtomicBoolean done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.park(); + } + }); + }); + await(thread, Thread.State.WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.park")); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on timed-parked thread that is pinned. + */ + @Test + void testGetStackTrace8() throws Exception { + AtomicBoolean done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.parkNanos(Long.MAX_VALUE); + } + }); + }); + await(thread, Thread.State.TIMED_WAITING); + try { + StackTraceElement[] stack = thread.getStackTrace(); + assertTrue(contains(stack, "LockSupport.parkNanos")); + } finally { + done.set(true); + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test Thread::getStackTrace on terminated thread. + */ + @Test + void testGetStackTrace9() throws Exception { var thread = Thread.ofVirtual().start(() -> { }); thread.join(); StackTraceElement[] stack = thread.getStackTrace(); @@ -2234,7 +2335,7 @@ void testEnumerate1() throws Exception { ThreadGroup vgroup = Thread.currentThread().getThreadGroup(); Thread[] threads = new Thread[100]; int n = vgroup.enumerate(threads, /*recurse*/false); - assertTrue(n == 0); + assertFalse(Arrays.stream(threads, 0, n).anyMatch(Thread::isVirtual)); }); } @@ -2347,6 +2448,33 @@ void testToString4() throws Exception { assertTrue(thread.toString().contains("fred")); } + /** + * Thread.UncaughtExceptionHandler that captures the first exception thrown. + */ + private static class CapturingUHE implements Thread.UncaughtExceptionHandler { + Thread thread; + Throwable exception; + @Override + public void uncaughtException(Thread t, Throwable e) { + synchronized (this) { + if (thread == null) { + this.thread = t; + this.exception = e; + } + } + } + Thread thread() { + synchronized (this) { + return thread; + } + } + Throwable exception() { + synchronized (this) { + return exception; + } + } + } + /** * Waits for the given thread to reach a given state. */ diff --git a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java index a4bccd47265..1ae73b280cb 100644 --- a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java +++ b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java @@ -25,15 +25,18 @@ * @test * @summary Test parking when pinned and emitting the JFR VirtualThreadPinnedEvent throws * @modules java.base/jdk.internal.event + * @library /test/lib * @compile/module=java.base jdk/internal/event/VirtualThreadPinnedEvent.java - * @run junit VirtualThreadPinnedEventThrows + * @run junit/othervm --enable-native-access=ALL-UNNAMED VirtualThreadPinnedEventThrows */ import java.lang.ref.Reference; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; import jdk.internal.event.VirtualThreadPinnedEvent; +import jdk.test.lib.thread.VThreadPinner; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -82,29 +85,31 @@ void testVirtualThreadPinnedEventCommitThrows() throws Exception { * Test parking a virtual thread when pinned. */ private void testParkWhenPinned() throws Exception { - Object lock = new Object(); + var exception = new AtomicReference(); + var done = new AtomicBoolean(); + Thread thread = Thread.startVirtualThread(() -> { + try { + VThreadPinner.runPinned(() -> { + while (!done.get()) { + LockSupport.park(); + } + }); + } catch (Throwable e) { + exception.set(e); + } + }); try { - var completed = new AtomicBoolean(); - Thread thread = Thread.startVirtualThread(() -> { - synchronized (lock) { - LockSupport.park(); - completed.set(true); - } - }); - // wait for thread to park Thread.State state; while ((state = thread.getState()) != Thread.State.WAITING) { assertTrue(state != Thread.State.TERMINATED); Thread.sleep(10); } - - // unpark and check that thread completed without exception + } finally { + done.set(true); LockSupport.unpark(thread); thread.join(); - assertTrue(completed.get()); - } finally { - Reference.reachabilityFence(lock); } + assertNull(exception.get()); } } diff --git a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java index 7bfce95b5c2..a420ebb330e 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java +++ b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java @@ -25,13 +25,15 @@ * @test * @summary Stress test timed park when pinned * @requires vm.debug != true - * @run main PinALot 500000 + * @library /test/lib + * @run main/othervm --enable-native-access=ALL-UNNAMED PinALot 500000 */ /* * @test * @requires vm.debug == true - * @run main/othervm/timeout=300 PinALot 200000 + * @library /test/lib + * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED PinALot 200000 */ import java.time.Duration; @@ -39,9 +41,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; -public class PinALot { +import jdk.test.lib.thread.VThreadPinner; - static final Object lock = new Object(); +public class PinALot { public static void main(String[] args) throws Exception { int iterations = 1_000_000; @@ -53,11 +55,11 @@ public static void main(String[] args) throws Exception { AtomicInteger count = new AtomicInteger(); Thread thread = Thread.ofVirtual().start(() -> { - synchronized (lock) { + VThreadPinner.runPinned(() -> { while (count.incrementAndGet() < ITERATIONS) { LockSupport.parkNanos(1); } - } + }); }); boolean terminated; diff --git a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java index fb4adbb25f2..ee45fc827b0 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java +++ b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java @@ -26,7 +26,7 @@ * @summary Stress test virtual threads with a variation of the Skynet 1M benchmark * @requires vm.continuations * @requires !vm.debug | vm.gc != "Z" - * @run main/othervm/timeout=300 -Xmx1g Skynet + * @run main/othervm/timeout=300 -Xmx1500m Skynet */ /* @@ -35,7 +35,7 @@ * @requires vm.gc.ZSinglegen * @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions * -XX:+UseZGC -XX:-ZGenerational - * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet + * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet */ /* @@ -44,7 +44,7 @@ * @requires vm.gc.ZGenerational * @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions * -XX:+UseZGC -XX:+ZGenerational - * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet + * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet */ import java.util.concurrent.BlockingQueue; diff --git a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java index 630a1ef88b8..de8b48ec22d 100644 --- a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java +++ b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -411,9 +411,7 @@ public void testInterruptDuringSelect() throws Exception { // select(Consumer, timeout) try (Selector sel = Selector.open()) { scheduleInterrupt(Thread.currentThread(), 1, SECONDS); - long start = System.currentTimeMillis(); int n = sel.select(k -> assertTrue(false), 60*1000); - long duration = System.currentTimeMillis() - start; assertTrue(n == 0); assertTrue(Thread.currentThread().isInterrupted()); assertTrue(sel.isOpen()); diff --git a/test/lib/jdk/test/lib/thread/VThreadPinner.java b/test/lib/jdk/test/lib/thread/VThreadPinner.java new file mode 100644 index 00000000000..d84226c5e5c --- /dev/null +++ b/test/lib/jdk/test/lib/thread/VThreadPinner.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2023, 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. + */ + +package jdk.test.lib.thread; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.nio.file.Path; +import java.time.Duration; +import java.util.concurrent.atomic.AtomicReference; +import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable; + +/** + * Helper class to allow tests run a task in a virtual thread while pinning its carrier. + * + * It defines the {@code runPinned} method to run a task when holding a lock. + */ +public class VThreadPinner { + + /** + * Thread local with the task to run. + */ + private static final ThreadLocal TASK_RUNNER = new ThreadLocal<>(); + + /** + * Runs a task, capturing any exception or error thrown. + */ + private static class TaskRunner implements Runnable { + private final ThrowingRunnable task; + private Throwable throwable; + + TaskRunner(ThrowingRunnable task) { + this.task = task; + } + + @Override + public void run() { + try { + task.run(); + } catch (Throwable ex) { + throwable = ex; + } + } + + Throwable exception() { + return throwable; + } + } + + /** + * Runs the given task on a virtual thread pinned to its carrier. If called from a + * virtual thread then it invokes the task directly. + */ + public static void runPinned(ThrowingRunnable task) throws X { + if (!Thread.currentThread().isVirtual()) { + VThreadRunner.run(() -> runPinned(task)); + return; + } + var runner = new TaskRunner(task); + TASK_RUNNER.set(runner); + try { + synchronized (runner) { + runner.run(); + } + } catch (Throwable e) { + throw new RuntimeException(e); + } finally { + TASK_RUNNER.remove(); + } + Throwable ex = runner.exception(); + if (ex != null) { + if (ex instanceof RuntimeException e) + throw e; + if (ex instanceof Error e) + throw e; + throw (X) ex; + } + } + +} diff --git a/test/lib/jdk/test/lib/thread/VThreadRunner.java b/test/lib/jdk/test/lib/thread/VThreadRunner.java index 74158c89a14..ba69496a047 100644 --- a/test/lib/jdk/test/lib/thread/VThreadRunner.java +++ b/test/lib/jdk/test/lib/thread/VThreadRunner.java @@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicReference; /** - * Helper class to support tests running tasks a in virtual thread. + * Helper class to support tests running tasks in a virtual thread. */ public class VThreadRunner { private VThreadRunner() { } @@ -41,38 +41,31 @@ private VThreadRunner() { } public static final int NO_INHERIT_THREAD_LOCALS = 1 << 2; /** - * Represents a task that does not return a result but may throw - * an exception. + * Represents a task that does not return a result but may throw an exception. */ @FunctionalInterface - public interface ThrowingRunnable { - /** - * Runs this operation. - */ - void run() throws Exception; + public interface ThrowingRunnable { + void run() throws X; } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param name thread name, can be null * @param characteristics thread characteristics * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(String name, - int characteristics, - ThrowingRunnable task) throws Exception { - AtomicReference exc = new AtomicReference<>(); - Runnable target = () -> { + public static void run(String name, + int characteristics, + ThrowingRunnable task) throws X { + var throwableRef = new AtomicReference(); + Runnable target = () -> { try { task.run(); - } catch (Error e) { - exc.set(new RuntimeException(e)); - } catch (Exception e) { - exc.set(e); + } catch (Throwable ex) { + throwableRef.set(ex); } }; @@ -84,54 +77,59 @@ public static void run(String name, Thread thread = builder.start(target); // wait for thread to terminate - while (thread.join(Duration.ofSeconds(10)) == false) { - System.out.println("-- " + thread + " --"); - for (StackTraceElement e : thread.getStackTrace()) { - System.out.println(" " + e); + try { + while (thread.join(Duration.ofSeconds(10)) == false) { + System.out.println("-- " + thread + " --"); + for (StackTraceElement e : thread.getStackTrace()) { + System.out.println(" " + e); + } } + } catch (InterruptedException e) { + throw new RuntimeException(e); } - Exception e = exc.get(); - if (e != null) { - throw e; + Throwable ex = throwableRef.get(); + if (ex != null) { + if (ex instanceof RuntimeException e) + throw e; + if (ex instanceof Error e) + throw e; + throw (X) ex; } } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param name thread name, can be null * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(String name, ThrowingRunnable task) throws Exception { + public static void run(String name, ThrowingRunnable task) throws X { run(name, 0, task); } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param characteristics thread characteristics * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(int characteristics, ThrowingRunnable task) throws Exception { + public static void run(int characteristics, ThrowingRunnable task) throws X { run(null, characteristics, task); } /** * Run a task in a virtual thread and wait for it to terminate. * If the task completes with an exception then it is thrown by this method. - * If the task throws an Error then it is wrapped in an RuntimeException. * * @param task the task to run - * @throws Exception the exception thrown by the task + * @throws X the exception thrown by the task */ - public static void run(ThrowingRunnable task) throws Exception { + public static void run(ThrowingRunnable task) throws X { run(null, 0, task); } From 9c0e18c2bb1fb628bd0a3a1785ab63ed0b74719f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 08:11:01 +0000 Subject: [PATCH 222/298] 8320924: Improve heap dump performance by optimizing archived object checks Backport-of: f32ab8cc47c8a1b4887e9c7c86b145ce4b85c546 --- src/hotspot/share/oops/klass.cpp | 4 --- src/hotspot/share/oops/klass.inline.hpp | 4 +++ src/hotspot/share/services/heapDumper.cpp | 38 ++++++++++++----------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 4ebcc5329c0..c7c605aa157 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -61,10 +61,6 @@ void Klass::set_java_mirror(Handle m) { _java_mirror = class_loader_data()->add_handle(m); } -oop Klass::java_mirror_no_keepalive() const { - return _java_mirror.peek(); -} - bool Klass::is_cloneable() const { return _access_flags.is_cloneable_fast() || is_subtype_of(vmClasses::Cloneable_klass()); diff --git a/src/hotspot/share/oops/klass.inline.hpp b/src/hotspot/share/oops/klass.inline.hpp index af2480e149b..a72868a08d8 100644 --- a/src/hotspot/share/oops/klass.inline.hpp +++ b/src/hotspot/share/oops/klass.inline.hpp @@ -56,6 +56,10 @@ inline oop Klass::java_mirror() const { return _java_mirror.resolve(); } +inline oop Klass::java_mirror_no_keepalive() const { + return _java_mirror.peek(); +} + inline klassVtable Klass::vtable() const { return klassVtable(const_cast(this), start_of_vtable(), vtable_length() / vtableEntry::size()); } diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index 8f044ed427f..0f7c780035e 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -939,15 +939,30 @@ class DumperSupport : AllStatic { // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record static void end_of_dump(AbstractDumpWriter* writer); - static oop mask_dormant_archived_object(oop o) { - if (o != nullptr && o->klass()->java_mirror() == nullptr) { + static oop mask_dormant_archived_object(oop o, oop ref_obj) { + if (o != nullptr && o->klass()->java_mirror_no_keepalive() == nullptr) { // Ignore this object since the corresponding java mirror is not loaded. // Might be a dormant archive object. + report_dormant_archived_object(o, ref_obj); return nullptr; } else { return o; } } + + static void report_dormant_archived_object(oop o, oop ref_obj) { + if (log_is_enabled(Trace, cds, heap)) { + ResourceMark rm; + if (ref_obj != nullptr) { + log_trace(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)", + p2i(o), o->klass()->external_name(), + p2i(ref_obj), ref_obj->klass()->external_name()); + } else { + log_trace(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", + p2i(o), o->klass()->external_name()); + } + } + } }; // Hash table of klasses to the klass metadata. This should greatly improve the @@ -1135,13 +1150,7 @@ void DumperSupport::dump_field_value(AbstractDumpWriter* writer, char type, oop case JVM_SIGNATURE_CLASS : case JVM_SIGNATURE_ARRAY : { oop o = obj->obj_field_access(offset); - if (o != nullptr && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == nullptr) { - ResourceMark rm; - log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)", - p2i(o), o->klass()->external_name(), - p2i(obj), obj->klass()->external_name()); - } - o = mask_dormant_archived_object(o); + o = mask_dormant_archived_object(o, obj); assert(oopDesc::is_oop_or_null(o), "Expected an oop or nullptr at " PTR_FORMAT, p2i(o)); writer->write_objectID(o); break; @@ -1473,13 +1482,7 @@ void DumperSupport::dump_object_array(AbstractDumpWriter* writer, objArrayOop ar // [id]* elements for (int index = 0; index < length; index++) { oop o = array->obj_at(index); - if (o != nullptr && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == nullptr) { - ResourceMark rm; - log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)", - p2i(o), o->klass()->external_name(), - p2i(array), array->klass()->external_name()); - } - o = mask_dormant_archived_object(o); + o = mask_dormant_archived_object(o, array); writer->write_objectID(o); } @@ -1814,8 +1817,7 @@ void HeapObjectDumper::do_object(oop o) { } } - if (DumperSupport::mask_dormant_archived_object(o) == nullptr) { - log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", p2i(o), o->klass()->external_name()); + if (DumperSupport::mask_dormant_archived_object(o, nullptr) == nullptr) { return; } From 2626d73689da8be1cab566fe18d5196f9e79df3d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 08:11:14 +0000 Subject: [PATCH 223/298] 8327989: java/net/httpclient/ManyRequest.java should not use "localhost" in URIs Backport-of: da4dd7c008da4be54ee5f58d1ac19f440fd2a74e --- test/jdk/java/net/httpclient/ManyRequests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/net/httpclient/ManyRequests.java b/test/jdk/java/net/httpclient/ManyRequests.java index 8e3eb7eba94..89f26d3a761 100644 --- a/test/jdk/java/net/httpclient/ManyRequests.java +++ b/test/jdk/java/net/httpclient/ManyRequests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -187,7 +187,7 @@ static void test(HttpsServer server, HttpClient client) throws Exception { URI baseURI = URIBuilder.newBuilder() .scheme("https") - .host(InetAddress.getLoopbackAddress().getHostName()) + .loopback() .port(port) .path("/foo/x").build(); server.createContext("/foo", new TestEchoHandler()); From 68d0925b09ab69ca6a8777703bdd2840c1e49911 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 08:55:45 +0000 Subject: [PATCH 224/298] 8324933: ConcurrentHashTable::statistics_calculate synchronization is expensive Backport-of: 0e2fdc95ae47c11e6a1e47cdc6190268e29a9d9c --- .../utilities/concurrentHashTable.inline.hpp | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index 13c219da212..21277853089 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -1222,23 +1222,30 @@ template inline TableStatistics ConcurrentHashTable:: statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f) { + constexpr size_t batch_size = 128; NumberSeq summary; size_t literal_bytes = 0; InternalTable* table = get_table(); - for (size_t bucket_it = 0; bucket_it < table->_size; bucket_it++) { + size_t num_batches = table->_size / batch_size; + for (size_t batch_start = 0; batch_start < _table->_size; batch_start += batch_size) { + // We batch the use of ScopedCS here as it has been found to be quite expensive to + // invoke it for every single bucket. + size_t batch_end = MIN2(batch_start + batch_size, _table->_size); ScopedCS cs(thread, this); - size_t count = 0; - Bucket* bucket = table->get_bucket(bucket_it); - if (bucket->have_redirect() || bucket->is_locked()) { - continue; - } - Node* current_node = bucket->first(); - while (current_node != nullptr) { - ++count; - literal_bytes += vs_f(current_node->value()); - current_node = current_node->next(); + for (size_t bucket_it = batch_start; bucket_it < batch_end; bucket_it++) { + size_t count = 0; + Bucket* bucket = table->get_bucket(bucket_it); + if (bucket->have_redirect() || bucket->is_locked()) { + continue; + } + Node* current_node = bucket->first(); + while (current_node != nullptr) { + ++count; + literal_bytes += vs_f(current_node->value()); + current_node = current_node->next(); + } + summary.add((double)count); } - summary.add((double)count); } if (_stats_rate == nullptr) { From 2331bc75b02ddcc093ef5811a7452f9999b4c8d6 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 25 Apr 2024 09:30:25 +0000 Subject: [PATCH 225/298] 8329013: StackOverflowError when starting Apache Tomcat with signed jar Backport-of: 925d82931c09dc11ea5a3bc410ea5cfd67ee14aa --- .../jdk/internal/event/EventHelper.java | 35 +++++++--- .../logging/RecursiveEventHelper.java | 66 +++++++++++++++++++ 2 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 test/jdk/jdk/security/logging/RecursiveEventHelper.java diff --git a/src/java.base/share/classes/jdk/internal/event/EventHelper.java b/src/java.base/share/classes/jdk/internal/event/EventHelper.java index e890ad8dde0..4da2d5854cb 100644 --- a/src/java.base/share/classes/jdk/internal/event/EventHelper.java +++ b/src/java.base/share/classes/jdk/internal/event/EventHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -27,6 +27,7 @@ import jdk.internal.access.JavaUtilJarAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.ThreadTracker; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -133,6 +134,18 @@ private static String getDurationString(Instant start) { } } + private static class ThreadTrackHolder { + static final ThreadTracker TRACKER = new ThreadTracker(); + } + + private static Object tryBeginLookup() { + return ThreadTrackHolder.TRACKER.tryBegin(); + } + + private static void endLookup(Object key) { + ThreadTrackHolder.TRACKER.end(key); + } + /** * Helper to determine if security events are being logged * at a preconfigured logging level. The configuration value @@ -141,14 +154,20 @@ private static String getDurationString(Instant start) { * @return boolean indicating whether an event should be logged */ public static boolean isLoggingSecurity() { - // Avoid a bootstrap issue where the commitEvent attempts to - // trigger early loading of System Logger but where - // the verification process still has JarFiles locked - if (securityLogger == null && !JUJA.isInitializing()) { - LOGGER_HANDLE.compareAndSet( null, System.getLogger(SECURITY_LOGGER_NAME)); - loggingSecurity = securityLogger.isLoggable(LOG_LEVEL); + Object key; + // Avoid bootstrap issues where + // * commitEvent triggers early loading of System Logger but where + // the verification process still has JarFiles locked + // * the loading of the logging libraries involves recursive + // calls to security libraries triggering recursion + if (securityLogger == null && !JUJA.isInitializing() && (key = tryBeginLookup()) != null) { + try { + LOGGER_HANDLE.compareAndSet(null, System.getLogger(SECURITY_LOGGER_NAME)); + loggingSecurity = securityLogger.isLoggable(LOG_LEVEL); + } finally { + endLookup(key); + } } return loggingSecurity; } - } diff --git a/test/jdk/jdk/security/logging/RecursiveEventHelper.java b/test/jdk/jdk/security/logging/RecursiveEventHelper.java new file mode 100644 index 00000000000..936d01f8115 --- /dev/null +++ b/test/jdk/jdk/security/logging/RecursiveEventHelper.java @@ -0,0 +1,66 @@ +/* + * 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.util.logging.*; + +import jdk.internal.event.EventHelper; + +/* + * @test + * @bug 8329013 + * @summary StackOverflowError when starting Apache Tomcat with signed jar + * @modules java.base/jdk.internal.event:+open + * @run main/othervm -Xmx32m -Djava.util.logging.manager=RecursiveEventHelper RecursiveEventHelper + */ +public class RecursiveEventHelper extends LogManager { + // an extra check to ensure the custom manager is in use + static volatile boolean customMethodCalled; + + public static void main(String[] args) throws Exception { + String classname = System.getProperty("java.util.logging.manager"); + if (!classname.equals("RecursiveEventHelper")) { + throw new RuntimeException("java.util.logging.manager not set"); + } + + // this call will trigger initialization of logging framework + // which will call into our custom LogManager and use the + // custom getProperty method below. EventHelper.isLoggingSecurity() + // is also on the code path of original report and triggers + // similar recursion. + System.getLogger("testLogger"); + if (!customMethodCalled) { + throw new RuntimeException("Method not called"); + } + } + + @Override + public String getProperty(String p) { + // this call mimics issue reported in initial bug report where + // opening of a signed jar during System logger initialization triggered + // a recursive call (via EventHelper.isLoggingSecurity) back into + // logger API + EventHelper.isLoggingSecurity(); + customMethodCalled = true; + return super.getProperty(p); + } +} From 1d01cd7361141a389f076702d41dd3cc012827d3 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Fri, 26 Apr 2024 09:17:02 +0000 Subject: [PATCH 226/298] 8315889: Open source several Swing HTMLDocument related tests Backport-of: 8f46abc938ffe338e25d5fdbdcfa0aaa12edfa58 --- .../text/html/HTMLDocument/bug4226914.java | 52 ++++++++++++++ .../text/html/HTMLDocument/bug4251593.java | 64 +++++++++++++++++ .../text/html/HTMLDocument/bug4687405.java | 72 +++++++++++++++++++ .../text/html/HTMLEditorKit/bug4213373.java | 62 ++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java create mode 100644 test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java create mode 100644 test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java new file mode 100644 index 00000000000..8bfaae935a2 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.JEditorPane; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4226914 + * @summary Tests if HTMLDocument streaming is broken + */ + +public class bug4226914 { + + public static void main(String[] args) throws Exception { + ObjectOutputStream oos = null; + try { + JEditorPane jtp = new JEditorPane("text/html", ""); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(jtp.getDocument()); + oos.flush(); + baos.toByteArray(); + } finally { + if (oos != null) { + oos.close(); + } + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java new file mode 100644 index 00000000000..bdd51d68a2e --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1999, 2023, 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.ActionEvent; +import javax.swing.Action; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4251593 + * @summary Tests that hyperlinks can be inserted into JTextPane + * via InsertHTMLTextAction. + */ + +public class bug4251593 { + private static JTextPane editor; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + editor = new JTextPane(); + editor.setContentType("text/html"); + editor.setEditable(true); + + int beforeLen = editor.getDocument().getLength(); + + String href = "javasoft "; + Action a = new HTMLEditorKit.InsertHTMLTextAction("Tester", href, HTML.Tag.BODY, HTML.Tag.A); + a.actionPerformed(new ActionEvent(editor, 0, null)); + + int afterLen = editor.getDocument().getLength(); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if ((afterLen - beforeLen) < 8) { + throw new RuntimeException("Test Failed: link not inserted!!"); + } + }); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java new file mode 100644 index 00000000000..5e549477072 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.text.AttributeSet; +import javax.swing.text.View; +import javax.swing.text.html.CSS; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4687405 + * @summary Tests if HTMLDocument very first paragraph doesn't have top margin. + */ + +public class bug4687405 { + private static JEditorPane jep; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(bug4687405::createHTMLEditor); + Thread.sleep(200); + + SwingUtilities.invokeAndWait(bug4687405::testEditorPane); + Thread.sleep(500); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " Top margin present in HTMLDocument"); + } + } + + public static void createHTMLEditor() { + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + } + + private static void testEditorPane() { + View v = jep.getUI().getRootView(jep); + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + v = v.getView(n - 1); + } + AttributeSet attrs = v.getAttributes(); + String marginTop = attrs.getAttribute(CSS.Attribute.MARGIN_TOP).toString(); + // MARGIN_TOP of the very first paragraph of the default html + // document should be 0. + passed = "0".equals(marginTop); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java new file mode 100644 index 00000000000..621547faca5 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.text.html.HTMLEditorKit; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4213373 + * @summary Serialization bug on HTMLEditorKit. + */ + +public class bug4213373 { + + public static void main(String[] args) throws Exception { + HTMLEditorKit ekr = null; + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + HTMLEditorKit ekw = new HTMLEditorKit(); + oos = new ObjectOutputStream(baos); + oos.writeObject(ekw); + byte[] buf = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(buf); + ois = new ObjectInputStream(bais); + ekr = (HTMLEditorKit) ois.readObject(); + } finally { + if (oos != null) { + oos.close(); + } + if (ois != null) { + ois.close(); + } + } + } +} From 262cacb2385af4e0e2ee3a4e1f763b68e3101f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Arias=20de=20Reyna?= Date: Fri, 26 Apr 2024 11:14:49 +0000 Subject: [PATCH 227/298] 8320061: [nmt] Multiple issues with peak accounting Reviewed-by: shade, stuefe Backport-of: dc256fbc6490f8163adb286dbb7380c10e5e1e06 --- src/hotspot/share/services/memReporter.cpp | 155 ++++++++++-------- .../share/services/virtualMemoryTracker.cpp | 2 - .../share/services/virtualMemoryTracker.hpp | 12 +- .../jtreg/runtime/NMT/HugeArenaTracking.java | 74 ++++++--- .../runtime/NMT/MallocRoundingReportTest.java | 29 ++-- .../jtreg/runtime/NMT/MallocStressTest.java | 5 +- .../jtreg/runtime/NMT/MallocTestType.java | 40 +++-- .../runtime/NMT/MallocTrackingVerify.java | 26 ++- .../jtreg/runtime/NMT/NMTTestUtils.java | 70 ++++++++ .../runtime/NMT/ThreadedMallocTestType.java | 26 ++- .../NMT/ThreadedVirtualAllocTestType.java | 32 ++-- .../runtime/NMT/VirtualAllocCommitMerge.java | 118 +++++++------ .../VirtualAllocCommitUncommitRecommit.java | 54 +++--- .../runtime/NMT/VirtualAllocTestType.java | 128 ++++++++++++--- .../jdk/test/lib/process/OutputAnalyzer.java | 76 +++++++++ 15 files changed, 551 insertions(+), 296 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/NMT/NMTTestUtils.java diff --git a/src/hotspot/share/services/memReporter.cpp b/src/hotspot/share/services/memReporter.cpp index dcad285c63a..1fa0438e30e 100644 --- a/src/hotspot/share/services/memReporter.cpp +++ b/src/hotspot/share/services/memReporter.cpp @@ -55,7 +55,7 @@ void MemReporterBase::print_total(size_t reserved, size_t committed, size_t peak output()->print("reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s", amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); if (peak != 0) { - output()->print(", largest_committed=" SIZE_FORMAT "%s", amount_in_current_scale(peak), scale); + output()->print(", peak=" SIZE_FORMAT "%s", amount_in_current_scale(peak), scale); } } @@ -93,9 +93,15 @@ void MemReporterBase::print_malloc(const MemoryCounter* c, MEMFLAGS flag) const } void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed, size_t peak) const { + outputStream* out = output(); const char* scale = current_scale(); - output()->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s, largest_committed=" SIZE_FORMAT "%s)", - amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale, amount_in_current_scale(peak), scale); + out->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s, ", + amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); + if (peak == committed) { + out->print_raw("at peak)"); + } else { + out->print("peak=" SIZE_FORMAT "%s)", amount_in_current_scale(peak), scale); + } } void MemReporterBase::print_malloc_line(const MemoryCounter* c) const { @@ -204,74 +210,79 @@ void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag, committed_amount += _malloc_snapshot->malloc_overhead(); } - if (amount_in_current_scale(reserved_amount) > 0) { - outputStream* out = output(); - const char* scale = current_scale(); - out->print("-%26s (", NMTUtil::flag_to_name(flag)); - print_total(reserved_amount, committed_amount); + // Omit printing if the current reserved value as well as all historical peaks (malloc, mmap committed, arena) + // fall below scale threshold + const size_t pk_vm = virtual_memory->peak_size(); + const size_t pk_malloc = malloc_memory->malloc_peak_size(); + const size_t pk_arena = malloc_memory->arena_peak_size(); + + if (amount_in_current_scale(MAX4(reserved_amount, pk_vm, pk_malloc, pk_arena)) == 0) { + return; + } + + outputStream* out = output(); + const char* scale = current_scale(); + out->print("-%26s (", NMTUtil::flag_to_name(flag)); + print_total(reserved_amount, committed_amount); #if INCLUDE_CDS - if (flag == mtClassShared) { - size_t read_only_bytes = FileMapInfo::readonly_total(); - output()->print(", readonly=" SIZE_FORMAT "%s", - amount_in_current_scale(read_only_bytes), scale); - } + if (flag == mtClassShared) { + size_t read_only_bytes = FileMapInfo::readonly_total(); + output()->print(", readonly=" SIZE_FORMAT "%s", + amount_in_current_scale(read_only_bytes), scale); + } #endif - out->print_cr(")"); + out->print_cr(")"); - if (flag == mtClass) { - // report class count - out->print_cr("%27s (classes #" SIZE_FORMAT ")", - " ", (_instance_class_count + _array_class_count)); - out->print_cr("%27s ( instance classes #" SIZE_FORMAT ", array classes #" SIZE_FORMAT ")", - " ", _instance_class_count, _array_class_count); - } else if (flag == mtThread) { - if (ThreadStackTracker::track_as_vm()) { - const VirtualMemory* thread_stack_usage = - _vm_snapshot->by_type(mtThreadStack); - // report thread count - out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", ThreadStackTracker::thread_count()); - out->print("%27s (stack: ", " "); - print_total(thread_stack_usage->reserved(), thread_stack_usage->committed(), thread_stack_usage->peak_size()); - } else { - MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack); - const char* scale = current_scale(); - // report thread count - out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", thread_stack_memory->malloc_count()); - out->print("%27s (Stack: " SIZE_FORMAT "%s", " ", - amount_in_current_scale(thread_stack_memory->malloc_size()), scale); - } - out->print_cr(")"); + if (flag == mtClass) { + // report class count + out->print_cr("%27s (classes #" SIZE_FORMAT ")", + " ", (_instance_class_count + _array_class_count)); + out->print_cr("%27s ( instance classes #" SIZE_FORMAT ", array classes #" SIZE_FORMAT ")", + " ", _instance_class_count, _array_class_count); + } else if (flag == mtThread) { + if (ThreadStackTracker::track_as_vm()) { + const VirtualMemory* thread_stack_usage = + _vm_snapshot->by_type(mtThreadStack); + // report thread count + out->print_cr("%27s (threads #" SIZE_FORMAT ")", " ", ThreadStackTracker::thread_count()); + out->print("%27s (stack: ", " "); + print_total(thread_stack_usage->reserved(), thread_stack_usage->committed(), thread_stack_usage->peak_size()); + } else { + MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack); + const char* scale = current_scale(); + // report thread count + out->print_cr("%27s (threads #" SIZE_FORMAT ")", " ", thread_stack_memory->malloc_count()); + out->print("%27s (Stack: " SIZE_FORMAT "%s", " ", + amount_in_current_scale(thread_stack_memory->malloc_size()), scale); } + out->print_cr(")"); + } - // report malloc'd memory - if (amount_in_current_scale(malloc_memory->malloc_size()) > 0 - || amount_in_current_scale(malloc_memory->malloc_peak_size()) > 0) { - print_malloc_line(malloc_memory->malloc_counter()); - } + // report malloc'd memory + if (amount_in_current_scale(MAX2(malloc_memory->malloc_size(), pk_malloc)) > 0) { + print_malloc_line(malloc_memory->malloc_counter()); + } - if (amount_in_current_scale(virtual_memory->reserved()) > 0 - DEBUG_ONLY(|| amount_in_current_scale(virtual_memory->peak_size()) > 0)) { - print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed(), virtual_memory->peak_size()); - } + if (amount_in_current_scale(MAX2(virtual_memory->reserved(), pk_vm)) > 0) { + print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed(), virtual_memory->peak_size()); + } - if (amount_in_current_scale(malloc_memory->arena_size()) > 0 - DEBUG_ONLY(|| amount_in_current_scale(malloc_memory->arena_peak_size()) > 0)) { - print_arena_line(malloc_memory->arena_counter()); - } + if (amount_in_current_scale(MAX2(malloc_memory->arena_size(), pk_arena)) > 0) { + print_arena_line(malloc_memory->arena_counter()); + } - if (flag == mtNMT && - amount_in_current_scale(_malloc_snapshot->malloc_overhead()) > 0) { - out->print_cr("%27s (tracking overhead=" SIZE_FORMAT "%s)", " ", - amount_in_current_scale(_malloc_snapshot->malloc_overhead()), scale); - } else if (flag == mtClass) { - // Metadata information - report_metadata(Metaspace::NonClassType); - if (Metaspace::using_class_space()) { - report_metadata(Metaspace::ClassType); - } + if (flag == mtNMT && + amount_in_current_scale(_malloc_snapshot->malloc_overhead()) > 0) { + out->print_cr("%27s (tracking overhead=" SIZE_FORMAT "%s)", " ", + amount_in_current_scale(_malloc_snapshot->malloc_overhead()), scale); + } else if (flag == mtClass) { + // Metadata information + report_metadata(Metaspace::NonClassType); + if (Metaspace::using_class_space()) { + report_metadata(Metaspace::ClassType); } - out->print_cr(" "); } + out->print_cr(" "); } void MemSummaryReporter::report_metadata(Metaspace::MetadataType type) const { @@ -321,9 +332,8 @@ int MemDetailReporter::report_malloc_sites() { const MallocSite* malloc_site; int num_omitted = 0; while ((malloc_site = malloc_itr.next()) != nullptr) { - // Don't report if site has never allocated less than one unit of whatever our scale is - if (scale() > 1 && amount_in_current_scale(malloc_site->size()) == 0 - DEBUG_ONLY(&& amount_in_current_scale(malloc_site->peak_size()) == 0)) { + // Omit printing if the current value and the historic peak value both fall below the reporting scale threshold + if (amount_in_current_scale(MAX2(malloc_site->size(), malloc_site->peak_size())) == 0) { num_omitted ++; continue; } @@ -353,8 +363,10 @@ int MemDetailReporter::report_virtual_memory_allocation_sites() { if (virtual_memory_site->reserved() == 0) { continue; } - // Don't report if site has reserved less than one unit of whatever our scale is - if (scale() > 1 && amount_in_current_scale(virtual_memory_site->reserved()) == 0) { + // Omit printing if the current value and the historic peak value both fall below the + // reporting scale threshold + if (amount_in_current_scale(MAX2(virtual_memory_site->reserved(), + virtual_memory_site->peak_size())) == 0) { num_omitted++; continue; } @@ -386,7 +398,16 @@ void MemDetailReporter::report_virtual_memory_map() { void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion* reserved_rgn) { assert(reserved_rgn != nullptr, "null pointer"); - // Don't report if size is too small + // We don't bother about reporting peaks here. + // That is because peaks - in the context of virtual memory, peak of committed areas - make little sense + // when we report *by region*, which are identified by their location in memory. There is a philosophical + // question about identity here: e.g. a committed region that has been split into three regions by + // uncommitting a middle section of it, should that still count as "having peaked" before the split? If + // yes, which of the three new regions would be the spiritual successor? Rather than introducing more + // complexity, we avoid printing peaks altogether. Note that peaks should still be printed when reporting + // usage *by callsite*. + + // Don't report if size is too small. if (amount_in_current_scale(reserved_rgn->size()) == 0) return; outputStream* out = output(); diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index ebb32ecbeeb..4e94a43c117 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -34,7 +34,6 @@ size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)]; -#ifdef ASSERT void VirtualMemory::update_peak(size_t size) { size_t peak_sz = peak_size(); while (peak_sz < size) { @@ -46,7 +45,6 @@ void VirtualMemory::update_peak(size_t size) { } } } -#endif // ASSERT void VirtualMemorySummary::initialize() { assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index 41af085e248..3839df113d7 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -43,21 +43,18 @@ class VirtualMemory { size_t _reserved; size_t _committed; -#ifdef ASSERT volatile size_t _peak_size; void update_peak(size_t size); -#endif // ASSERT public: - VirtualMemory() : _reserved(0), _committed(0) { - DEBUG_ONLY(_peak_size = 0;) - } + VirtualMemory() : _reserved(0), _committed(0), _peak_size(0) {} inline void reserve_memory(size_t sz) { _reserved += sz; } inline void commit_memory (size_t sz) { _committed += sz; DEBUG_ONLY(update_peak(sz);) assert(_committed <= _reserved, "Sanity check"); + update_peak(_committed); } inline void release_memory (size_t sz) { @@ -73,7 +70,7 @@ class VirtualMemory { inline size_t reserved() const { return _reserved; } inline size_t committed() const { return _committed; } inline size_t peak_size() const { - return DEBUG_ONLY(Atomic::load(&_peak_size)) NOT_DEBUG(0); + return Atomic::load(&_peak_size); } }; @@ -86,10 +83,9 @@ class VirtualMemoryAllocationSite : public AllocationSite { inline void reserve_memory(size_t sz) { _c.reserve_memory(sz); } inline void commit_memory (size_t sz) { _c.commit_memory(sz); } - inline void uncommit_memory(size_t sz) { _c.uncommit_memory(sz); } - inline void release_memory(size_t sz) { _c.release_memory(sz); } inline size_t reserved() const { return _c.reserved(); } inline size_t committed() const { return _c.committed(); } + inline size_t peak_size() const { return _c.peak_size(); } }; class VirtualMemorySummary; diff --git a/test/hotspot/jtreg/runtime/NMT/HugeArenaTracking.java b/test/hotspot/jtreg/runtime/NMT/HugeArenaTracking.java index e5a38114f6c..adccbd01170 100644 --- a/test/hotspot/jtreg/runtime/NMT/HugeArenaTracking.java +++ b/test/hotspot/jtreg/runtime/NMT/HugeArenaTracking.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2023, Red Hat, Inc. 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 @@ -31,59 +31,81 @@ * java.management * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail HugeArenaTracking + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary HugeArenaTracking */ import java.util.Random; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.Utils; import jdk.test.whitebox.WhiteBox; public class HugeArenaTracking { - private static final long GB = 1024 * 1024 * 1024; + private static final long MB = 1024 * 1024; + private static final long GB = MB * 1024; public static void main(String args[]) throws Exception { - OutputAnalyzer output; final WhiteBox wb = WhiteBox.getWhiteBox(); - // Grab my own PID - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - long arena1 = wb.NMTNewArena(1024); long arena2 = wb.NMTNewArena(1024); - // Run 'jcmd VM.native_memory summary' - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=2KB, committed=2KB)"); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=K" }, + new String[] { "Test (reserved=2KB, committed=2KB)", + "(arena=2KB #2) (at peak)" }); Random rand = Utils.getRandomInstance(); // Allocate 2GB+ from arena long total = 0; while (total < 2 * GB) { - // Cap to 10M - long inc = rand.nextInt(10 * 1024 * 1024); - wb.NMTArenaMalloc(arena1, inc); - total += inc; + wb.NMTArenaMalloc(arena1, MB); + total += MB; } - ProcessBuilder pb2 = new ProcessBuilder(); - // Run 'jcmd VM.native_memory summary' - pb2.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=GB"}); - output = new OutputAnalyzer(pb2.start()); - output.shouldContain("Test (reserved=2GB, committed=2GB)"); + // run a report at GB level. We should see our allocations; since they are rounded + // to GB, we expect an exact output match + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=G" }, + new String[] { "Test (reserved=2GB, committed=2GB)", + "(arena=2GB #2) (at peak)" }); + + // Repeat at MB level; we expect the same behavior + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=M" }, + new String[] { "Test (reserved=2048MB, committed=2048MB)", + "(arena=2048MB #2) (at peak)" }); wb.NMTFreeArena(arena1); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=1KB, committed=1KB)"); + // Repeat report at GB level. Reserved should be 0 now. Current usage is 1KB, since arena2 is left, but that + // is below GB scale threshold, so should show up as 0. + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=G" }, + new String[] { "Test (reserved=0GB, committed=0GB)", + "(arena=0GB #1) (peak=2GB #2)" }); + + // Same, for MB scale + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=M" }, + new String[] { "Test (reserved=0MB, committed=0MB)", + "(arena=0MB #1) (peak=2048MB #2)" }); + + // At KB level we should see the remaining 1KB. Note that we refrain from testing peak here + // since the number gets fuzzy: it depends on the size of the initially allocated chunk. At MB + // and GB scale, these differences don't matter. + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=K" }, + new String[] { "Test (reserved=1KB, committed=1KB)", + "(arena=1KB #1) (peak=" }); + wb.NMTFreeArena(arena2); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved"); + // Everything free'd, current usage 0, peak should be preserved. + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[] { "scale=G" }, + new String[] { "Test (reserved=0GB, committed=0GB)", + "(arena=0GB #0) (peak=2GB #2)" }); } } diff --git a/test/hotspot/jtreg/runtime/NMT/MallocRoundingReportTest.java b/test/hotspot/jtreg/runtime/NMT/MallocRoundingReportTest.java index 653f8354e65..30a03f973bf 100644 --- a/test/hotspot/jtreg/runtime/NMT/MallocRoundingReportTest.java +++ b/test/hotspot/jtreg/runtime/NMT/MallocRoundingReportTest.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -33,23 +34,14 @@ * */ -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; - import jdk.test.whitebox.WhiteBox; public class MallocRoundingReportTest { private static long K = 1024; public static void main(String args[]) throws Exception { - OutputAnalyzer output; WhiteBox wb = WhiteBox.getWhiteBox(); - // Grab my own PID - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - long[] additionalBytes = {0, 1, 512, 650}; long[] kByteSize = {1024, 2048}; long mallocd_total = 0; @@ -63,17 +55,18 @@ public static void main(String args[]) throws Exception { mallocd_total = wb.NMTMalloc(curKB); // Run 'jcmd VM.native_memory summary', check for expected output // NMT does not track memory allocations less than 1KB, and rounds to the nearest KB - String expectedOut = ("Test (reserved=" + numKB + "KB, committed=" + numKB + "KB)"); - - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" }); - output = new OutputAnalyzer(pb.start()); - output.shouldContain(expectedOut); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=" + numKB + "KB, committed=" + numKB + "KB)", + "(malloc=" + numKB + "KB #1) (at peak)" + ); wb.NMTFree(mallocd_total); + // Run 'jcmd VM.native_memory summary', check for expected output - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" }); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=0KB, committed=0KB)", + "(malloc=0KB) (peak=" + numKB + "KB #1)" + ); } } } diff --git a/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java b/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java index 55531a68b96..6af14268c7e 100644 --- a/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java +++ b/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -130,7 +131,7 @@ public static void main(String args[]) throws Exception { // All test memory allocated should be released output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + output.shouldContain("Test (reserved=0KB, committed=0KB)"); // Verify that tracking level has not been downgraded pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"}); diff --git a/test/hotspot/jtreg/runtime/NMT/MallocTestType.java b/test/hotspot/jtreg/runtime/NMT/MallocTestType.java index e091ab0f7a7..67df864e7b4 100644 --- a/test/hotspot/jtreg/runtime/NMT/MallocTestType.java +++ b/test/hotspot/jtreg/runtime/NMT/MallocTestType.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -32,37 +33,34 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTestType */ -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.whitebox.WhiteBox; public class MallocTestType { public static void main(String args[]) throws Exception { - OutputAnalyzer output; WhiteBox wb = WhiteBox.getWhiteBox(); - // Grab my own PID - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - // Use WB API to alloc and free with the mtTest type - long memAlloc3 = wb.NMTMalloc(128 * 1024); - long memAlloc2 = wb.NMTMalloc(256 * 1024); - wb.NMTFree(memAlloc3); - long memAlloc1 = wb.NMTMalloc(512 * 1024); - wb.NMTFree(memAlloc2); + long memAlloc3 = wb.NMTMalloc(128 * 1024); // current +128K #1 peak +128K #1 + long memAlloc2 = wb.NMTMalloc(256 * 1024); // current +384K #2 peak +384K #2 + + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[]{"Test (reserved=384KB, committed=384KB)", + "(malloc=384KB #2) (at peak)"}); + + wb.NMTFree(memAlloc3); // current +256K #1 peak +384K #2 + long memAlloc1 = wb.NMTMalloc(512 * 1024); // current +768K #2 peak +768K #2 + wb.NMTFree(memAlloc2); // current +512K #1 peak +768K #2 - // Run 'jcmd VM.native_memory summary' - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=512KB, committed=512KB)"); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[]{"Test (reserved=512KB, committed=512KB)", + "(malloc=512KB #1) (peak=768KB #2)"}); // Free the memory allocated by NMTAllocTest - wb.NMTFree(memAlloc1); + wb.NMTFree(memAlloc1); // current 0K #0 peak +768K #2 - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + new String[]{"Test (reserved=0KB, committed=0KB)", + "(malloc=0KB) (peak=768KB #2)"}); } } diff --git a/test/hotspot/jtreg/runtime/NMT/MallocTrackingVerify.java b/test/hotspot/jtreg/runtime/NMT/MallocTrackingVerify.java index f89f15a764e..0c08e07fd25 100644 --- a/test/hotspot/jtreg/runtime/NMT/MallocTrackingVerify.java +++ b/test/hotspot/jtreg/runtime/NMT/MallocTrackingVerify.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -31,7 +32,7 @@ * java.management * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary MallocTrackingVerify * */ @@ -53,11 +54,6 @@ public class MallocTrackingVerify { public static WhiteBox wb = WhiteBox.getWhiteBox(); public static void main(String args[]) throws Exception { - OutputAnalyzer output; - - // Grab my own PID - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); Random random = Utils.getRandomInstance(); // Allocate small amounts of memory with random pseudo call stack @@ -74,9 +70,10 @@ public static void main(String args[]) throws Exception { } } - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" }); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4KB, committed=4KB)"); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=4KB, committed=4KB)", + "(malloc=4KB #" + mallocd_memory.size() + ") (at peak)" + ); // Free for (MallocMemory mem : mallocd_memory) { @@ -84,10 +81,11 @@ public static void main(String args[]) throws Exception { } // Run 'jcmd VM.native_memory summary', check for expected output - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, - "VM.native_memory", "summary" }); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=0KB, committed=0KB)", + "(malloc=0KB) (peak=4KB #" + + mallocd_memory.size() + ")" + ); + } static class MallocMemory { diff --git a/test/hotspot/jtreg/runtime/NMT/NMTTestUtils.java b/test/hotspot/jtreg/runtime/NMT/NMTTestUtils.java new file mode 100644 index 00000000000..6cb0d727328 --- /dev/null +++ b/test/hotspot/jtreg/runtime/NMT/NMTTestUtils.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 Red Hat, Inc. 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 jdk.test.lib.JDKToolFinder; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class NMTTestUtils { + + public static OutputAnalyzer startJcmdVMNativeMemory(String... additional_args) throws Exception { + if (additional_args == null) { + additional_args = new String[] {}; + } + String fullargs[] = new String[3 + additional_args.length]; + fullargs[0] = JDKToolFinder.getJDKTool("jcmd"); + fullargs[1] = Long.toString(ProcessTools.getProcessId()); + fullargs[2] = "VM.native_memory"; + System.arraycopy(additional_args, 0, fullargs, 3, additional_args.length); + ProcessBuilder pb = new ProcessBuilder(); + pb.command(fullargs); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + return output; + } + + public static OutputAnalyzer startJcmdVMNativeMemoryDetail(String... additional_args) throws Exception { + return startJcmdVMNativeMemory("detail"); + } + + public static void runJcmdSummaryReportAndCheckOutput(String[] additional_args, String[] pattern, boolean verbose) throws Exception { + OutputAnalyzer output = startJcmdVMNativeMemory(additional_args); + output.stdoutShouldContainMultiLinePattern(pattern, true); + } + + public static void runJcmdSummaryReportAndCheckOutput(String[] additional_args, String[] pattern) throws Exception { + runJcmdSummaryReportAndCheckOutput(additional_args, pattern, true); + } + + public static void runJcmdSummaryReportAndCheckOutput(String... pattern) throws Exception { + runJcmdSummaryReportAndCheckOutput(null, pattern, true); + } + + public static void checkReservedCommittedSummary(OutputAnalyzer output, long reservedKB, long committedKB, long peakKB) { + String peakString = (committedKB == peakKB) ? "at peak" : "peak=" + peakKB + "KB"; + output.stdoutShouldContainMultiLinePattern( + "Test (reserved=" + reservedKB + "KB, committed=" + committedKB + "KB)", + "(mmap: reserved=" + reservedKB + "KB, committed=" + committedKB + "KB, " + peakString + ")" + ); + } +} diff --git a/test/hotspot/jtreg/runtime/NMT/ThreadedMallocTestType.java b/test/hotspot/jtreg/runtime/NMT/ThreadedMallocTestType.java index 2b1faf9fb43..290984c4185 100644 --- a/test/hotspot/jtreg/runtime/NMT/ThreadedMallocTestType.java +++ b/test/hotspot/jtreg/runtime/NMT/ThreadedMallocTestType.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -28,12 +29,9 @@ * java.management * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ThreadedMallocTestType + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary ThreadedMallocTestType */ -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.whitebox.WhiteBox; public class ThreadedMallocTestType { @@ -42,13 +40,8 @@ public class ThreadedMallocTestType { public static long memAlloc3; public static void main(String args[]) throws Exception { - OutputAnalyzer output; final WhiteBox wb = WhiteBox.getWhiteBox(); - // Grab my own PID - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - Thread allocThread = new Thread() { public void run() { // Alloc memory using the WB api @@ -66,9 +59,10 @@ public void run() { System.out.println("memAlloc3:"+memAlloc3); // Run 'jcmd VM.native_memory summary' - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=896KB, committed=896KB)"); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=896KB, committed=896KB)", + "(malloc=896KB #3) (at peak)" + ); Thread freeThread = new Thread() { public void run() { @@ -82,7 +76,9 @@ public void run() { freeThread.start(); freeThread.join(); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + NMTTestUtils.runJcmdSummaryReportAndCheckOutput( + "Test (reserved=0KB, committed=0KB)", + "(malloc=0KB) (peak=896KB #3)" + ); } } diff --git a/test/hotspot/jtreg/runtime/NMT/ThreadedVirtualAllocTestType.java b/test/hotspot/jtreg/runtime/NMT/ThreadedVirtualAllocTestType.java index 4bc6ffc90cc..60a493ea728 100644 --- a/test/hotspot/jtreg/runtime/NMT/ThreadedVirtualAllocTestType.java +++ b/test/hotspot/jtreg/runtime/NMT/ThreadedVirtualAllocTestType.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. 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 @@ -31,9 +32,7 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ThreadedVirtualAllocTestType */ -import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.whitebox.WhiteBox; public class ThreadedVirtualAllocTestType { @@ -45,8 +44,6 @@ public class ThreadedVirtualAllocTestType { public static void main(String args[]) throws Exception { OutputAnalyzer output; - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); Thread reserveThread = new Thread() { public void run() { @@ -56,9 +53,8 @@ public void run() { reserveThread.start(); reserveThread.join(); - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"}); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=512KB, committed=0KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output,512, 0); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 512KB for Test"); Thread commitThread = new Thread() { @@ -69,8 +65,8 @@ public void run() { commitThread.start(); commitThread.join(); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=512KB, committed=128KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output,512, 128); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB"); Thread uncommitThread = new Thread() { @@ -81,7 +77,8 @@ public void run() { uncommitThread.start(); uncommitThread.join(); - output = new OutputAnalyzer(pb.start()); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output,512, 0); output.shouldContain("Test (reserved=512KB, committed=0KB)"); output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed"); @@ -93,9 +90,18 @@ public void run() { releaseThread.start(); releaseThread.join(); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output,0, 0); output.shouldNotContain("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved"); } + static long peakKB = 0; + + public static void checkReservedCommittedSummary(OutputAnalyzer output, long reservedKB, long committedKB) { + if (committedKB > peakKB) { + peakKB = committedKB; + } + NMTTestUtils.checkReservedCommittedSummary(output, reservedKB, committedKB, peakKB); + } + } diff --git a/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java index 9cc8c39d897..4d691eb920a 100644 --- a/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java +++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java @@ -36,9 +36,7 @@ * */ -import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.lib.Platform; import jdk.test.whitebox.WhiteBox; @@ -53,16 +51,10 @@ public static void main(String args[]) throws Exception { long reserveSize = 4 * 1024 * 1024; // 4096KB long addr; - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - // reserve addr = wb.NMTReserveMemory(reserveSize); - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, - "VM.native_memory", "detail" }); - - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemory("detail"); + checkReservedCommittedSummary(output, 4096, 0); checkReserved(output, addr, reserveSize, "4096KB"); long addrA = addr + (0 * commitSize); @@ -75,8 +67,8 @@ public static void main(String args[]) throws Exception { // commit overlapping ABC, A, B, C wb.NMTCommitMemory(addrA, 3 * commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -84,8 +76,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -93,16 +85,16 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); wb.NMTCommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -110,8 +102,8 @@ public static void main(String args[]) throws Exception { // uncommit wb.NMTUncommitMemory(addrA, 3 * commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } // Test discontigous areas @@ -121,8 +113,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrC, commitSize); wb.NMTCommitMemory(addrE, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, commitSize, "128KB"); @@ -134,8 +126,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrC, commitSize); wb.NMTUncommitMemory(addrE, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } // Test contiguous areas @@ -144,8 +136,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrA, commitSize); wb.NMTCommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "256KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 256); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 2 * commitSize, "256KB"); @@ -154,8 +146,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrA, commitSize); wb.NMTUncommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -163,8 +155,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrB, commitSize); wb.NMTCommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "256KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 256); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 2 * commitSize, "256KB"); @@ -173,8 +165,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrB, commitSize); wb.NMTUncommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -183,8 +175,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrB, commitSize); wb.NMTCommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -194,8 +186,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrB, commitSize); wb.NMTUncommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -204,8 +196,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrC, commitSize); wb.NMTCommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -215,8 +207,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrC, commitSize); wb.NMTUncommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -225,8 +217,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrA, commitSize); wb.NMTCommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -236,8 +228,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrA, commitSize); wb.NMTUncommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -246,8 +238,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrC, commitSize); wb.NMTCommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -257,8 +249,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrC, commitSize); wb.NMTUncommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -267,8 +259,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrA, commitSize); wb.NMTCommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -278,8 +270,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrA, commitSize); wb.NMTUncommitMemory(addrB, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } { @@ -288,8 +280,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrB, commitSize); wb.NMTCommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "384KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); checkReserved(output, addr, reserveSize, "4096KB"); checkCommitted(output, addrA, 3 * commitSize, "384KB"); @@ -299,20 +291,26 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrB, commitSize); wb.NMTUncommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - checkReservedCommittedSummary(output, "4096KB", "0KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); } // release wb.NMTReleaseMemory(addr, reserveSize); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 0, 0); output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); } - public static void checkReservedCommittedSummary(OutputAnalyzer output, String reservedString, String committedString) { - output.shouldContain("Test (reserved=" + reservedString + ", committed=" + committedString + ")"); + // running peak counter + static long peakKB = 0; + + public static void checkReservedCommittedSummary(OutputAnalyzer output, long reservedKB, long committedKB) { + if (committedKB > peakKB) { + peakKB = committedKB; + } + NMTTestUtils.checkReservedCommittedSummary(output, reservedKB, committedKB, peakKB); } public static void checkReserved(OutputAnalyzer output, long addr, long size, String sizeString) { diff --git a/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitUncommitRecommit.java b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitUncommitRecommit.java index bfa4de6e0c2..ef6ee6f8838 100644 --- a/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitUncommitRecommit.java +++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitUncommitRecommit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -33,10 +33,7 @@ * */ -import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; - import jdk.test.whitebox.WhiteBox; public class VirtualAllocCommitUncommitRecommit { @@ -49,16 +46,10 @@ public static void main(String args[]) throws Exception { long reserveSize = 4 * 1024 * 1024; // 4096KB long addr; - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); - // reserve addr = wb.NMTReserveMemory(reserveSize); - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, - "VM.native_memory", "detail" }); - - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=0KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); @@ -76,8 +67,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrC, commitSize); wb.NMTCommitMemory(addrD, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=512KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 512); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) @@ -86,9 +77,8 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrB, commitSize); wb.NMTUncommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=256KB)"); - + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 256); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); @@ -97,8 +87,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrE, commitSize); wb.NMTCommitMemory(addrF, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=512KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 512); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); @@ -106,8 +96,8 @@ public static void main(String args[]) throws Exception { // uncommit A wb.NMTUncommitMemory(addrA, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=384KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 384); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); @@ -117,8 +107,8 @@ public static void main(String args[]) throws Exception { wb.NMTCommitMemory(addrB, commitSize); wb.NMTCommitMemory(addrC, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=768KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 768); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); @@ -131,17 +121,27 @@ public static void main(String args[]) throws Exception { wb.NMTUncommitMemory(addrE, commitSize); wb.NMTUncommitMemory(addrF, commitSize); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=4096KB, committed=0KB)"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 4096, 0); output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); // release wb.NMTReleaseMemory(addr, reserveSize); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 0, 0); output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test"); } + + // running peak counter + static long peakKB = 0; + + public static void checkReservedCommittedSummary(OutputAnalyzer output, long reservedKB, long committedKB) { + if (committedKB > peakKB) { + peakKB = committedKB; + } + NMTTestUtils.checkReservedCommittedSummary(output, reservedKB, committedKB, peakKB); + } } diff --git a/test/hotspot/jtreg/runtime/NMT/VirtualAllocTestType.java b/test/hotspot/jtreg/runtime/NMT/VirtualAllocTestType.java index 081ba6aafb6..f4321e80b22 100644 --- a/test/hotspot/jtreg/runtime/NMT/VirtualAllocTestType.java +++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocTestType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -32,9 +32,7 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocTestType */ -import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.JDKToolFinder; import jdk.test.whitebox.WhiteBox; public class VirtualAllocTestType { @@ -44,36 +42,120 @@ public static void main(String args[]) throws Exception { OutputAnalyzer output; long commitSize = 128 * 1024; long reserveSize = 256 * 1024; - long addr; + long addr1, addr2; - String pid = Long.toString(ProcessTools.getProcessId()); - ProcessBuilder pb = new ProcessBuilder(); + String info = "start"; - addr = wb.NMTReserveMemory(reserveSize); - pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"}); + try { + // ------ + // Reserve first mapping + addr1 = wb.NMTReserveMemory(reserveSize); + info = "reserve 1: addr1=" + addr1; - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=256KB, committed=0KB)"); - output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 256KB for Test"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 256, 0); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); - wb.NMTCommitMemory(addr, commitSize); + // ------ + // Reserve second mapping + addr2 = wb.NMTReserveMemory(reserveSize); + info = "reserve 2: addr2=" + addr2; + // If the second mapping happens to be adjacent to the first mapping, reserve another mapping and release the second mapping; for + // this test, we want to see two disjunct mappings. + if (addr2 == addr1 + reserveSize) { + long tmp = wb.NMTReserveMemory(reserveSize); + wb.NMTReleaseMemory(addr2, reserveSize); + addr2 = tmp; + } - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=256KB, committed=128KB)"); - output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB"); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 512, 0); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); - wb.NMTUncommitMemory(addr, commitSize); + // ------ + // Now commit the first mapping + wb.NMTCommitMemory(addr1, commitSize); + info = "commit 1"; + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 512, 128); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); - output = new OutputAnalyzer(pb.start()); - output.shouldContain("Test (reserved=256KB, committed=0KB)"); - output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed"); + // ------ + // Now commit the second mapping + wb.NMTCommitMemory(addr2, commitSize); + info = "commit 2"; - wb.NMTReleaseMemory(addr, reserveSize); + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 512, 256); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + commitSize) + "\\] committed 128KB"); - output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Test (reserved="); - output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved"); + // ------ + // Now uncommit the second mapping + wb.NMTUncommitMemory(addr2, commitSize); + info = "uncommit 2"; + + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 512, 128); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + commitSize) + "\\] committed 128KB"); + + // ------ + // Now uncommit the first mapping + wb.NMTUncommitMemory(addr1, commitSize); + info = "uncommit 1"; + + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 512, 0); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + commitSize) + "\\] committed 128KB"); + + // ---------- + // Release second mapping + wb.NMTReleaseMemory(addr2, reserveSize); + info = "release 2"; + + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 256, 0); + output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + commitSize) + "\\] committed 128KB"); + + // ---------- + // Release first mapping + wb.NMTReleaseMemory(addr1, reserveSize); + info = "release 1"; + + output = NMTTestUtils.startJcmdVMNativeMemoryDetail(); + checkReservedCommittedSummary(output, 0, 0); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr1) + " - 0x[0]*" + Long.toHexString(addr1 + commitSize) + "\\] committed 128KB"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + reserveSize) + "\\] reserved 256KB for Test"); + output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr2) + " - 0x[0]*" + Long.toHexString(addr2 + commitSize) + "\\] committed 128KB"); + + } catch (Exception e) { + throw new RuntimeException(e.getMessage() + " (" + info + ")"); + } + } + + static long peakKB = 0; + + public static void checkReservedCommittedSummary(OutputAnalyzer output, long reservedKB, long committedKB) { + if (committedKB > peakKB) { + peakKB = committedKB; + } + NMTTestUtils.checkReservedCommittedSummary(output, reservedKB, committedKB, peakKB); } } diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index bfdec8d63a4..ad81fd64a1e 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -608,6 +608,14 @@ public List asLines() { return asLines(getOutput()); } + public List stdoutAsLines() { + return asLines(getStdout()); + } + + public List stderrAsLines() { + return asLines(getStderr()); + } + private List asLines(String buffer) { return Arrays.asList(buffer.split("\\R")); } @@ -773,4 +781,72 @@ private int indexOf(List lines, String regexp, int fromIndex) { return -1; } + private void searchLinesForMultiLinePattern(String[] haystack, String[] needles, boolean verbose) { + + if (needles.length == 0) { + return; + } + + int firstNeedlePos = 0; + for (int i = 0; i < haystack.length; i++) { + if (verbose) { + System.out.println("" + i + ":" + haystack[i]); + } + if (haystack[i].contains(needles[0])) { + if (verbose) { + System.out.println("Matches pattern 0 (\"" + needles[0] + "\")"); + } + firstNeedlePos = i; + break; + } + } + + for (int i = 1; i < needles.length; i++) { + int haystackPos = firstNeedlePos + i; + if (haystackPos < haystack.length) { + if (verbose) { + System.out.println("" + haystackPos + ":" + haystack[haystackPos]); + } + if (haystack[haystackPos].contains(needles[i])) { + if (verbose) { + System.out.println("Matches pattern " + i + "(\"" + needles[i] + "\")"); + } + } else { + String err = "First unmatched pattern: " + i + " (\"" + needles[i] + "\")"; + if (!verbose) { // don't print twice + reportDiagnosticSummary(); + } + throw new RuntimeException(err); + } + } + } + } + + public void stdoutShouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] stdoutLines = stdoutAsLines().toArray(new String[0]); + searchLinesForMultiLinePattern(stdoutLines, needles, verbose); + } + + public void stdoutShouldContainMultiLinePattern(String... needles) { + stdoutShouldContainMultiLinePattern(needles, true); + } + + public void stderrShouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] stderrLines = stdoutAsLines().toArray(new String[0]); + searchLinesForMultiLinePattern(stderrLines, needles, verbose); + } + + public void stderrShouldContainMultiLinePattern(String... needles) { + stderrShouldContainMultiLinePattern(needles, true); + } + + public void shouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] lines = asLines().toArray(new String[0]); + searchLinesForMultiLinePattern(lines, needles, verbose); + } + + public void shouldContainMultiLinePattern(String... needles) { + shouldContainMultiLinePattern(needles, true); + } + } From 6f07ee48ed74e3be7e458ce1f8c353fdb16e52d2 Mon Sep 17 00:00:00 2001 From: Amos Shi Date: Sun, 28 Apr 2024 21:48:57 +0000 Subject: [PATCH 228/298] 8324733: [macos14] Problem list tests which fail due to macOS bug described in JDK-8322653 Backport-of: d1e676360d5143cf12655ab1175a4a60bf402473 --- test/jdk/ProblemList.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 04c2778461a..59d9ab3b218 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -440,8 +440,8 @@ java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java 8233568 macosx-all java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java 8233568 macosx-all java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720 windows-all java/awt/PopupMenu/PopupMenuLocation.java 8238720 windows-all -java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 windows-all -java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720 windows-all +java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720,8324782 windows-all,macosx-all +java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,8324782 windows-all,macosx-all java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all # Several tests which fail sometimes on macos11 @@ -473,6 +473,9 @@ java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 gen java/beans/XMLEncoder/Test6570354.java 8015593 macosx-all +# This test fails on macOS 14 +java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8324782 macosx-all + ############################################################################ # jdk_lang @@ -685,6 +688,9 @@ sanity/client/SwingSet/src/EditorPaneDemoTest.java 8212240 linux-x64 # jdk_time +# This test fails on macOS 14 +javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all + ############################################################################ # core_tools From e59f4fa6b266df22401bec1582da551421535893 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 29 Apr 2024 04:13:55 +0000 Subject: [PATCH 229/298] 8328194: Add a test to check default rendering engine Backport-of: c013fa18119bbd2e355d5c0d13cd8c172892800a --- .../java2d/marlin/DefaultRenderingEngine.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java diff --git a/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java b/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java new file mode 100644 index 00000000000..8ba6945d903 --- /dev/null +++ b/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, 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 sun.java2d.pipe.RenderingEngine; + +/** + * @test + * @bug 8241307 + * @summary Verifies that the Marlin renderer is the default RenderingEngine + * @modules java.desktop/sun.java2d.pipe + */ +public final class DefaultRenderingEngine { + + public static void main(String[] argv) { + + final RenderingEngine engine = RenderingEngine.getInstance(); + + if (!engine.getClass().getSimpleName().contains("Marlin")) { + throw new RuntimeException("Marlin must be the default RenderingEngine"); + } + } +} From d1b97d47379495b61f2afe0f4aacfef5d4b81d34 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 29 Apr 2024 08:33:59 +0000 Subject: [PATCH 230/298] 8309142: Refactor test/langtools/tools/javac/versions/Versions.java 8321182: SourceExample.SOURCE_14 comment should refer to 'switch expressions' instead of 'text blocks' Reviewed-by: phh Backport-of: 7d82479096d9ecc14881bf9b639507eee43f547b --- .../tools/javac/versions/Versions.java | 455 +++++++----------- 1 file changed, 182 insertions(+), 273 deletions(-) diff --git a/test/langtools/tools/javac/versions/Versions.java b/test/langtools/tools/javac/versions/Versions.java index 37e00ccec25..bd385ab93ca 100644 --- a/test/langtools/tools/javac/versions/Versions.java +++ b/test/langtools/tools/javac/versions/Versions.java @@ -23,7 +23,9 @@ /* * @test - * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 8000961 8030610 8028546 8188870 8173382 8173382 8193290 8205619 8028563 8245147 8245586 8257453 8286035 + * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 + * 8000961 8030610 8028546 8188870 8173382 8173382 8193290 8205619 8028563 + * 8245147 8245586 8257453 8286035 * @summary Check interpretation of -target and -source options * @modules java.compiler * jdk.compiler @@ -40,9 +42,7 @@ import javax.tools.StandardJavaFileManager; import java.util.List; import java.util.ArrayList; -import java.util.Arrays; import java.util.Set; -import java.util.function.BiConsumer; import java.util.function.Consumer; /* @@ -76,36 +76,48 @@ public static void main(String... args) throws IOException { public static final String LATEST_MAJOR_VERSION = "65.0"; static enum SourceTarget { - EIGHT(true, "52.0", "8", Versions::checksrc8), - NINE(true, "53.0", "9", Versions::checksrc9), - TEN(true, "54.0", "10", Versions::checksrc10), - ELEVEN(false, "55.0", "11", Versions::checksrc11), - TWELVE(false, "56.0", "12", Versions::checksrc12), - THIRTEEN(false, "57.0", "13", Versions::checksrc13), - FOURTEEN(false, "58.0", "14", Versions::checksrc14), - FIFTEEN(false, "59.0", "15", Versions::checksrc15), - SIXTEEN(false, "60.0", "16", Versions::checksrc16), - SEVENTEEN(false, "61.0", "17", Versions::checksrc17), - EIGHTEEN(false, "62.0", "18", Versions::checksrc18), - NINETEEN(false, "63.0", "19", Versions::checksrc19), - TWENTY(false, "64.0", "20", Versions::checksrc20), - TWENTY_ONE(false,"65.0", "21", Versions::checksrc21); + EIGHT(true, "52.0", "8"), + NINE(true, "53.0", "9"), + TEN(true, "54.0", "10"), + ELEVEN(false, "55.0", "11"), + TWELVE(false, "56.0", "12"), + THIRTEEN(false, "57.0", "13"), + FOURTEEN(false, "58.0", "14"), + FIFTEEN(false, "59.0", "15"), + SIXTEEN(false, "60.0", "16"), + SEVENTEEN(false, "61.0", "17"), + EIGHTEEN(false, "62.0", "18"), + NINETEEN(false, "63.0", "19"), + TWENTY(false, "64.0", "20"), + TWENTY_ONE(false,"65.0", "21"), + ; // Reduce code churn when appending new constants private final boolean dotOne; private final String classFileVer; private final String target; - private final BiConsumer> checker; + private final int intTarget; - private SourceTarget(boolean dotOne, String classFileVer, String target, - BiConsumer> checker) { + private SourceTarget(boolean dotOne, String classFileVer, String target) { this.dotOne = dotOne; this.classFileVer = classFileVer; this.target = target; - this.checker = checker; + this.intTarget = Integer.parseInt(target); } - public void checksrc(Versions version, List args) { - checker.accept(version, args); + public void checksrc(Versions versions, List args) { + // checker.accept(version, args); + versions.printargs("checksrc" + target, args); + List expectedPassFiles = new ArrayList<>(); + List expectedFailFiles = new ArrayList<>(); + + for (SourceExample srcEg : SourceExample.values()) { + var x = (srcEg.sourceLevel <= this.intTarget) ? + expectedPassFiles.add(srcEg.fileName()): + expectedFailFiles.add(srcEg.fileName()); + } + + versions.expectedPass(args, expectedPassFiles); + versions.expectedFail(args, expectedFailFiles); } public boolean dotOne() { @@ -119,6 +131,10 @@ public String classFileVer() { public String target() { return target; } + + public int intTarget() { + return intTarget; + } } void run() { @@ -221,16 +237,8 @@ protected void check(String major) { protected void check(String major, List args) { printargs("check", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); boolean creturn = compile("Base.java", jcargs); if (!creturn) { @@ -245,101 +253,150 @@ protected void check(String major, List args) { } } - protected void checksrc8(List args) { - printargs("checksrc8", args); - expectedPass(args, List.of("New7.java", "New8.java")); - expectedFail(args, List.of("New10.java", "New11.java", "New14.java", "New15.java", - "New16.java", "New17.java", "New21.java")); - - } - - protected void checksrc9(List args) { - printargs("checksrc9", args); - expectedPass(args, List.of("New7.java", "New8.java")); - expectedFail(args, List.of("New10.java", "New11.java", "New14.java", "New15.java", - "New16.java", "New17.java", "New21.java")); - } - - protected void checksrc10(List args) { - printargs("checksrc10", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java")); - expectedFail(args, List.of("New11.java", "New14.java", "New15.java", - "New16.java", "New17.java", "New21.java")); - } - - protected void checksrc11(List args) { - printargs("checksrc11", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java")); - expectedFail(args, List.of("New14.java", "New15.java", "New16.java", "New17.java", "New21.java")); - } - - protected void checksrc12(List args) { - printargs("checksrc12", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java")); - expectedFail(args, List.of("New14.java", "New15.java", "New16.java", "New17.java", "New21.java")); - } - - protected void checksrc13(List args) { - printargs("checksrc13", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java")); - expectedFail(args, List.of("New14.java", "New15.java", "New16.java", "New17.java", "New21.java")); - } - - protected void checksrc14(List args) { - printargs("checksrc14", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java")); - expectedFail(args, List.of("New15.java", "New16.java", "New17.java", "New21.java")); - } + /** + * Create a list of options suitable for use with {@link JavaCompiler} + * @param args a list of space-delimited options, such as "-source 11" + * @return a list of arguments suitable for use with {@link JavaCompiler} + */ + private static List javaCompilerOptions(List args) { + List jcargs = new ArrayList<>(); + jcargs.add("-Xlint:-options"); - protected void checksrc15(List args) { - printargs("checksrc15", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java")); - expectedFail(args, List.of("New16.java", "New17.java", "New21.java")); - } + // add in args conforming to List requirements of JavaCompiler + for (String onearg : args) { + String[] fields = onearg.split(" "); + for (String onefield : fields) { + jcargs.add(onefield); + } + } + return jcargs; + } + + /** + * The BASE source example is expected to compile on all source + * levels. Otherwise, an example is expected to compile on its + * declared source level and later, but to _not_ compile on + * earlier source levels. (This enum is _not_ intended to capture + * the uncommon program that is accepted in one version of the + * language and rejected in a later version.) + * + * When version of the language get a new, non-preview feature, a + * new source example enum constant should be added. + */ + enum SourceExample { + BASE(7, "Base.java", "public class Base { }\n"), + + + SOURCE_8(8, "New8.java", + // New feature in 8: lambda + """ + public class New8 { + void m() { + new Thread(() -> { }); + } + } + """), - protected void checksrc16(List args) { - printargs("checksrc16", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java")); - expectedFail(args, List.of("New17.java", "New21.java")); - } + SOURCE_10(10, "New10.java", + // New feature in 10: var + """ + public class New10 { + void m() { + var tmp = new Thread(() -> { }); + } + } + """), - protected void checksrc17(List args) { - printargs("checksrc17", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java", "New17.java")); - expectedFail(args, List.of("New21.java")); - } + SOURCE_11(11, "New11.java", + // New feature in 11: var for lambda parameters + """ + public class New11 { + static java.util.function.Function f = (var x) -> x.substring(0); + void m(String name) { + var tmp = new Thread(() -> { }, f.apply(name)); + } + } + """), - protected void checksrc18(List args) { - printargs("checksrc18", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java", "New17.java")); - expectedFail(args, List.of("New21.java")); - } + SOURCE_14(14, "New14.java", + // New feature in 14: switch expressions + """ + public class New14 { + static { + int i = 5; + System.out.println( + switch(i) { + case 0 -> false; + default -> true; + } + ); + } + } + """), + + SOURCE_15(15, "New15.java", + // New feature in 15: text blocks + """ + public class New15 { + public static final String s = + \"\"\" + Hello, World. + \"\"\" + ; + } + """), + + SOURCE_16(16, "New16.java", + // New feature in 16: records + """ + public class New16 { + public record Record(double rpm) { + public static final Record LONG_PLAY = new Record(100.0/3.0); + } + } + """), + + SOURCE_17(17, "New17.java", + // New feature in 17: sealed classes + """ + public class New17 { + public static sealed class Seal {} - protected void checksrc19(List args) { - printargs("checksrc19", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java", "New17.java")); - expectedFail(args, List.of("New21.java")); - } + public static final class Pinniped extends Seal {} + public static final class TaperedThread extends Seal {} + public static final class Wax extends Seal {} + } + """), - protected void checksrc20(List args) { - printargs("checksrc20", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java", "New17.java")); - expectedFail(args, List.of("New21.java")); - } + SOURCE_21(21, "New21.java", + // New feature in 21: pattern matching for switch + """ + public class New21 { + public static void main(String... args) { + Object o = new Object(){}; + + System.out.println(switch (o) { + case Integer i -> String.format("%d", i); + default -> o.toString(); + }); + } + } + """), + + ; // Reduce code churn when appending new constants + + private int sourceLevel; + private String fileName; + private String fileContents; + + private SourceExample(int sourceLevel, String fileName, String fileContents) { + this.sourceLevel = sourceLevel; + this.fileName = fileName; + this.fileContents = fileContents; + } - protected void checksrc21(List args) { - printargs("checksrc21", args); - expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", - "New14.java", "New15.java", "New16.java", "New17.java", - "New21.java")); - // Add expectedFail after new language features added in a later release. + public String fileName() {return fileName;} + public String fileContents() {return fileContents;} } protected void expected(List args, List fileNames, @@ -364,16 +421,7 @@ protected void expectedFail(List args, List fileNames) { protected void pass(List args) { printargs("pass", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); // empty list is error if (jcargs.isEmpty()) { @@ -401,16 +449,7 @@ protected void pass(List args) { protected void fail(List args) { printargs("fail", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); // empty list is error if (jcargs.isEmpty()) { @@ -465,139 +504,9 @@ protected void writeSourceFile(String fileName, String body) throws IOException{ } protected void genSourceFiles() throws IOException{ - /* Create a file that executes with all supported versions. */ - writeSourceFile("Base.java","public class Base { }\n"); - - /* - * Create a file with a new feature in 7, not in 6 : "<>" - */ - writeSourceFile("New7.java", - """ - import java.util.List; - import java.util.ArrayList; - class New7 { List s = new ArrayList<>(); } - """ - ); - - /* - * Create a file with a new feature in 8, not in 7 : lambda - */ - writeSourceFile("New8.java", - """ - public class New8 { - void m() { - new Thread(() -> { }); - } - } - """ - ); - - /* - * Create a file with a new feature in 10, not in 9 : var - */ - writeSourceFile("New10.java", - """ - public class New10 { - void m() { - var tmp = new Thread(() -> { }); - } - } - """ - ); - - /* - * Create a file with a new feature in 11, not in 10 : var for lambda parameters - */ - writeSourceFile("New11.java", - """ - public class New11 { - static java.util.function.Function f = (var x) -> x.substring(0); - void m(String name) { - var tmp = new Thread(() -> { }, f.apply(name)); - } - } - """ - ); - - /* - * Create a file with a new feature in 14, not in 13 : switch expressions - */ - writeSourceFile("New14.java", - """ - public class New14 { - static { - int i = 5; - System.out.println( - switch(i) { - case 0 -> false; - default -> true; - } - ); - } - } - """ - ); - - /* - * Create a file with a new feature in 15, not in 14 : text blocks - */ - writeSourceFile("New15.java", - """ - public class New15 { - public static final String s = - \"\"\" - Hello, World. - \"\"\" - ; - } - """ - ); - - /* - * Create a file with a new feature in 16, not in 15 : records - */ - writeSourceFile("New16.java", - """ - public class New16 { - public record Record(double rpm) { - public static final Record LONG_PLAY = new Record(100.0/3.0); - } - } - """ - ); - - /* - * Create a file with a new feature in 17, not in 16 : sealed classes - */ - writeSourceFile("New17.java", - """ - public class New17 { - public static sealed class Seal {} - - public static final class Pinniped extends Seal {} - public static final class TaperedThread extends Seal {} - public static final class Wax extends Seal {} - } - """ - ); - - /* - * Create a file with a new feature in 21, not in 20 : pattern matching for switch - */ - writeSourceFile("New21.java", - """ - public class New21 { - public static void main(String... args) { - Object o = new Object(){}; - - System.out.println(switch (o) { - case Integer i -> String.format("%d", i); - default -> o.toString(); - }); - } - } - """ - ); + for (SourceExample srcEg : SourceExample.values()) { + writeSourceFile(srcEg.fileName(), srcEg.fileContents()); + } } protected boolean checkClassFileVersion From d8bc9e441049d516941852708b43974cc48271e9 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 29 Apr 2024 08:34:48 +0000 Subject: [PATCH 231/298] 8331113: createJMHBundle.sh support configurable maven repo mirror Backport-of: ce9eac38191fa700afa3ac06b2b202576a11dd71 --- make/devkit/createJMHBundle.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/make/devkit/createJMHBundle.sh b/make/devkit/createJMHBundle.sh index c3c97947dab..b2b10769d15 100644 --- a/make/devkit/createJMHBundle.sh +++ b/make/devkit/createJMHBundle.sh @@ -1,6 +1,6 @@ #!/bin/bash -e # -# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 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 @@ -29,6 +29,7 @@ JMH_VERSION=1.37 COMMONS_MATH3_VERSION=3.6.1 JOPT_SIMPLE_VERSION=5.0.4 +MAVEN_MIRROR=${MAVEN_MIRROR:-https://repo.maven.apache.org/maven2} BUNDLE_NAME=jmh-$JMH_VERSION.tar.gz @@ -41,7 +42,7 @@ cd $JAR_DIR rm -f * fetchJar() { - url="https://repo.maven.apache.org/maven2/$1/$2/$3/$2-$3.jar" + url="${MAVEN_MIRROR}/$1/$2/$3/$2-$3.jar" if command -v curl > /dev/null; then curl -O --fail $url elif command -v wget > /dev/null; then From e7ebae54a7e0250cb9f645bd2bdc04a60f6b0cba Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 29 Apr 2024 09:19:40 +0000 Subject: [PATCH 232/298] 8321713: Harmonize executeTestJvm with create[Limited]TestJavaProcessBuilder Reviewed-by: lucy Backport-of: cbe329b90ac1488836d4852fead79aa26c082114 --- .../TestCompileThresholdScaling.java | 2 +- .../compiler/c1/TestPrintC1Statistics.java | 2 +- .../compiler/c2/cr7200264/TestDriver.java | 2 +- .../jtreg/compiler/ciReplay/CiReplayBase.java | 4 +- .../compilercontrol/commands/OptionTest.java | 16 +++--- .../parser/HugeDirectiveUtil.java | 2 +- .../parser/TestCompileOnly.java | 2 +- .../share/scenario/Executor.java | 2 +- .../TestAESIntrinsicsOnSupportedConfig.java | 10 ++-- .../TestAESIntrinsicsOnUnsupportedConfig.java | 4 +- .../gcbarriers/TestMembarDependencies.java | 2 +- .../intrinsics/bmi/BMITestRunner.java | 2 +- .../ir_framework/driver/FlagVMProcess.java | 2 +- .../ir_framework/driver/TestVMProcess.java | 2 +- .../UseCountedLoopSafepointsTest.java | 7 +-- .../loopstripmining/CheckLoopStripMining.java | 4 +- .../compiler/oracle/PrintIdealPhaseTest.java | 2 +- .../print/CompileCommandPrintCompilation.java | 2 +- .../compiler/print/PrintCompilation.java | 2 +- .../runtime/TestConstantsInError.java | 4 +- .../vectorapi/TestVectorErgonomics.java | 14 +++--- .../gc/arguments/TestSoftMaxHeapSizeFlag.java | 28 +++++------ .../jtreg/gc/g1/ihop/TestIHOPErgo.java | 2 +- .../jtreg/gc/g1/ihop/TestIHOPStatic.java | 2 +- .../gc/g1/logging/TestG1LoggingFailure.java | 2 +- .../gc/g1/plab/TestPLABEvacuationFailure.java | 2 +- .../jtreg/gc/g1/plab/TestPLABPromotion.java | 2 +- .../jtreg/gc/g1/plab/TestPLABResize.java | 2 +- .../TestExcessGCLockerCollections.java | 2 +- test/hotspot/jtreg/gc/x/TestHighUsage.java | 18 +++---- test/hotspot/jtreg/gc/z/TestHighUsage.java | 18 +++---- .../LoadLibrary/TestSunBootLibraryPath.java | 10 ++-- .../jtreg/runtime/Shutdown/ShutdownTest.java | 2 +- .../jni/FindClass/FindClassFromBoot.java | 2 +- .../jni/FindClassUtf8/FindClassUtf8.java | 8 +-- .../jtreg/runtime/jni/atExit/TestAtExit.java | 4 +- .../checked/TestCheckedJniExceptionCheck.java | 6 +-- .../TestCheckedReleaseArrayElements.java | 2 +- .../jni/nativeStack/TestNativeStack.java | 14 +++--- .../TestRegisterNativesWarning.java | 12 ++--- .../stringtable/StringTableCleaningTest.java | 2 +- test/hotspot/jtreg/sanity/BasicVMTest.java | 2 +- .../TestLambdaFormRetransformation.java | 2 +- .../TestRedefineWithUnresolvedClass.java | 2 +- .../agentonunload001/TestDriver.java | 2 +- .../general_functions/GF08/gf08t.java | 4 +- .../multienv/MA02/ma02t001/TestDriver.java | 2 +- test/jdk/com/sun/jdi/BadAgentPath.java | 2 +- test/jdk/com/sun/jdi/DoubleAgentTest.java | 2 +- test/jdk/com/sun/jdi/OnJcmdTest.java | 4 +- test/jdk/com/sun/jdi/SuspendNoFlagTest.java | 2 +- test/jdk/com/sun/tools/attach/BasicTests.java | 2 +- .../com/sun/tools/attach/PermissionTest.java | 4 +- .../com/sun/tools/attach/ProviderTest.java | 2 +- .../jdk/com/sun/tools/attach/TempDirTest.java | 2 +- .../jdk/java/io/File/TempDirDoesNotExist.java | 6 +-- .../jdk/java/io/FilePermission/MergeName.java | 2 +- .../io/FilePermission/ReadFileOnPath.java | 2 +- .../securityManager/ClassLoaderTest.java | 2 +- .../RuntimeTests/shutdown/ShutdownHooks.java | 2 +- .../ExtensiblePolicyWithJarTest.java | 2 +- .../Policy/SignedJar/SignedJarTest.java | 6 +-- .../Provider/SecurityProviderModularTest.java | 2 +- .../Security/signedfirst/DynStatic.java | 4 +- .../spi-calendar-provider/TestSPISigned.java | 2 +- .../java/util/Currency/PropertiesTestRun.java | 4 +- .../java/util/Locale/UseOldISOCodesTest.java | 2 +- .../util/prefs/CheckUserPrefsStorage.java | 2 +- test/jdk/java/util/zip/EntryCount64k.java | 2 +- .../util/zip/ZipFile/DeleteTempJarTest.java | 2 +- .../login/modules/JaasModularClientTest.java | 2 +- .../JaasModularDefaultHandlerTest.java | 2 +- .../jdk/internal/ref/Cleaner/ExitOnThrow.java | 6 +-- .../security/TestStreamingRemote.java | 2 +- .../jdk/jfr/event/io/TestInstrumentation.java | 2 +- .../jfr/jcmd/TestJcmdPreserveRepository.java | 2 +- .../pkcs11/Config/ReadConfInUTF16Env.java | 2 +- .../CertPathRestrictions/TLSRestrictions.java | 2 +- .../EngineArgs/DebugReportsOneExtraByte.java | 2 +- .../SSLLogger/LoggingFormatConsistency.java | 4 +- .../IgnorableExceptionMessages.java | 4 +- .../multiRelease/MVJarSigningTest.java | 2 +- .../util/Resources/early/EarlyResources.java | 2 +- .../jdk/test/lib/RandomGeneratorTest.java | 4 +- ...rocessToolsExecuteLimitedTestJavaTest.java | 45 +++++++++++++++++ .../jdk/test/lib/process/ProcessTools.java | 50 ++++++++++++++----- 86 files changed, 255 insertions(+), 183 deletions(-) create mode 100644 test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java diff --git a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java index c417cc66248..47025572428 100644 --- a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java +++ b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java @@ -48,7 +48,7 @@ public static void main(String args[]) throws Throwable { } static void checkCompileThresholdScaling(double value, boolean fail) throws Throwable { - OutputAnalyzer out = ProcessTools.executeTestJvm("-XX:CompileThresholdScaling=" + value, "--version"); + OutputAnalyzer out = ProcessTools.executeTestJava("-XX:CompileThresholdScaling=" + value, "--version"); out.shouldHaveExitValue(0); String output = out.getOutput(); diff --git a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java index 854ccd907c9..3d62aa4d271 100644 --- a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java +++ b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Exception { options.add("-XX:+PrintC1Statistics"); options.add("--version"); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0).shouldContain("C1 Runtime statistics"); } diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java index 8fc1fa0580d..9975fd7511c 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java @@ -44,7 +44,7 @@ public void run() throws Throwable { } private List executeApplication() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Xbatch", "-XX:-TieredCompilation", "-XX:+PrintCompilation", diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index 6ad45edd26b..dcb8dff8f7d 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -105,9 +105,9 @@ static void test(int i) { static { try { - CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION) + CLIENT_VM_AVAILABLE = ProcessTools.executeTestJava(CLIENT_VM_OPTION, VERSION_OPTION) .getOutput().contains("Client"); - SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION) + SERVER_VM_AVAILABLE = ProcessTools.executeTestJava(SERVER_VM_OPTION, VERSION_OPTION) .getOutput().contains("Server"); } catch(Throwable t) { throw new Error("Initialization failed: " + t, t); diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java index c65c3b4846b..9833bb7235e 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java @@ -36,13 +36,13 @@ public class OptionTest { public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldHaveExitValue(0) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldHaveExitValue(0) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") @@ -50,35 +50,35 @@ public static void main(String[] args) throws Exception { // corner case: // ccstrlist could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.ccstrlist const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.* const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // PrintIntrinsics could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") .shouldContain("CompileCommand: PrintIntrinsics class.PrintIntrinsics bool PrintIntrinsics = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // _dontinline_* is a valid method pattern, so it should be accepted - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") .shouldContain("CompileCommand: dontinline *.dontinline_* bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*.dontinline", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*.dontinline", "-version") .shouldContain("CompileCommand: dontinline *.dontinline bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("Error: Did not specify any method name") diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java index 6db9a995862..d337266dd50 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java @@ -121,7 +121,7 @@ private static List getRandomDescriptors( protected static OutputAnalyzer execute(String fileName) { OutputAnalyzer output; try { - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-XX:+UnlockDiagnosticVMOptions", "-XX:CompilerDirectivesLimit=1000", "-XX:CompilerDirectivesFile=" + fileName, diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java index e129bf7ab48..2b4845a34df 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java @@ -46,7 +46,7 @@ public static void main(String[] args) throws Exception { } public static void test(String compileOnlyCommand) throws Exception { - OutputAnalyzer output = ProcessTools.executeTestJvm("-XX:CompileOnly=" + compileOnlyCommand, "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-XX:CompileOnly=" + compileOnlyCommand, "-version"); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java index 8a868e89ee6..30222ace4a2 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java @@ -105,7 +105,7 @@ public List execute() { vmInputArgs.length + vmOptions.size()); System.arraycopy(vmOptions.toArray(), 0, cmds, vmInputArgs.length, vmOptions.size()); - output = ProcessTools.executeTestJvm(cmds); + output = ProcessTools.executeTestJava(cmds); } catch (Throwable thr) { throw new Error("Execution failed: " + thr.getMessage(), thr); } diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java index 4c56daebfb8..ac3a6d9a8c6 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java @@ -72,7 +72,7 @@ private boolean isTieredLevelGreaterThan(int level) { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, true))); final String errorMessage = "Case testUseAES failed"; @@ -103,7 +103,7 @@ private void testUseAES() throws Throwable { */ private void testUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, true), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -132,7 +132,7 @@ private void testUseAESUseSSE2() throws Throwable { */ private void testNoUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -158,7 +158,7 @@ private void testNoUseAESUseSSE2() throws Throwable { * @throws Throwable */ private void testNoUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false))); final String errorMessage = "Case testNoUseAES failed"; @@ -180,7 +180,7 @@ private void testNoUseAES() throws Throwable { * @throws Throwable */ private void testNoUseAESIntrinsic() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, false))); final String errorMessage = "Case testNoUseAESIntrinsic failed"; diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java index 03016ea3dd6..fdc8f63f9e0 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java @@ -65,7 +65,7 @@ protected void runTestCases() throws Throwable { * @throws Throwable */ private void testUseAESIntrinsics() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag( AESIntrinsicsBase.USE_AES_INTRINSICS, true))); final String errorMessage = "Case testUseAESIntrinsics failed"; @@ -89,7 +89,7 @@ private void testUseAESIntrinsics() throws Throwable { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag (AESIntrinsicsBase.USE_AES, true))); final String errorMessage = "Case testUseAES failed"; diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java index bbd518c6756..3678691b218 100644 --- a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java +++ b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java @@ -43,7 +43,7 @@ public class TestMembarDependencies { public static void main(String args[]) throws Exception { if (args.length == 0) { // For debugging, add "-XX:+TraceOptoPipelining" - OutputAnalyzer oa = ProcessTools.executeTestJvm("-XX:+IgnoreUnrecognizedVMOptions", + OutputAnalyzer oa = ProcessTools.executeTestJava("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:+PrintOpto", "-XX:CompileCommand=compileonly,compiler.membars.TestMembarDependencies::test*", "-XX:CompileCommand=dontinline,compiler.membars.TestMembarDependencies::test_m1", diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java index 4060bacbfba..159e471e3fc 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java +++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java @@ -146,7 +146,7 @@ public static OutputAnalyzer runTest(Class expr, new Integer(iterations).toString() }); - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(vmOpts); + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(vmOpts); outputAnalyzer.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java index f15d4bec398..cb362b3bbfb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java @@ -112,7 +112,7 @@ private void prepareVMFlags(Class testClass, List additionalFlags) { private void start() { try { // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. - oa = ProcessTools.executeTestJvm(cmds); + oa = ProcessTools.executeTestJava(cmds); } catch (Exception e) { throw new TestRunException("Failed to execute TestFramework flag VM", e); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index 2c63bbe9589..04f8096d969 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -149,7 +149,7 @@ private void start() { ProcessBuilder process = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); try { // Calls 'main' of TestVM to run all specified tests with commands 'cmds'. - // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and + // Use executeProcess instead of executeTestJava as we have already added the JTreg VM and // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(process); } catch (Exception e) { diff --git a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java index a971c947ff4..effbbbe46bd 100644 --- a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java +++ b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java @@ -59,9 +59,10 @@ public static void main (String args[]) { private static void check(boolean enabled) { OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", - "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", - "-XX:+WhiteBoxAPI", + oa = ProcessTools.executeTestJava( + "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", + "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", + "-XX:+WhiteBoxAPI", "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0", "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod", UseCountedLoopSafepoints.class.getName()); diff --git a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java index 48bd723a13e..9e8ac6b013a 100644 --- a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java +++ b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java @@ -38,7 +38,7 @@ public class CheckLoopStripMining { public static void main(String args[]) throws Exception { - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", "-XX:+SafepointTimeout", "-XX:+SafepointALot", "-XX:+AbortVMOnSafepointTimeout", @@ -54,7 +54,7 @@ public static void main(String args[]) throws Exception { .shouldHaveExitValue(0) .stdoutShouldContain("sum: 715827882"); - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", "-XX:+SafepointTimeout", "-XX:+SafepointALot", "-XX:+AbortVMOnSafepointTimeout", diff --git a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java index 1c0ae791004..04e6dfdcbcc 100644 --- a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java +++ b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java @@ -81,7 +81,7 @@ private void runTest(String cmdPhases, List expectedPhases, String logFi options.add("-XX:CompileCommand=PrintIdealPhase," + getTestClass() + "::test," + cmdPhases); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); if (valid) { oa.shouldHaveExitValue(0) .shouldContain("CompileCommand: PrintIdealPhase compiler/oracle/PrintIdealPhaseTest$TestMain.test const char* PrintIdealPhase = '"+cmdPhases.replace(',', ' ')+"'") diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java index 1fb102acb07..358a5a0a6b3 100644 --- a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java +++ b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java @@ -56,7 +56,7 @@ private static void test(String include, String exclude) throws Exception { options.add("-XX:CompileCommand=PrintCompilation," + getTestMethod(include)); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0) .shouldContain(getTestMethod(include)) diff --git a/test/hotspot/jtreg/compiler/print/PrintCompilation.java b/test/hotspot/jtreg/compiler/print/PrintCompilation.java index c04b2bf5206..3b3db304cef 100644 --- a/test/hotspot/jtreg/compiler/print/PrintCompilation.java +++ b/test/hotspot/jtreg/compiler/print/PrintCompilation.java @@ -47,7 +47,7 @@ public static void main(String[] args) throws Exception { options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*"); options.add(getTestClass()); - OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + OutputAnalyzer oa = ProcessTools.executeTestJava(options); oa.shouldHaveExitValue(0) .shouldContain(getTestMethod("method1")) diff --git a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java index df221959bb5..3daf12df879 100644 --- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java +++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java @@ -261,7 +261,7 @@ static void run(TestConstantsInError test) throws Exception { c1Args.addAll(List.of("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1", "-XX:+TracePatching")); c1Args.addAll(commonArgs); - OutputAnalyzer outputC1 = ProcessTools.executeTestJvm(c1Args) + OutputAnalyzer outputC1 = ProcessTools.executeTestJava(c1Args) .shouldHaveExitValue(0); test.process(outputC1, true); @@ -270,7 +270,7 @@ static void run(TestConstantsInError test) throws Exception { c2Args.add("-XX:-TieredCompilation"); c2Args.addAll(commonArgs); - OutputAnalyzer outputC2 = ProcessTools.executeTestJvm(c2Args) + OutputAnalyzer outputC2 = ProcessTools.executeTestJava(c2Args) .shouldHaveExitValue(0); test.process(outputC2, false); diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java index c15c38af64d..ed8981eb086 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java +++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java @@ -37,42 +37,42 @@ public class TestVectorErgonomics { public static void main(String[] args) throws Throwable { - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version", "--enable-preview") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") diff --git a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java index a61e7545522..3d8f31db864 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java @@ -42,36 +42,36 @@ public class TestSoftMaxHeapSizeFlag { public static void main(String args[]) throws Exception { // Test default value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting small value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xms, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xms, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xms) .shouldHaveExitValue(0); // Test setting middle value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + betweenXmsAndXmx) .shouldHaveExitValue(0); // Test setting largest value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting a too large value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + greaterThanXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + greaterThanXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldContain("SoftMaxHeapSize must be less than or equal to the maximum heap size") .shouldHaveExitValue(1); } diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java index a93232dd82e..a962efba460 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java @@ -129,7 +129,7 @@ private static void runTest(int heapSize, int sleepTime, boolean isIhopAdaptive) } private static OutputAnalyzer executeTest(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); throw new RuntimeException("AppIHOP failed with exit code" + out.getExitValue()); diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java index c84374fa359..7f5259a0855 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java @@ -129,7 +129,7 @@ private static void runTest(int ihop, long pctToFill, long heapSize, boolean exp Collections.addAll(options, COMMON_OPTIONS); options.add(AppIHOP.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); diff --git a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java index befa34dea65..eb008f04e52 100644 --- a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java +++ b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java @@ -63,7 +63,7 @@ public static void main(String[] args) throws Throwable { } private static void startVM(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); out.shouldNotContain("pure virtual method called"); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java index e4ca3f9ea85..bfa87d5c07b 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java @@ -108,7 +108,7 @@ private static void runTest(int wastePct, int plabSize, int parGCThreads, int he "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB", "-XX:MaxHeapSize=" + heapSize + "m"); testOptions.add(AppPLABEvacuationFailure.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions); + OutputAnalyzer out = ProcessTools.executeTestJava(testOptions); appPlabEvacFailureOutput = out.getOutput(); if (out.getExitValue() != 0) { diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java index add5f3ec16f..1c07eeefe94 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java @@ -116,7 +116,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABPromotion.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); output = out.getOutput(); checkResults(testCase); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java index 0c9ebb12e82..82246d790f4 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java @@ -87,7 +87,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABResize.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); checkResults(out.getOutput(), testCase); } diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java index 8b6326b1cae..1e65a80bd3c 100644 --- a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java +++ b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java @@ -173,7 +173,7 @@ public static void main(String args[]) throws Exception { finalArgs.addAll(Arrays.asList(args)); // GC and other options obtained from test framework. - OutputAnalyzer output = ProcessTools.executeTestJvm(finalArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(finalArgs); output.shouldHaveExitValue(0); //System.out.println("------------- begin stdout ----------------"); //System.out.println(output.getStdout()); diff --git a/test/hotspot/jtreg/gc/x/TestHighUsage.java b/test/hotspot/jtreg/gc/x/TestHighUsage.java index 370d8031800..32b0af19e4b 100644 --- a/test/hotspot/jtreg/gc/x/TestHighUsage.java +++ b/test/hotspot/jtreg/gc/x/TestHighUsage.java @@ -85,15 +85,15 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:+UseZGC", - "-XX:-ZGenerational", - "-XX:-ZProactive", - "-Xms128M", - "-Xmx128M", - "-XX:ParallelGCThreads=1", - "-XX:ConcGCThreads=1", - "-Xlog:gc,gc+start", - Test.class.getName()) + ProcessTools.executeTestJava("-XX:+UseZGC", + "-XX:-ZGenerational", + "-XX:-ZProactive", + "-Xms128M", + "-Xmx128M", + "-XX:ParallelGCThreads=1", + "-XX:ConcGCThreads=1", + "-Xlog:gc,gc+start", + Test.class.getName()) .shouldNotContain("Allocation Stall") .shouldContain("High Usage") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/z/TestHighUsage.java b/test/hotspot/jtreg/gc/z/TestHighUsage.java index 5d92c3fba55..d7d8c6df635 100644 --- a/test/hotspot/jtreg/gc/z/TestHighUsage.java +++ b/test/hotspot/jtreg/gc/z/TestHighUsage.java @@ -86,15 +86,15 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:+UseZGC", - "-XX:+ZGenerational", - "-XX:-ZProactive", - "-Xms128M", - "-Xmx128M", - "-XX:ParallelGCThreads=1", - "-XX:ConcGCThreads=1", - "-Xlog:gc,gc+start", - Test.class.getName()) + ProcessTools.executeTestJava("-XX:+UseZGC", + "-XX:+ZGenerational", + "-XX:-ZProactive", + "-Xms128M", + "-Xmx128M", + "-XX:ParallelGCThreads=1", + "-XX:ConcGCThreads=1", + "-Xlog:gc,gc+start", + Test.class.getName()) .shouldNotContain("Allocation Stall") .shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java index 356064d79a4..deb2a000d3d 100644 --- a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java +++ b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java @@ -46,11 +46,11 @@ public static void main(String[] args) throws Exception { // Start a java process with this property set, and check that: // 1) The process failed and // 2) The error message was correct. - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + tooLongPath, - "TestSunBootLibraryPath", - "'Do-Nothing'") - .shouldNotHaveExitValue(0) - .stdoutShouldContain(expectedErrorMessage); + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + tooLongPath, + "TestSunBootLibraryPath", + "'Do-Nothing'") + .shouldNotHaveExitValue(0) + .stdoutShouldContain(expectedErrorMessage); } else if (!args[0].equals("Do-Nothing")) { // Fail, to prevent accidental args from causing accidental test passing. throw new IllegalArgumentException("Test was launched with an invalid argument."); diff --git a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java index 30b1ebe252a..68dc6b2e1a7 100644 --- a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java +++ b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java @@ -66,7 +66,7 @@ public static void main(String args[]) { private static void startVM(String... options) throws Throwable { // Combine VM flags given from command-line and your additional options - OutputAnalyzer output = ProcessTools.executeTestJvm(options); + OutputAnalyzer output = ProcessTools.executeTestJava(options); output.shouldContain("- ShutdownTest -"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java index 06db9c07c73..4f59af310bf 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java +++ b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java @@ -42,7 +42,7 @@ public static void main(String... args) throws Exception { Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base"); String syspaths = System.getProperty("sun.boot.library.path") + File.pathSeparator + System.getProperty("java.library.path"); - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + syspaths, + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + syspaths, "--patch-module", "java.base=" + patches.toString(), "BootLoaderTest") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java index 4f90838c107..7b0a4cc46bf 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java +++ b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java @@ -43,10 +43,10 @@ public final class FindClassUtf8 { public static void main(String... args) throws Exception { if (args.length == 1) { // run java -Xcheck:jni FindClassUtf8 and check that the -Xcheck:jni message comes out. - ProcessTools.executeTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "-Xcheck:jni", - "-XX:-CreateCoredumpOnCrash", - "FindClassUtf8") + ProcessTools.executeTestJava("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "-Xcheck:jni", + "-XX:-CreateCoredumpOnCrash", + "FindClassUtf8") .shouldContain("JNI class name is not a valid UTF8 string") .shouldNotHaveExitValue(0); // you get a core dump from -Xcheck:jni failures } else { diff --git a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java index a54eaedbad4..82d834c869c 100644 --- a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java +++ b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java @@ -61,13 +61,13 @@ public static void main(String[] args) throws Exception { String jlp = "-Djava.library.path=" + Utils.TEST_NATIVE_PATH; // First run will terminate via DestroyJavaVM - OutputAnalyzer output = ProcessTools.executeTestJvm(jlp, main); + OutputAnalyzer output = ProcessTools.executeTestJava(jlp, main); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // Second run will terminate via System.exit() - output = ProcessTools.executeTestJvm(jlp, main, "doExit"); + output = ProcessTools.executeTestJava(jlp, main, "doExit"); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java index e731bab6374..3c6efeb9a2d 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java @@ -205,9 +205,9 @@ public static void main(String[] args) throws Throwable { } // launch and check output - checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestCheckedJniExceptionCheck")); + checkOuputForCorrectWarnings(ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestCheckedJniExceptionCheck")); } } diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java index 6395e3b9f0b..6bc09b8a034 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java @@ -45,7 +45,7 @@ public static void main(String[] args) throws Throwable { if (args == null || args.length == 0) { test(); } else { - // Uses executeProcess() instead of executeTestJvm() to avoid passing options + // Uses executeProcess() instead of executeTestJava() to avoid passing options // that might generate output on stderr (which should be empty for this test). ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xcheck:jni", diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java index 81ce1da7846..d1146ab3ad3 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java @@ -52,19 +52,19 @@ public class TestNativeStack { public static void main(String[] args) throws Throwable { // case 1: Trigger a JNI warning with Xcheck:jni OutputAnalyzer oa = - ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main"); + ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main"); oa.shouldHaveExitValue(0); oa.shouldContain("WARNING in native method"); oa.shouldContain("thread_start"); oa.reportDiagnosticSummary(); // Case 2: Trigger a JNI FatalError call - oa = ProcessTools.executeTestJvm("-XX:-CreateCoredumpOnCrash", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main", - "error"); + oa = ProcessTools.executeTestJava("-XX:-CreateCoredumpOnCrash", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main", + "error"); oa.shouldNotHaveExitValue(0); oa.shouldContain("FATAL ERROR in native method"); oa.shouldContain("thread_start"); diff --git a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java index e22c75a6a44..e3d043ee4af 100644 --- a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java +++ b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java @@ -65,17 +65,17 @@ public static void main(String[] args) throws Exception { String cp = Utils.TEST_CLASS_PATH; String libp = Utils.TEST_NATIVE_PATH; - OutputAnalyzer output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - Tester.class.getName()); + OutputAnalyzer output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + Tester.class.getName()); output.shouldContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // If we run everything from the "boot" loader there should be no warning - output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - "-Xbootclasspath/a:" + cp, - "-Dsun.boot.library.path=" + libp, - Tester.class.getName()); + output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + "-Xbootclasspath/a:" + cp, + "-Dsun.boot.library.path=" + libp, + Tester.class.getName()); output.shouldNotContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java index 4c54273c8c7..a62d61166fc 100644 --- a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java +++ b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java @@ -58,7 +58,7 @@ public static void main(String[] args) throws Exception { subargs.addAll(List.of("-Xlog:gc,gc+start,stringtable*=trace", "-Xmx1g")); subargs.add(Tester.class.getName()); subargs.addAll(Arrays.asList(args)); - OutputAnalyzer output = ProcessTools.executeTestJvm(subargs); + OutputAnalyzer output = ProcessTools.executeTestJava(subargs); output.shouldHaveExitValue(0); checkOutput(output); } diff --git a/test/hotspot/jtreg/sanity/BasicVMTest.java b/test/hotspot/jtreg/sanity/BasicVMTest.java index a128cdfea37..47773d63df4 100644 --- a/test/hotspot/jtreg/sanity/BasicVMTest.java +++ b/test/hotspot/jtreg/sanity/BasicVMTest.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { "-X", "-help"); for (String flag : flags) { - ProcessTools.executeTestJvm(flag) + ProcessTools.executeTestJava(flag) .shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java index feacea07aab..48c9ad1328e 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java @@ -60,7 +60,7 @@ public class TestLambdaFormRetransformation { public static void main(String args[]) throws Throwable { Path agent = TestLambdaFormRetransformation.buildAgent(); - OutputAnalyzer oa = ProcessTools.executeTestJvm("-javaagent:" + + OutputAnalyzer oa = ProcessTools.executeTestJava("-javaagent:" + agent.toAbsolutePath().toString(), "-version"); oa.shouldHaveExitValue(ExitCode.OK.value); } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java index 2e36e33ce83..4bcd2a44588 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java @@ -79,7 +79,7 @@ private static void buildJar(String jarName) throws Throwable { } private static void launchTest() throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-javaagent:" + testClasses + "UnresolvedClassAgent.jar", "-Dtest.classes=" + testClasses, "UnresolvedClassAgent"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java index 9d8bb71cbc5..48245698712 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java @@ -53,7 +53,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:agentonunload001=-waittime=5", nsk.jvmti.Agent_OnUnload.agentonunload001.class.getName()); oa.shouldHaveExitValue(95); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java index 9f028153342..964283d2b01 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java @@ -38,13 +38,13 @@ public static void main(String[] args) throws Exception { .skip(3) .collect(Collectors.joining(" ")); - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=yes", className); oa.shouldHaveExitValue(95); oa.stdoutShouldContain(phrase); - oa = ProcessTools.executeTestJvm( + oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=no", "-verbose:" + verboseType, className); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java index 2aae25104fe..3d474c4e149 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java @@ -47,7 +47,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:ma02t001=-waittime=5", "-agentlib:ma02t001a=-waittime=5", nsk.jvmti.scenarios.multienv.MA02.ma02t001.class.getName()); diff --git a/test/jdk/com/sun/jdi/BadAgentPath.java b/test/jdk/com/sun/jdi/BadAgentPath.java index 68f28701cdc..3ef0adadc84 100644 --- a/test/jdk/com/sun/jdi/BadAgentPath.java +++ b/test/jdk/com/sun/jdi/BadAgentPath.java @@ -38,7 +38,7 @@ public class BadAgentPath { public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-agentpath:/badAgent/agent", "-version"); output.shouldContain("Could not find agent library /badAgent/agent"); } } diff --git a/test/jdk/com/sun/jdi/DoubleAgentTest.java b/test/jdk/com/sun/jdi/DoubleAgentTest.java index 99ec6091aaf..ea2a109ed9b 100644 --- a/test/jdk/com/sun/jdi/DoubleAgentTest.java +++ b/test/jdk/com/sun/jdi/DoubleAgentTest.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Throwable { String jdwpOption = "-agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=n" + ",address=*:0"; - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, jdwpOption, // Notice jdwpOption specified twice jdwpOption, diff --git a/test/jdk/com/sun/jdi/OnJcmdTest.java b/test/jdk/com/sun/jdi/OnJcmdTest.java index 6cc417497c6..c7f93e6fb31 100644 --- a/test/jdk/com/sun/jdi/OnJcmdTest.java +++ b/test/jdk/com/sun/jdi/OnJcmdTest.java @@ -51,12 +51,12 @@ private static String getListenerAddress() throws Exception { public static void main(String[] args) throws Throwable { // First check if we get the expected errors. - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y"); output.shouldContain("Can only use onjcmd with server=y"); output.shouldHaveExitValue(1); - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y,onthrow=a,launch=a"); output.shouldContain("Cannot combine onjcmd and launch suboptions"); output.shouldHaveExitValue(1); diff --git a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java index 98b32063c74..31e717a63d0 100644 --- a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java +++ b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java @@ -38,7 +38,7 @@ public class SuspendNoFlagTest { "test.classes", "."); public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n", "HelloWorld"); diff --git a/test/jdk/com/sun/tools/attach/BasicTests.java b/test/jdk/com/sun/tools/attach/BasicTests.java index ff1849984d4..833d7022ce8 100644 --- a/test/jdk/com/sun/tools/attach/BasicTests.java +++ b/test/jdk/com/sun/tools/attach/BasicTests.java @@ -101,7 +101,7 @@ private static void runTests(long pid) throws Throwable { testClassDir + "Agent.jar", testClassDir + "BadAgent.jar", testClassDir + "RedefineAgent.jar" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/PermissionTest.java b/test/jdk/com/sun/tools/attach/PermissionTest.java index 3a4128a9472..bf9473b0c8c 100644 --- a/test/jdk/com/sun/tools/attach/PermissionTest.java +++ b/test/jdk/com/sun/tools/attach/PermissionTest.java @@ -86,7 +86,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "true" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); // Use a policy that will allow attach. @@ -98,7 +98,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "false" }; - output = ProcessTools.executeTestJvm(args); + output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/ProviderTest.java b/test/jdk/com/sun/tools/attach/ProviderTest.java index 575420722d3..c7249a54b26 100644 --- a/test/jdk/com/sun/tools/attach/ProviderTest.java +++ b/test/jdk/com/sun/tools/attach/ProviderTest.java @@ -79,7 +79,7 @@ private static void runTests() throws Throwable { "-classpath", classpath, "ProviderTest$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/TempDirTest.java b/test/jdk/com/sun/tools/attach/TempDirTest.java index 2d932ffcf0e..b9ce4acb141 100644 --- a/test/jdk/com/sun/tools/attach/TempDirTest.java +++ b/test/jdk/com/sun/tools/attach/TempDirTest.java @@ -140,7 +140,7 @@ private static void launchTests(long pid, Path clientTmpDir) throws Throwable { classpath, "TempDirTest$TestMain", Long.toString(pid) }); - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/java/io/File/TempDirDoesNotExist.java b/test/jdk/java/io/File/TempDirDoesNotExist.java index bb59f6f9aeb..f1c69f58654 100644 --- a/test/jdk/java/io/File/TempDirDoesNotExist.java +++ b/test/jdk/java/io/File/TempDirDoesNotExist.java @@ -124,21 +124,21 @@ public static Stream counterSource() { @ParameterizedTest @MethodSource("tempDirSource") public void existingMessage(List options) throws Exception { - ProcessTools.executeTestJvm(options).shouldContain(WARNING) + ProcessTools.executeTestJava(options).shouldContain(WARNING) .shouldHaveExitValue(0); } @ParameterizedTest @MethodSource("noTempDirSource") public void nonexistentMessage(List options) throws Exception { - ProcessTools.executeTestJvm(options).shouldNotContain(WARNING) + ProcessTools.executeTestJava(options).shouldNotContain(WARNING) .shouldHaveExitValue(0); } @ParameterizedTest @MethodSource("counterSource") public void messageCounter(List options) throws Exception { - OutputAnalyzer originalOutput = ProcessTools.executeTestJvm(options); + OutputAnalyzer originalOutput = ProcessTools.executeTestJava(options); long count = originalOutput.asLines().stream().filter( line -> line.equalsIgnoreCase(WARNING)).count(); assertEquals(1, count, diff --git a/test/jdk/java/io/FilePermission/MergeName.java b/test/jdk/java/io/FilePermission/MergeName.java index c2eff765f2d..715b9851209 100644 --- a/test/jdk/java/io/FilePermission/MergeName.java +++ b/test/jdk/java/io/FilePermission/MergeName.java @@ -81,7 +81,7 @@ private static void test(String file, String... actions) throws Exception { } content.add("};"); Files.write(Paths.get(file), content); - ProcessTools.executeTestJvm("-Djava.security.manager", + ProcessTools.executeTestJava("-Djava.security.manager", "-Djava.security.policy=" + file, "MergeName", "x", diff --git a/test/jdk/java/io/FilePermission/ReadFileOnPath.java b/test/jdk/java/io/FilePermission/ReadFileOnPath.java index acc66dac6ab..06e2c6c435a 100644 --- a/test/jdk/java/io/FilePermission/ReadFileOnPath.java +++ b/test/jdk/java/io/FilePermission/ReadFileOnPath.java @@ -87,7 +87,7 @@ static void test(String... args) throws Exception { cmds.addAll(List.of( "x", "modules/m", "modules/m/base", "modules/m/p/child", "-", "child", "/base", "../base")); - ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()])) + ProcessTools.executeTestJava(cmds.toArray(new String[cmds.size()])) .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java index 7f335d15edd..a20440d2adf 100644 --- a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java +++ b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java @@ -241,7 +241,7 @@ private void execute(String[] args, String status, String msg) throws Exception if (s.contains(" ")) { throw new RuntimeException("No spaces in args");} return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ("PASS".equals(status) && out.contains(msg)) { System.out.println("PASS: Expected Result: " + msg); diff --git a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java index 6b2dc7b4dbf..36d3878fb41 100644 --- a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java +++ b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java @@ -61,7 +61,7 @@ public void testShutdownHooks() throws Exception { // Run in a new process in order to evaluate shutdown hook results String[] testCommand = new String[] {"-classpath", TEST_CLASSES, ShutdownHooksProcess.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); String errorMsg = "File exists despite shutdown hook has been run"; assertFalse(Files.exists(TEST_FILE.toPath()), errorMsg); diff --git a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java index 8fdd7878639..fdbe44fb03c 100644 --- a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java +++ b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java @@ -94,7 +94,7 @@ public static void main(String args[]) throws Throwable { "-Djava.security.manager", "-Djava.security.policy=" + POL, "ExtensiblePolicyTest_orig$TestMain"}; - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } catch (Exception ex) { System.out.println("ExtensiblePolicyWithJarTest Failed"); } diff --git a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java index c93337d73d0..cd06cc15691 100644 --- a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java +++ b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java @@ -121,7 +121,7 @@ public static void main(String args[]) throws Throwable { System.out.println("Test Case 1"); //copy policy file into current directory String[] cmd = constructCMD("first.jar", POLICY1, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 2, test with both.jar //setIO permission granted to code that was signed by first signer @@ -131,7 +131,7 @@ public static void main(String args[]) throws Throwable { //Expect no AccessControlException System.out.println("Test Case 2"); cmd = constructCMD("both.jar", POLICY1, "false", "false"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 3 //setIO permission granted to code that was signed by first signer @@ -141,7 +141,7 @@ public static void main(String args[]) throws Throwable { //Expect AccessControlException for setFactory permission System.out.println("Test Case 3"); cmd = constructCMD("both.jar", POLICY2, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } diff --git a/test/jdk/java/security/Provider/SecurityProviderModularTest.java b/test/jdk/java/security/Provider/SecurityProviderModularTest.java index a919f104817..1e3c2306e9c 100644 --- a/test/jdk/java/security/Provider/SecurityProviderModularTest.java +++ b/test/jdk/java/security/Provider/SecurityProviderModularTest.java @@ -257,7 +257,7 @@ private void execute(String args, String msgKey) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) { System.out.printf("PASS: Expected Result: %s.%n", diff --git a/test/jdk/java/security/Security/signedfirst/DynStatic.java b/test/jdk/java/security/Security/signedfirst/DynStatic.java index 5256564064b..59e30de5462 100644 --- a/test/jdk/java/security/Security/signedfirst/DynStatic.java +++ b/test/jdk/java/security/Security/signedfirst/DynStatic.java @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(DYN_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the DynSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "DynSignedProvFirst") .shouldContain("test passed"); @@ -87,7 +87,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(STATIC_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the StaticSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "-Djava.security.properties=file:" + STATIC_PROPS, "StaticSignedProvFirst") diff --git a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java index 69fe8effe70..83c2d85f6e4 100644 --- a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java +++ b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java @@ -100,7 +100,7 @@ public static void main(String[] args) throws Throwable { testRun.add(classPath); testRun.add(TestSPISigned.class.getSimpleName()); testRun.add("run-test"); - OutputAnalyzer out = ProcessTools.executeTestJvm(testRun); + OutputAnalyzer out = ProcessTools.executeTestJava(testRun); out.shouldHaveExitValue(0); out.shouldContain("DEBUG: Getting xx language"); } diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java index 6f2ea28a90d..baec22f3e86 100644 --- a/test/jdk/java/util/Currency/PropertiesTestRun.java +++ b/test/jdk/java/util/Currency/PropertiesTestRun.java @@ -116,7 +116,7 @@ private static Stream PropertiesTestMethods() { // Launch a PropertiesTest method using the TEST JDK private static void executeTestJDKMethod(String... params) throws Throwable { - int exitStatus = ProcessTools.executeTestJvm(params).getExitValue(); + int exitStatus = ProcessTools.executeTestJava(params).getExitValue(); if (exitStatus != 0) { fail("Process started with: " + Arrays.toString(params) + " failed"); } @@ -126,7 +126,7 @@ private static void executeTestJDKMethod(String... params) throws Throwable { private static void executeWritableJDKMethod(String... params) throws Throwable { // Need to include WritableJDK javapath, TEST JDK classpath String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length]; - // We don't use executeTestJvm() because we want to point to separate JDK java path + // We don't use executeTestJava() because we want to point to separate JDK java path allParams[0] = WRITABLE_JDK_JAVA_PATH; allParams[1] = "-cp"; allParams[2] = System.getProperty("java.class.path"); diff --git a/test/jdk/java/util/Locale/UseOldISOCodesTest.java b/test/jdk/java/util/Locale/UseOldISOCodesTest.java index b38537bceca..01f997a743d 100644 --- a/test/jdk/java/util/Locale/UseOldISOCodesTest.java +++ b/test/jdk/java/util/Locale/UseOldISOCodesTest.java @@ -41,7 +41,7 @@ public class UseOldISOCodesTest { // Ensure java.locale.useOldISOCodes is only interpreted at runtime startup @Test public void staticInitializationTest() throws Exception { - ProcessTools.executeTestJvm("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") + ProcessTools.executeTestJava("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") .outputTo(System.out) .errorTo(System.err) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java index 51ecae932d1..1f772f4811a 100644 --- a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java +++ b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Throwable { } public static void run(String testName) throws Exception { - ProcessTools.executeTestJvm("-Djava.util.prefs.userRoot=.", testName) + ProcessTools.executeTestJava("-Djava.util.prefs.userRoot=.", testName) .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index 08d896a124a..2dac7643de2 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -160,7 +160,7 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { } // Check java -jar - OutputAnalyzer a = ProcessTools.executeTestJvm("-jar", zipFile.getName()); + OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); a.stdoutShouldMatch("\\AMain\\Z"); a.stderrShouldMatch("\\A\\Z"); diff --git a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java index e0a987f8bdc..cafc17accf8 100644 --- a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java +++ b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java @@ -42,7 +42,7 @@ public class DeleteTempJarTest { public static void main(String[] args) throws Exception { - String tmpFile = ProcessTools.executeTestJvm(DeleteTempJar.class.getName()) + String tmpFile = ProcessTools.executeTestJava(DeleteTempJar.class.getName()) .shouldHaveExitValue(0) .getStdout(); diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java index 5e90ecf839c..3bf9138a134 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java @@ -186,7 +186,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java index 9f808b2caad..5ce323f5ac7 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java @@ -170,7 +170,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java index 02346414cd3..7651c92bf77 100644 --- a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java +++ b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java @@ -44,9 +44,9 @@ public class ExitOnThrow { public static void main(String[] args) throws Exception { if (args.length == 0) { - ProcessTools.executeTestJvm("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", - "ExitOnThrow", - "-executeCleaner") + ProcessTools.executeTestJava("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", + "ExitOnThrow", + "-executeCleaner") .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(1) diff --git a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java index 6b97613f4ab..f5a32e0b45a 100644 --- a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java +++ b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java @@ -81,7 +81,7 @@ public static void main(String... args) throws Exception { c[1] = "-Djava.security.policy=" + escapeBackslashes(policy.toString()); c[2] = Test.class.getName(); c[3] = repository; - OutputAnalyzer oa = ProcessTools.executeTestJvm(c); + OutputAnalyzer oa = ProcessTools.executeTestJava(c); oa.shouldContain(SUCCESS); } } diff --git a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java index 5e08f45cb55..ddbc1206497 100644 --- a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java +++ b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java @@ -283,7 +283,7 @@ private static void launchTest() throws Throwable { "-classpath", classpath, "-javaagent:" + testClassDir + "TestInstrumentation.jar", "jdk.jfr.event.io.TestInstrumentation$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java index f1550e633eb..2ab6bad6259 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java @@ -57,7 +57,7 @@ public static void main(String[] args) throws Throwable { "-Dtest.jdk=" + System.getProperty("test.jdk"), TestProcess.class.getName() }; - OutputAnalyzer output = ProcessTools.executeTestJvm(arguments); + OutputAnalyzer output = ProcessTools.executeTestJava(arguments); output.shouldHaveExitValue(0); Optional p = Files.find(path, 99, (a,b) -> a.getFileName().toString().endsWith(".jfr")).findAny(); if (p.isEmpty()) { diff --git a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java index b5ca601c011..11a6a781e01 100644 --- a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java +++ b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java @@ -40,7 +40,7 @@ public class ReadConfInUTF16Env { public void testReadConfInUTF16Env() throws Exception { String[] testCommand = new String[] { "-Dfile.encoding=UTF-16", TestSunPKCS11Provider.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); } static class TestSunPKCS11Provider { diff --git a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java index b9fb72b8faf..476dc954884 100644 --- a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java +++ b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java @@ -231,7 +231,7 @@ static void testConstraint(String[] trustNames, String[] certNames, // Run client on another JVM so that its properties cannot be in conflict // with server's. - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Dcert.dir=" + CERT_DIR, "-Djava.security.debug=certpath", "-classpath", diff --git a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java index 1ce50662f46..7632fcf462f 100644 --- a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java +++ b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java @@ -93,7 +93,7 @@ public class DebugReportsOneExtraByte extends SSLEngineTemplate { public static void main(String args[]) throws Exception { if (args.length == 0) { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-Dtest.src=" + System.getProperty("test.src"), "-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p"); output.shouldContain("WRITE: TLSv1 application_data, length = 8"); diff --git a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java index c614ca62f29..5cfa9c9a680 100644 --- a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java +++ b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java @@ -50,7 +50,7 @@ public class LoggingFormatConsistency extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length != 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -71,7 +71,7 @@ public static void main(String[] args) throws Exception { System.out.println("TESTING " + expectedTLSVersion); var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion; - var output = ProcessTools.executeTestJvm( + var output = ProcessTools.executeTestJava( testSrc, activeTLSProtocol, javaxNetDebug, diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java index 708b8f0d11b..a1c9cad2271 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java @@ -49,7 +49,7 @@ public class IgnorableExceptionMessages extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length > 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -67,7 +67,7 @@ public static void main(String[] args) throws Exception { className, extraArgument); - OutputAnalyzer output = ProcessTools.executeTestJvm(jvmArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(jvmArgs); if (output.getExitValue() != 0) { output.asLines().forEach(System.out::println); // No need to dump the output unless the test fails diff --git a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java index ccc4b405147..9c9a8590ac7 100644 --- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java +++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java @@ -120,7 +120,7 @@ public static void main(String[] args) throws Throwable { "-Djava.security.policy=" + TEST_SRC + File.separator + POLICY_FILE, "version.Main"}; - ProcessTools.executeTestJvm(cmd) + ProcessTools.executeTestJava(cmd) .shouldHaveExitValue(0) .shouldContain(VERSION_MESSAGE); } diff --git a/test/jdk/sun/security/util/Resources/early/EarlyResources.java b/test/jdk/sun/security/util/Resources/early/EarlyResources.java index 12da50e311f..3ee0a9f576c 100644 --- a/test/jdk/sun/security/util/Resources/early/EarlyResources.java +++ b/test/jdk/sun/security/util/Resources/early/EarlyResources.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { String fs = File.separator; String policyPath = testSrc + fs + "malformed.policy"; - OutputAnalyzer out = ProcessTools.executeTestJvm( + OutputAnalyzer out = ProcessTools.executeTestJava( "-Djava.security.manager", "-Djava.security.policy=" + policyPath, "EarlyResources$TestMain"); diff --git a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java index ce57ebfe65f..71e36bdc9c4 100644 --- a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java +++ b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java @@ -69,7 +69,7 @@ public static void main( String[] args) throws Throwable { jvmArgs.add(origFileName); int fileNameIndex = jvmArgs.size() - 1; String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]); - ProcessTools.executeTestJvm(cmdLineArgs).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmdLineArgs).shouldHaveExitValue(0); String etalon = Utils.fileAsString(origFileName).trim(); cmdLineArgs[fileNameIndex] = seedOpt.name(); seedOpt.verify(etalon, cmdLineArgs); @@ -143,7 +143,7 @@ public void verify(String orig, String[] cmdLine) { String output; OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm(cmdLine); + oa = ProcessTools.executeTestJava(cmdLine); } catch (Throwable t) { throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t); } diff --git a/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java new file mode 100644 index 00000000000..4331f9ab374 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Unit test for ProcessTools.executeLimitedTestJava() + * @library /test/lib + * @run main/othervm -Dtest.java.opts=-XX:MaxMetaspaceSize=123456789 ProcessToolsExecuteLimitedTestJavaTest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class ProcessToolsExecuteLimitedTestJavaTest { + public static void main(String[] args) throws Exception { + if (args.length > 0) { + // Do nothing. Just let the JVM log its output. + } else { + // In comparison to executeTestJava, executeLimitedTestJava should not add the + // -Dtest.java.opts flags. Check that it doesn't. + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintFlagsFinal", "-version"); + output.stdoutShouldNotMatch(".*MaxMetaspaceSize.* = 123456789.*"); + } + } +} diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 12e2f0de6a2..aafb6fe3f4c 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -608,43 +608,69 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

      The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(List cmds) throws Exception { - return executeTestJvm(cmds.toArray(String[]::new)); + public static OutputAnalyzer executeTestJava(List command) throws Exception { + return executeTestJava(command.toArray(String[]::new)); } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

      The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(String... cmds) throws Exception { - ProcessBuilder pb = createTestJavaProcessBuilder(cmds); + public static OutputAnalyzer executeTestJava(String... command) throws Exception { + ProcessBuilder pb = createTestJavaProcessBuilder(command); return executeProcess(pb); } /** - * @param cmds User specified arguments. + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

      The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. + * @return The output from the process. + */ + public static OutputAnalyzer executeLimitedTestJava(List command) throws Exception { + return executeLimitedTestJava(command.toArray(String[]::new)); + } + + /** + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

      The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. * @return The output from the process. - * @see #executeTestJvm(String...) */ - public static OutputAnalyzer executeTestJava(String... cmds) throws Exception { - return executeTestJvm(cmds); + public static OutputAnalyzer executeLimitedTestJava(String... command) throws Exception { + ProcessBuilder pb = createLimitedTestJavaProcessBuilder(command); + return executeProcess(pb); } /** From a0e8de81ea653552d487886d5059e6eede2972a5 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Mon, 29 Apr 2024 10:01:27 +0000 Subject: [PATCH 233/298] 8330156: RISC-V: Range check auipc + signed 12 imm instruction Backport-of: 8990864a53fa04f44ecf8bff65a6dc9cdd67cb1c --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 2 +- src/hotspot/cpu/riscv/macroAssembler_riscv.hpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index fd5739d3d40..dd2922240b2 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -720,7 +720,7 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg void MacroAssembler::la(Register Rd, const address dest) { int64_t offset = dest - pc(); - if (is_simm32(offset)) { + if (is_valid_32bit_offset(offset)) { auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit addi(Rd, Rd, ((int64_t)offset << 52) >> 52); } else { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 21f64f4b20e..ca64e2e8152 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -640,6 +640,14 @@ class MacroAssembler: public Assembler { int pop_v(unsigned int bitset, Register stack); #endif // COMPILER2 + // The signed 20-bit upper imm can materialize at most negative 0xF...F80000000, two G. + // The following signed 12-bit imm can at max subtract 0x800, two K, from that previously loaded two G. + bool is_valid_32bit_offset(int64_t x) { + constexpr int64_t twoG = (2 * G); + constexpr int64_t twoK = (2 * K); + return x < (twoG - twoK) && x >= (-twoG - twoK); + } + public: void push_reg(Register Rs); void pop_reg(Register Rd); @@ -794,7 +802,7 @@ class MacroAssembler: public Assembler { void NAME(Register Rd, address dest) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(Rd, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, Rd, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -851,7 +859,7 @@ class MacroAssembler: public Assembler { void NAME(FloatRegister Rd, address dest, Register temp = t0) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -912,7 +920,7 @@ class MacroAssembler: public Assembler { assert_cond(dest != nullptr); \ assert_different_registers(Rs, temp); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -957,7 +965,7 @@ class MacroAssembler: public Assembler { void NAME(FloatRegister Rs, address dest, Register temp = t0) { \ assert_cond(dest != nullptr); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ From 75ac9e858f0eee48da3136c5b7c96a6db0496241 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 29 Apr 2024 13:45:03 +0000 Subject: [PATCH 234/298] 8328168: Epsilon: Premature OOM when allocating object larger than uncommitted heap size Backport-of: 7baec6622254fc21e315b974a213605a7605daac --- src/hotspot/share/gc/epsilon/epsilonHeap.cpp | 12 ++++-- .../gc/epsilon/TestEnoughUnusedSpace.java | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp index c44baa3cc04..3cd5665e045 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp @@ -125,17 +125,21 @@ HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) { // Expand and loop back if space is available size_t size_in_bytes = size * HeapWordSize; - size_t space_left = max_capacity() - capacity(); + size_t uncommitted_space = max_capacity() - capacity(); + size_t unused_space = max_capacity() - used(); size_t want_space = MAX2(size_in_bytes, EpsilonMinHeapExpand); + assert(unused_space >= uncommitted_space, + "Unused (" SIZE_FORMAT ") >= uncommitted (" SIZE_FORMAT ")", + unused_space, uncommitted_space); - if (want_space < space_left) { + if (want_space < uncommitted_space) { // Enough space to expand in bulk: bool expand = _virtual_space.expand_by(want_space); assert(expand, "Should be able to expand"); - } else if (size_in_bytes < space_left) { + } else if (size_in_bytes < unused_space) { // No space to expand in bulk, and this allocation is still possible, // take all the remaining space: - bool expand = _virtual_space.expand_by(space_left); + bool expand = _virtual_space.expand_by(uncommitted_space); assert(expand, "Should be able to expand"); } else { // No space left: diff --git a/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java b/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java new file mode 100644 index 00000000000..2578b3fb2e0 --- /dev/null +++ b/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +package gc.epsilon; + +/** + * @test TestEnoughUnusedSpace + * @requires vm.gc.Epsilon + * @summary Epsilon should allocates object successfully if it has enough space. + * @run main/othervm -Xms64M -Xmx128M -XX:+UnlockExperimentalVMOptions + * -XX:+UseEpsilonGC gc.epsilon.TestEnoughUnusedSpace + */ + +public class TestEnoughUnusedSpace { + static volatile Object arr; + + public static void main(String[] args) { + // Create an array about 90M. It should be created successfully + // instead of throwing OOME, because 90M is smaller than 128M. + arr = new byte[90 * 1024 * 1024]; + } +} From cbd30c952d5079df92dcd1c3148dbf6c1855b75c Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 29 Apr 2024 15:43:14 +0000 Subject: [PATCH 235/298] 8325095: C2: bailout message broken: ResourceArea allocated string used after free Reviewed-by: phh Backport-of: c589555845e61cdde5340aaa76fcc36b2753240d --- src/hotspot/share/ci/ciEnv.cpp | 8 ++- src/hotspot/share/ci/ciEnv.hpp | 7 +-- .../share/compiler/cHeapStringHolder.cpp | 43 ++++++++++++++++ .../share/compiler/cHeapStringHolder.hpp | 50 +++++++++++++++++++ src/hotspot/share/compiler/compileBroker.cpp | 4 +- src/hotspot/share/opto/compile.cpp | 6 +-- src/hotspot/share/opto/compile.hpp | 20 ++++++-- src/hotspot/share/runtime/vmStructs.cpp | 1 - 8 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 src/hotspot/share/compiler/cHeapStringHolder.cpp create mode 100644 src/hotspot/share/compiler/cHeapStringHolder.hpp diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index c05c20dccd7..fa02bc3766c 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -120,7 +120,6 @@ ciEnv::ciEnv(CompileTask* task) _oop_recorder = nullptr; _debug_info = nullptr; _dependencies = nullptr; - _failure_reason = nullptr; _inc_decompile_count_on_failure = true; _compilable = MethodCompilable; _break_at_compile = false; @@ -249,7 +248,6 @@ ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) { _oop_recorder = nullptr; _debug_info = nullptr; _dependencies = nullptr; - _failure_reason = nullptr; _inc_decompile_count_on_failure = true; _compilable = MethodCompilable_never; _break_at_compile = false; @@ -1232,9 +1230,9 @@ int ciEnv::num_inlined_bytecodes() const { // ------------------------------------------------------------------ // ciEnv::record_failure() void ciEnv::record_failure(const char* reason) { - if (_failure_reason == nullptr) { + if (_failure_reason.get() == nullptr) { // Record the first failure reason. - _failure_reason = reason; + _failure_reason.set(reason); } } @@ -1264,7 +1262,7 @@ void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) { _compilable = new_compilable; // Reset failure reason; this one is more important. - _failure_reason = nullptr; + _failure_reason.clear(); record_failure(reason); } } diff --git a/src/hotspot/share/ci/ciEnv.hpp b/src/hotspot/share/ci/ciEnv.hpp index added1ae358..ef3afa3eb70 100644 --- a/src/hotspot/share/ci/ciEnv.hpp +++ b/src/hotspot/share/ci/ciEnv.hpp @@ -33,6 +33,7 @@ #include "code/exceptionHandlerTable.hpp" #include "compiler/compiler_globals.hpp" #include "compiler/compilerThread.hpp" +#include "compiler/cHeapStringHolder.hpp" #include "oops/methodData.hpp" #include "runtime/javaThread.hpp" @@ -57,7 +58,7 @@ class ciEnv : StackObj { OopRecorder* _oop_recorder; DebugInformationRecorder* _debug_info; Dependencies* _dependencies; - const char* _failure_reason; + CHeapStringHolder _failure_reason; bool _inc_decompile_count_on_failure; int _compilable; bool _break_at_compile; @@ -319,10 +320,10 @@ class ciEnv : StackObj { // This is true if the compilation is not going to produce code. // (It is reasonable to retry failed compilations.) - bool failing() { return _failure_reason != nullptr; } + bool failing() const { return _failure_reason.get() != nullptr; } // Reason this compilation is failing, such as "too many basic blocks". - const char* failure_reason() { return _failure_reason; } + const char* failure_reason() const { return _failure_reason.get(); } // Return state of appropriate compatibility int compilable() { return _compilable; } diff --git a/src/hotspot/share/compiler/cHeapStringHolder.cpp b/src/hotspot/share/compiler/cHeapStringHolder.cpp new file mode 100644 index 00000000000..0383e738a47 --- /dev/null +++ b/src/hotspot/share/compiler/cHeapStringHolder.cpp @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +#include "precompiled.hpp" +#include "compiler/cHeapStringHolder.hpp" + +void CHeapStringHolder::set(const char* string) { + clear(); + if (string != nullptr) { + size_t len = strlen(string); + _string = NEW_C_HEAP_ARRAY(char, len + 1, mtCompiler); + ::memcpy(_string, string, len); + _string[len] = 0; // terminating null + } +} + +void CHeapStringHolder::clear() { + if (_string != nullptr) { + FREE_C_HEAP_ARRAY(char, _string); + _string = nullptr; + } +} diff --git a/src/hotspot/share/compiler/cHeapStringHolder.hpp b/src/hotspot/share/compiler/cHeapStringHolder.hpp new file mode 100644 index 00000000000..46659c2a521 --- /dev/null +++ b/src/hotspot/share/compiler/cHeapStringHolder.hpp @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +#ifndef SHARE_COMPILER_CHEAPSTRINGHOLDER_HPP +#define SHARE_COMPILER_CHEAPSTRINGHOLDER_HPP + +#include "memory/allocation.hpp" + +// Holder for a C-Heap allocated String +// The user must ensure that the destructor is called, or at least clear. +class CHeapStringHolder : public StackObj { +private: + char* _string; + +public: + CHeapStringHolder() : _string(nullptr) {} + ~CHeapStringHolder() { clear(); }; + NONCOPYABLE(CHeapStringHolder); + + // Allocate memory to hold a copy of string + void set(const char* string); + + // Release allocated memory + void clear(); + + const char* get() const { return _string; }; +}; + +#endif // SHARE_COMPILER_CHEAPSTRINGHOLDER_HPP diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 8a83a864f62..7bfff15b316 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -2289,7 +2289,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { compilable = ci_env.compilable(); if (ci_env.failing()) { - failure_reason = ci_env.failure_reason(); + // Duplicate the failure reason string, so that it outlives ciEnv + failure_reason = os::strdup(ci_env.failure_reason(), mtCompiler); + failure_reason_on_C_heap = true; retry_message = ci_env.retry_message(); ci_env.report_failure(failure_reason); } diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index b7ed590126f..77fab1daaf7 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -622,7 +622,6 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci, _env(ci_env), _directive(directive), _log(ci_env->log()), - _failure_reason(nullptr), _intrinsics (comp_arena(), 0, 0, nullptr), _macro_nodes (comp_arena(), 8, 0, nullptr), _parse_predicate_opaqs (comp_arena(), 8, 0, nullptr), @@ -919,7 +918,6 @@ Compile::Compile( ciEnv* ci_env, _env(ci_env), _directive(directive), _log(ci_env->log()), - _failure_reason(nullptr), _congraph(nullptr), NOT_PRODUCT(_igv_printer(nullptr) COMMA) _dead_node_list(comp_arena()), @@ -4328,9 +4326,9 @@ void Compile::record_failure(const char* reason) { if (log() != nullptr) { log()->elem("failure reason='%s' phase='compile'", reason); } - if (_failure_reason == nullptr) { + if (_failure_reason.get() == nullptr) { // Record the first failure reason. - _failure_reason = reason; + _failure_reason.set(reason); } if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index e5b881065ac..c843ed27faf 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -32,6 +32,7 @@ #include "compiler/compilerOracle.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compilerEvent.hpp" +#include "compiler/cHeapStringHolder.hpp" #include "libadt/dict.hpp" #include "libadt/vectset.hpp" #include "memory/resourceArea.hpp" @@ -350,7 +351,7 @@ class Compile : public Phase { ciEnv* _env; // CI interface DirectiveSet* _directive; // Compiler directive CompileLog* _log; // from CompilerThread - const char* _failure_reason; // for record_failure/failing pattern + CHeapStringHolder _failure_reason; // for record_failure/failing pattern GrowableArray _intrinsics; // List of intrinsics. GrowableArray _macro_nodes; // List of nodes which need to be expanded before matching. GrowableArray _parse_predicate_opaqs; // List of Opaque1 nodes for the Parse Predicates. @@ -775,11 +776,22 @@ class Compile : public Phase { Arena* comp_arena() { return &_comp_arena; } ciEnv* env() const { return _env; } CompileLog* log() const { return _log; } - bool failing() const { return _env->failing() || _failure_reason != nullptr; } - const char* failure_reason() const { return (_env->failing()) ? _env->failure_reason() : _failure_reason; } + + bool failing() const { + return _env->failing() || + _failure_reason.get() != nullptr; + } + + const char* failure_reason() const { + return _env->failing() ? _env->failure_reason() + : _failure_reason.get(); + } bool failure_reason_is(const char* r) const { - return (r == _failure_reason) || (r != nullptr && _failure_reason != nullptr && strcmp(r, _failure_reason) == 0); + return (r == _failure_reason.get()) || + (r != nullptr && + _failure_reason.get() != nullptr && + strcmp(r, _failure_reason.get()) == 0); } void record_failure(const char* reason); diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 37241534b2b..d11af5cb5af 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -785,7 +785,6 @@ /************/ \ \ nonstatic_field(ciEnv, _compiler_data, void*) \ - nonstatic_field(ciEnv, _failure_reason, const char*) \ nonstatic_field(ciEnv, _factory, ciObjectFactory*) \ nonstatic_field(ciEnv, _dependencies, Dependencies*) \ nonstatic_field(ciEnv, _task, CompileTask*) \ From c922c50bad2c3cd5eadc59f7e99c99c5b2e00ca2 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 29 Apr 2024 16:04:13 +0000 Subject: [PATCH 236/298] 8322962: Upcall stub might go undetected when freezing frames Backport-of: 93feda3d9a1807422c7f47703358aabd2e8639b8 --- .../cpu/aarch64/upcallLinker_aarch64.cpp | 4 ++++ src/hotspot/cpu/ppc/upcallLinker_ppc.cpp | 4 ++++ src/hotspot/cpu/riscv/upcallLinker_riscv.cpp | 4 ++++ src/hotspot/cpu/x86/upcallLinker_x86_64.cpp | 4 ++++ .../share/runtime/continuationFreezeThaw.cpp | 19 +++++++++---------- .../stress/GetStackTraceALotWhenPinned.java | 8 +++++--- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index 57cc9fe6274..45a1af83e8c 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -241,9 +241,13 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ mov_metadata(rmethod, entry); __ str(rmethod, Address(rthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized + __ push_cont_fastpath(rthread); + __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); __ blr(rscratch1); + __ pop_cont_fastpath(rthread); + // return value shuffle if (!needs_return_buffer) { #ifdef ASSERT diff --git a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp index 4cb86ad573c..871c8e08bf5 100644 --- a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp @@ -239,10 +239,14 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ load_const_optimized(R19_method, (intptr_t)entry); __ std(R19_method, in_bytes(JavaThread::callee_target_offset()), R16_thread); + __ push_cont_fastpath(); + __ ld(call_target_address, in_bytes(Method::from_compiled_offset()), R19_method); __ mtctr(call_target_address); __ bctrl(); + __ pop_cont_fastpath(); + // return value shuffle if (!needs_return_buffer) { // CallArranger can pick a return type that goes in the same reg for both CCs. diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index 6d605d716af..4acf4975d3d 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -263,9 +263,13 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ mov_metadata(xmethod, entry); __ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized + __ push_cont_fastpath(xthread); + __ ld(t0, Address(xmethod, Method::from_compiled_offset())); __ jalr(t0); + __ pop_cont_fastpath(xthread); + // return value shuffle if (!needs_return_buffer) { #ifdef ASSERT diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index dfce6aef52d..b687d929364 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -296,8 +296,12 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ mov_metadata(rbx, entry); __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // just in case callee is deoptimized + __ push_cont_fastpath(); + __ call(Address(rbx, Method::from_compiled_offset())); + __ pop_cont_fastpath(); + // return value shuffle if (!needs_return_buffer) { #ifdef ASSERT diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index 662b8ef81f9..0882bc933c2 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -389,7 +389,7 @@ class FreezeBase : public StackObj { inline int size_if_fast_freeze_available(); #ifdef ASSERT - bool interpreted_native_or_deoptimized_on_stack(); + bool check_valid_fast_path(); #endif protected: @@ -1480,7 +1480,10 @@ static bool monitors_on_stack(JavaThread* thread) { return false; } -bool FreezeBase::interpreted_native_or_deoptimized_on_stack() { +// There are no interpreted frames if we're not called from the interpreter and we haven't ancountered an i2c +// adapter or called Deoptimization::unpack_frames. As for native frames, upcalls from JNI also go through the +// interpreter (see JavaCalls::call_helper), while the UpcallLinker explicitly sets cont_fastpath. +bool FreezeBase::check_valid_fast_path() { ContinuationEntry* ce = _thread->last_continuation(); RegisterMap map(_thread, RegisterMap::UpdateMap::skip, @@ -1488,11 +1491,11 @@ bool FreezeBase::interpreted_native_or_deoptimized_on_stack() { RegisterMap::WalkContinuation::skip); map.set_include_argument_oops(false); for (frame f = freeze_start_frame(); Continuation::is_frame_in_continuation(ce, f); f = f.sender(&map)) { - if (f.is_interpreted_frame() || f.is_native_frame() || f.is_deoptimized_frame()) { - return true; + if (!f.is_compiled_frame() || f.is_deoptimized_frame()) { + return false; } } - return false; + return true; } #endif // ASSERT @@ -1554,11 +1557,7 @@ static inline int freeze_internal(JavaThread* current, intptr_t* const sp) { Freeze freeze(current, cont, sp); - // There are no interpreted frames if we're not called from the interpreter and we haven't ancountered an i2c - // adapter or called Deoptimization::unpack_frames. Calls from native frames also go through the interpreter - // (see JavaCalls::call_helper). - assert(!current->cont_fastpath() - || (current->cont_fastpath_thread_state() && !freeze.interpreted_native_or_deoptimized_on_stack()), ""); + assert(!current->cont_fastpath() || freeze.check_valid_fast_path(), ""); bool fast = UseContinuationFastPath && current->cont_fastpath(); if (fast && freeze.size_if_fast_freeze_available() > 0) { freeze.freeze_fast_existing_chunk(); diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java index e00cf89fb8c..35986718a38 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -43,6 +43,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; import jdk.test.lib.thread.VThreadRunner; +import jdk.test.lib.thread.VThreadPinner; public class GetStackTraceALotWhenPinned { @@ -65,13 +66,14 @@ public static void main(String[] args) throws Exception { barrier.await(); Thread.yield(); - synchronized (GetStackTraceALotWhenPinned.class) { - if (timed) { + boolean b = timed; + VThreadPinner.runPinned(() -> { + if (b) { LockSupport.parkNanos(Long.MAX_VALUE); } else { LockSupport.park(); } - } + }); timed = !timed; } }); From 56a90908c379ad8c0be0deafc3c9931144cfdf42 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Tue, 30 Apr 2024 09:00:13 +0000 Subject: [PATCH 237/298] 8312014: [s390x] TestSigInfoInHsErrFile.java Failure Reviewed-by: lucy Backport-of: 6f6621303ad54a7dfd880c9472a387706a4466ff --- src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp | 1 + src/hotspot/cpu/arm/globalDefinitions_arm.hpp | 1 + src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp | 6 ++++++ src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp | 1 + src/hotspot/cpu/s390/globalDefinitions_s390.hpp | 4 ++++ src/hotspot/cpu/x86/globalDefinitions_x86.hpp | 1 + src/hotspot/cpu/zero/globalDefinitions_zero.hpp | 7 +++++++ src/hotspot/share/utilities/vmError.cpp | 1 + src/hotspot/share/utilities/vmError.hpp | 2 +- .../runtime/ErrorHandling/TestSigInfoInHsErrFile.java | 9 ++++++++- 10 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 1146324e19c..2293d70c8da 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -27,6 +27,7 @@ #define CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP const int StackAlignmentInBytes = 16; +const size_t pd_segfault_address = 1024; // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. diff --git a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp index ba180fb0f87..2041cf9e17e 100644 --- a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp +++ b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp @@ -26,6 +26,7 @@ #define CPU_ARM_GLOBALDEFINITIONS_ARM_HPP const int StackAlignmentInBytes = 8; +const size_t pd_segfault_address = 1024; // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. diff --git a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp index 8ac5c39b831..f124477bc32 100644 --- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp +++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp @@ -31,6 +31,12 @@ const int BytesPerInstWord = 4; const int StackAlignmentInBytes = 16; +#ifdef AIX +const size_t pd_segfault_address = -1; +#else +const size_t pd_segfault_address = 1024; +#endif + // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. const bool CCallingConventionRequiresIntsAsLongs = true; diff --git a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp index 2a8cff71c55..f40ffbeefa7 100644 --- a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp +++ b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp @@ -28,6 +28,7 @@ #define CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP const int StackAlignmentInBytes = 16; +const size_t pd_segfault_address = 1024; // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp index 2232215a587..39baf5bf047 100644 --- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp +++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp @@ -30,6 +30,10 @@ const int StackAlignmentInBytes = 8; +// All faults on s390x give the address only on page granularity. +// Set Pdsegfault_address to minimum one page address. +const size_t pd_segfault_address = 4096; + #define SUPPORTS_NATIVE_CX8 #define CPU_MULTI_COPY_ATOMIC diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp index bdf9ac440d0..7eff43471b5 100644 --- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp +++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp @@ -26,6 +26,7 @@ #define CPU_X86_GLOBALDEFINITIONS_X86_HPP const int StackAlignmentInBytes = 16; +const size_t pd_segfault_address = 1024; // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp index ca11d106c26..c0c74e0987a 100644 --- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp +++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp @@ -43,5 +43,12 @@ // Indicates whether the C calling conventions require that // 32-bit integer argument values are extended to 64 bits. const bool CCallingConventionRequiresIntsAsLongs = false; +#if defined(AIX) +const size_t pd_segfault_address = -1; +#elif defined(S390) +const size_t pd_segfault_address = 4096; +#else +const size_t pd_segfault_address = 1024; +#endif #endif // CPU_ZERO_GLOBALDEFINITIONS_ZERO_HPP diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 5c0b4440e2c..868c67a7dbc 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -100,6 +100,7 @@ const char* VMError::_filename; int VMError::_lineno; size_t VMError::_size; const size_t VMError::_reattempt_required_stack_headroom = 64 * K; +const intptr_t VMError::segfault_address = pd_segfault_address; // List of environment variables that should be reported in error log file. static const char* env_list[] = { diff --git a/src/hotspot/share/utilities/vmError.hpp b/src/hotspot/share/utilities/vmError.hpp index 5a0625c920b..88ba476891e 100644 --- a/src/hotspot/share/utilities/vmError.hpp +++ b/src/hotspot/share/utilities/vmError.hpp @@ -207,7 +207,7 @@ class VMError : public AllStatic { DEBUG_ONLY(static void controlled_crash(int how);) // Non-null address guaranteed to generate a SEGV mapping error on read, for test purposes. - static constexpr intptr_t segfault_address = AIX_ONLY(-1) NOT_AIX(1 * K); + static const intptr_t segfault_address; // Max value for the ErrorLogPrintCodeLimit flag. static const int max_error_log_print_code = 10; diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestSigInfoInHsErrFile.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestSigInfoInHsErrFile.java index 7d6a18f6cdb..e53757a29f3 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestSigInfoInHsErrFile.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestSigInfoInHsErrFile.java @@ -69,7 +69,14 @@ public static void main(String[] args) throws Exception { patterns.add(Pattern.compile("# .*VMError::controlled_crash.*")); // Crash address: see VMError::_segfault_address - String crashAddress = Platform.isAix() ? "0xffffffffffffffff" : "0x0*400"; + String crashAddress = "0x0*400"; + if (Platform.isAix()) { + crashAddress = "0xffffffffffffffff"; + } else if (Platform.isS390x()) { + // All faults on s390x give the address only on page granularity. + // Hence fault address is first page address. + crashAddress = "0x0*1000"; + } patterns.add(Pattern.compile("siginfo: si_signo: \\d+ \\(SIGSEGV\\), si_code: \\d+ \\(SEGV_.*\\), si_addr: " + crashAddress + ".*")); HsErrFileUtils.checkHsErrFileContent(f, patterns.toArray(new Pattern[] {}), true); From 5d5c67898a3d3f198fb452ffe569dc93834aa90f Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 30 Apr 2024 14:03:17 +0000 Subject: [PATCH 238/298] 8319713: Parallel: Remove PSAdaptiveSizePolicy::should_full_GC Backport-of: 4bcda602668835c35e2ac6ff6702d15cd249bc2a --- .../share/gc/parallel/psAdaptiveSizePolicy.cpp | 16 ---------------- .../share/gc/parallel/psAdaptiveSizePolicy.hpp | 4 ---- src/hotspot/share/gc/parallel/psScavenge.cpp | 5 +---- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp index f97727c8bc8..e5817ca6f5c 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp @@ -169,22 +169,6 @@ void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live, _major_timer.start(); } -// If the remaining free space in the old generation is less that -// that expected to be needed by the next collection, do a full -// collection now. -bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) { - - // A similar test is done in the scavenge's should_attempt_scavenge(). If - // this is changed, decide if that test should also be changed. - bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes; - log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT, - result ? "Full" : "No full", - (size_t) average_promoted_in_bytes(), - (size_t) padded_average_promoted_in_bytes(), - old_free_in_bytes); - return result; -} - void PSAdaptiveSizePolicy::clear_generation_free_space_flags() { AdaptiveSizePolicy::clear_generation_free_space_flags(); diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp index c39514922fc..1b058e2dd29 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp @@ -306,10 +306,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { } float major_collection_slope() { return _major_collection_estimator->slope();} - // Given the amount of live data in the heap, should we - // perform a Full GC? - bool should_full_GC(size_t live_in_old_gen); - // Calculates optimal (free) space sizes for both the young and old // generations. Stores results in _eden_size and _promo_size. // Takes current used space in all generations as input, as well diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 6c35ed6b593..1bfba37735f 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -239,8 +239,7 @@ bool PSScavenge::invoke() { IsGCActiveMark mark; const bool scavenge_done = PSScavenge::invoke_no_policy(); - const bool need_full_gc = !scavenge_done || - policy->should_full_GC(heap->old_gen()->free_in_bytes()); + const bool need_full_gc = !scavenge_done; bool full_gc_done = false; if (UsePerfData) { @@ -707,8 +706,6 @@ bool PSScavenge::should_attempt_scavenge() { // Test to see if the scavenge will likely fail. PSAdaptiveSizePolicy* policy = heap->size_policy(); - // A similar test is done in the policy's should_full_GC(). If this is - // changed, decide if that test should also be changed. size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); bool result = promotion_estimate < old_gen->free_in_bytes(); From 3ab3f52b2799e75bdd32d0ee105be80d88312082 Mon Sep 17 00:00:00 2001 From: Bernhard Urban-Forster Date: Tue, 30 Apr 2024 19:35:53 +0000 Subject: [PATCH 239/298] 8326974: ODR violation in macroAssembler_aarch64.cpp Backport-of: b972997af76a506ffd79ee8c6043e7a8db836b33 --- src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 5a90cf189ce..1343e7d4f26 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -389,13 +389,13 @@ static bool offset_for(uint32_t insn1, uint32_t insn2, ptrdiff_t &byte_offset) { return false; } -class Decoder : public RelocActions { - virtual reloc_insn adrpMem() { return &Decoder::adrpMem_impl; } - virtual reloc_insn adrpAdd() { return &Decoder::adrpAdd_impl; } - virtual reloc_insn adrpMovk() { return &Decoder::adrpMovk_impl; } +class AArch64Decoder : public RelocActions { + virtual reloc_insn adrpMem() { return &AArch64Decoder::adrpMem_impl; } + virtual reloc_insn adrpAdd() { return &AArch64Decoder::adrpAdd_impl; } + virtual reloc_insn adrpMovk() { return &AArch64Decoder::adrpMovk_impl; } public: - Decoder(address insn_addr, uint32_t insn) : RelocActions(insn_addr, insn) {} + AArch64Decoder(address insn_addr, uint32_t insn) : RelocActions(insn_addr, insn) {} virtual int loadStore(address insn_addr, address &target) { intptr_t offset = Instruction_aarch64::sextract(_insn, 23, 5); @@ -491,7 +491,7 @@ class Decoder : public RelocActions { }; address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) { - Decoder decoder(insn_addr, insn); + AArch64Decoder decoder(insn_addr, insn); address target; decoder.run(insn_addr, target); return target; From 3892078094735be9d8074d23ce3d70201cd60445 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 2 May 2024 08:27:12 +0000 Subject: [PATCH 240/298] 8324121: SIGFPE in PhaseIdealLoop::extract_long_range_checks 8329163: C2: possible overflow in PhaseIdealLoop::extract_long_range_checks() Backport-of: cb2a6713596548d76c03912709656172b0bbcc76 --- src/hotspot/share/opto/loopnode.cpp | 17 +++--- src/hotspot/share/opto/loopnode.hpp | 4 +- .../TestLargeScaleInLongRCOverflow.java | 59 +++++++++++++++++++ 3 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/rangechecks/TestLargeScaleInLongRCOverflow.java diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index e102d9ac9e9..52467e75010 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -801,13 +801,14 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { } #endif - jlong stride_con = head->stride_con(); - assert(stride_con != 0, "missed some peephole opt"); + jlong stride_con_long = head->stride_con(); + assert(stride_con_long != 0, "missed some peephole opt"); // We can't iterate for more than max int at a time. - if (stride_con != (jint)stride_con) { + if (stride_con_long != (jint)stride_con_long || stride_con_long == min_jint) { assert(bt == T_LONG, "only for long loops"); return false; } + jint stride_con = checked_cast(stride_con_long); // The number of iterations for the integer count loop: guarantee no // overflow: max_jint - stride_con max. -1 so there's no need for a // loop limit check if the exit test is <= or >=. @@ -945,7 +946,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { } // Clone the iv data nodes as an integer iv - Node* int_stride = _igvn.intcon(checked_cast(stride_con)); + Node* int_stride = _igvn.intcon(stride_con); set_ctrl(int_stride, C->root()); Node* inner_phi = new PhiNode(x->in(0), TypeInt::INT); Node* inner_incr = new AddINode(inner_phi, int_stride); @@ -1040,7 +1041,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { register_new_node(outer_phi, outer_head); } - transform_long_range_checks(checked_cast(stride_con), range_checks, outer_phi, inner_iters_actual_int, + transform_long_range_checks(stride_con, range_checks, outer_phi, inner_iters_actual_int, inner_phi, iv_add, inner_head); // Peel one iteration of the loop and use the safepoint at the end // of the peeled iteration to insert Parse Predicates. If no well @@ -1077,7 +1078,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { return true; } -int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jlong stride_con, int iters_limit, PhiNode* phi, +int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jint stride_con, int iters_limit, PhiNode* phi, Node_List& range_checks) { const jlong min_iters = 2; jlong reduced_iters_limit = iters_limit; @@ -1093,7 +1094,9 @@ int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jlong s jlong scale = 0; if (loop->is_range_check_if(if_proj, this, T_LONG, phi, range, offset, scale) && loop->is_invariant(range) && loop->is_invariant(offset) && - original_iters_limit / ABS(scale * stride_con) >= min_iters) { + scale != min_jlong && + original_iters_limit / ABS(scale) >= min_iters * ABS(stride_con)) { + assert(scale == (jint)scale, "scale should be an int"); reduced_iters_limit = MIN2(reduced_iters_limit, original_iters_limit/ABS(scale)); range_checks.push(c); } diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 6d44434d71e..868a4fd153c 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1695,8 +1695,8 @@ class PhaseIdealLoop : public PhaseTransform { LoopNode* create_inner_head(IdealLoopTree* loop, BaseCountedLoopNode* head, IfNode* exit_test); - int extract_long_range_checks(const IdealLoopTree* loop, jlong stride_con, int iters_limit, PhiNode* phi, - Node_List &range_checks); + int extract_long_range_checks(const IdealLoopTree* loop, jint stride_con, int iters_limit, PhiNode* phi, + Node_List &range_checks); void transform_long_range_checks(int stride_con, const Node_List &range_checks, Node* outer_phi, Node* inner_iters_actual_int, Node* inner_phi, diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestLargeScaleInLongRCOverflow.java b/test/hotspot/jtreg/compiler/rangechecks/TestLargeScaleInLongRCOverflow.java new file mode 100644 index 00000000000..c762b0e2fd7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/rangechecks/TestLargeScaleInLongRCOverflow.java @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8324121 + * @summary SIGFPE in PhaseIdealLoop::extract_long_range_checks + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestLargeScaleInLongRCOverflow::test* -XX:-TieredCompilation TestLargeScaleInLongRCOverflow + * + */ + +import java.util.Objects; + +public class TestLargeScaleInLongRCOverflow { + + public static void main(String args[]) { + Objects.checkIndex(0, 1); + try { + test1(); + } catch (java.lang.IndexOutOfBoundsException e) { } + try { + test2(); + } catch (java.lang.IndexOutOfBoundsException e) { } + } + + // SIGFPE in PhaseIdealLoop::extract_long_range_checks + public static void test1() { + for (long i = 1; i < 100; i += 2) { + Objects.checkIndex(Long.MIN_VALUE * i, 10); + } + } + + // "assert(static_cast(result) == thing) failed: must be" in PhaseIdealLoop::transform_long_range_checks + public static void test2() { + for (long i = 1; i < 100; i += 2) { + Objects.checkIndex((Long.MIN_VALUE + 2) * i, 10); + } + } +} From 87d5da4f4f61bde5125b2534cd059a5772f991b7 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 2 May 2024 12:27:14 +0000 Subject: [PATCH 241/298] 8328822: C2: "negative trip count?" assert failure in profile predicate code Backport-of: 2ceeb6c00135310b7bdabacb92d26d81de525240 --- src/hotspot/share/opto/loopPredicate.cpp | 2 +- .../TestCountedLoopMinJintStride.java | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/predicates/TestCountedLoopMinJintStride.java diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 9ae24cb2055..fa39301cbef 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -1146,7 +1146,7 @@ bool PhaseIdealLoop::loop_predication_should_follow_branches(IdealLoopTree* loop CountedLoopNode* cl = head->as_CountedLoop(); if (cl->phi() != nullptr) { const TypeInt* t = _igvn.type(cl->phi())->is_int(); - float worst_case_trip_cnt = ((float)t->_hi - t->_lo) / ABS(cl->stride_con()); + float worst_case_trip_cnt = ((float)t->_hi - t->_lo) / ABS((float)cl->stride_con()); if (worst_case_trip_cnt < loop_trip_cnt) { loop_trip_cnt = worst_case_trip_cnt; } diff --git a/test/hotspot/jtreg/compiler/predicates/TestCountedLoopMinJintStride.java b/test/hotspot/jtreg/compiler/predicates/TestCountedLoopMinJintStride.java new file mode 100644 index 00000000000..62bfc60cc73 --- /dev/null +++ b/test/hotspot/jtreg/compiler/predicates/TestCountedLoopMinJintStride.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8328822 + * @summary C2: "negative trip count?" assert failure in profile predicate code + * @run main/othervm -XX:-BackgroundCompilation TestCountedLoopMinJintStride + */ + +import java.util.Objects; + +public class TestCountedLoopMinJintStride { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test1(Integer.MAX_VALUE-1, Integer.MAX_VALUE, 0); + testHelper1(100, -1, Integer.MAX_VALUE, 0); + test2(Integer.MAX_VALUE-1, Integer.MAX_VALUE, 0); + testHelper2(100, -1, Integer.MAX_VALUE, 0); + } + } + + private static void test1(int stop, int range, int start) { + testHelper1(stop, Integer.MIN_VALUE, range, start); + } + + private static void testHelper1(int stop, int stride, int range, int start) { + for (int i = stop; i >= start; i += stride) { + Objects.checkIndex(i, range); + } + } + + private static void test2(int stop, int range, int start) { + testHelper1(stop, Integer.MIN_VALUE, range, start); + } + + private static void testHelper2(int stop, int stride, int range, int start) { + for (int i = stop; i >= start; i += stride) { + if (i < 0 || i >= range) { + throw new RuntimeException("out of bounds"); + } + } + } +} From a4d8d061a8a694502a085b444a480fa3211a07dc Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 2 May 2024 14:14:09 +0000 Subject: [PATCH 242/298] 8328744: Parallel: Parallel GC throws OOM before heap is fully expanded Backport-of: bf8146eac24ba8e00d1794ef7134ecf2476cf897 --- src/hotspot/share/gc/parallel/psScavenge.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 1bfba37735f..7da789261c0 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -708,12 +708,14 @@ bool PSScavenge::should_attempt_scavenge() { size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); - bool result = promotion_estimate < old_gen->free_in_bytes(); + // Total free size after possible old gen expansion + size_t free_in_old_gen = old_gen->max_gen_size() - old_gen->used_in_bytes(); + bool result = promotion_estimate < free_in_old_gen; log_trace(ergo)("%s scavenge: average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT, result ? "Do" : "Skip", (size_t) policy->average_promoted_in_bytes(), (size_t) policy->padded_average_promoted_in_bytes(), - old_gen->free_in_bytes()); + free_in_old_gen); if (young_gen->used_in_bytes() < (size_t) policy->padded_average_promoted_in_bytes()) { log_trace(ergo)(" padded_promoted_average is greater than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes()); } From 3bb8eeed4817d490a1089aa567434af3f303c4f8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 3 May 2024 06:22:47 +0000 Subject: [PATCH 243/298] 8317809: Insertion of free code blobs into code cache can be very slow during class unloading Reviewed-by: phh, adinn Backport-of: 30817b742300f10f566e6aee3a8c1f8af4ab3083 --- .../share/classfile/classLoaderData.cpp | 2 +- .../share/classfile/classLoaderData.hpp | 14 +- .../share/classfile/classLoaderDataGraph.cpp | 26 +-- .../share/classfile/classLoaderDataGraph.hpp | 2 - src/hotspot/share/code/codeBlob.cpp | 4 +- src/hotspot/share/code/codeBlob.hpp | 2 +- src/hotspot/share/code/codeCache.cpp | 36 +--- src/hotspot/share/code/codeCache.hpp | 4 +- src/hotspot/share/code/compiledMethod.hpp | 2 +- src/hotspot/share/code/nmethod.cpp | 17 +- src/hotspot/share/code/nmethod.hpp | 8 +- src/hotspot/share/compiler/compileBroker.cpp | 2 +- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 34 +++- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 2 + src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 31 +--- src/hotspot/share/gc/g1/g1FullCollector.cpp | 13 +- .../share/gc/parallel/psParallelCompact.cpp | 26 ++- src/hotspot/share/gc/serial/genMarkSweep.cpp | 14 +- .../share/gc/shared/classUnloadingContext.cpp | 174 ++++++++++++++++++ .../share/gc/shared/classUnloadingContext.hpp | 77 ++++++++ .../share/gc/shared/genCollectedHeap.cpp | 6 +- .../gc/shenandoah/shenandoahCodeRoots.cpp | 3 +- .../share/gc/shenandoah/shenandoahHeap.cpp | 8 +- .../share/gc/shenandoah/shenandoahUnload.cpp | 6 +- src/hotspot/share/gc/x/xHeap.cpp | 4 + src/hotspot/share/gc/x/xNMethod.cpp | 3 +- src/hotspot/share/gc/z/zGeneration.cpp | 4 + src/hotspot/share/gc/z/zNMethod.cpp | 3 +- 28 files changed, 396 insertions(+), 131 deletions(-) create mode 100644 src/hotspot/share/gc/shared/classUnloadingContext.cpp create mode 100644 src/hotspot/share/gc/shared/classUnloadingContext.hpp diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index ca6b58d6530..be91f26bdef 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -599,7 +599,7 @@ void ClassLoaderData::unload() { free_deallocate_list_C_heap_structures(); // Clean up class dependencies and tell serviceability tools - // these classes are unloading. Must be called + // these classes are unloading. This must be called // after erroneous classes are released. classes_do(InstanceKlass::unload_class); diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index 6b5cfdc0664..c9d025aded1 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -186,12 +186,16 @@ class ClassLoaderData : public CHeapObj { ClassLoaderData* next() const; void unlink_next(); - void set_unloading_next(ClassLoaderData* unloading_next); - ClassLoaderData* unloading_next() const; - ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder); + +public: ~ClassLoaderData(); + void set_unloading_next(ClassLoaderData* unloading_next); + ClassLoaderData* unloading_next() const; + void unload(); + +private: // The CLD are not placed in the Heap, so the Card Table or // the Mod Union Table can't be used to mark when CLD have modified oops. // The CT and MUT bits saves this information for the whole class loader data. @@ -203,11 +207,11 @@ class ClassLoaderData : public CHeapObj { oop holder_no_keepalive() const; oop holder() const; + void classes_do(void f(Klass* const)); + private: - void unload(); bool keep_alive() const { return _keep_alive > 0; } - void classes_do(void f(Klass* const)); void loaded_classes_do(KlassClosure* klass_closure); void classes_do(void f(InstanceKlass*)); void methods_do(void f(Method*)); diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index ded67718929..2046286651e 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -31,6 +31,7 @@ #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "code/dependencyContext.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" @@ -124,7 +125,6 @@ void ClassLoaderDataGraph::walk_metadata_and_clean_metaspaces() { // List head of all class loader data. ClassLoaderData* volatile ClassLoaderDataGraph::_head = nullptr; -ClassLoaderData* ClassLoaderDataGraph::_unloading_head = nullptr; bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false; bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false; @@ -342,11 +342,7 @@ void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) { } void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) { - assert_locked_or_safepoint(ClassLoaderDataGraph_lock); - for (ClassLoaderData* cld = _unloading_head; cld != nullptr; cld = cld->unloading_next()) { - assert(cld->is_unloading(), "invariant"); - cld->classes_do(f); - } + ClassUnloadingContext::context()->classes_unloading_do(f); } void ClassLoaderDataGraph::verify_dictionary() { @@ -425,7 +421,8 @@ bool ClassLoaderDataGraph::do_unloading() { } else { // Found dead CLD. loaders_removed++; - data->unload(); + + ClassUnloadingContext::context()->register_unloading_class_loader_data(data); // Move dead CLD to unloading list. if (prev != nullptr) { @@ -435,8 +432,6 @@ bool ClassLoaderDataGraph::do_unloading() { // The GC might be walking this concurrently Atomic::store(&_head, data->next()); } - data->set_unloading_next(_unloading_head); - _unloading_head = data; } } @@ -469,16 +464,9 @@ void ClassLoaderDataGraph::clean_module_and_package_info() { } void ClassLoaderDataGraph::purge(bool at_safepoint) { - ClassLoaderData* list = _unloading_head; - _unloading_head = nullptr; - ClassLoaderData* next = list; - bool classes_unloaded = false; - while (next != nullptr) { - ClassLoaderData* purge_me = next; - next = purge_me->unloading_next(); - delete purge_me; - classes_unloaded = true; - } + ClassUnloadingContext::context()->purge_class_loader_data(); + + bool classes_unloaded = ClassUnloadingContext::context()->has_unloaded_classes(); Metaspace::purge(classes_unloaded); if (classes_unloaded) { diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp index ae502b6d30d..3de2c10850e 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp @@ -43,8 +43,6 @@ class ClassLoaderDataGraph : public AllStatic { private: // All CLDs (except unlinked CLDs) can be reached by walking _head->_next->... static ClassLoaderData* volatile _head; - // All unlinked CLDs - static ClassLoaderData* _unloading_head; // Set if there's anything to purge in the deallocate lists or previous versions // during a safepoint after class unloading in a full GC. diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index a384edc936f..058ac24e167 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -164,7 +164,7 @@ RuntimeBlob::RuntimeBlob( void RuntimeBlob::free(RuntimeBlob* blob) { assert(blob != nullptr, "caller must check for nullptr"); ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock - blob->flush(); + blob->purge(); { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); @@ -173,7 +173,7 @@ void RuntimeBlob::free(RuntimeBlob* blob) { MemoryService::track_code_cache_memory_usage(); } -void CodeBlob::flush() { +void CodeBlob::purge(bool free_code_cache_data) { if (_oop_maps != nullptr) { delete _oop_maps; _oop_maps = nullptr; diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 6c40fe992ae..719ca57b30f 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -143,7 +143,7 @@ class CodeBlob { static unsigned int align_code_offset(int offset); // Deletion - virtual void flush(); + virtual void purge(bool free_code_cache_data = true); // Typing virtual bool is_buffer_blob() const { return false; } diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index d2ee5c36317..9b0bdc3643d 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -37,6 +37,7 @@ #include "compiler/compilerDefinitions.inline.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.hpp" #include "jfr/jfrEvents.hpp" #include "jvm_io.h" @@ -606,7 +607,7 @@ void CodeCache::free(CodeBlob* cb) { cb->~CodeBlob(); // Get heap for given CodeBlob and deallocate - get_code_heap(cb)->deallocate(cb); + heap->deallocate(cb); assert(heap->blob_count() >= 0, "sanity check"); } @@ -970,36 +971,8 @@ void CodeCache::purge_exception_caches() { _exception_cache_purge_list = nullptr; } -// Register an is_unloading nmethod to be flushed after unlinking -void CodeCache::register_unlinked(nmethod* nm) { - assert(nm->unlinked_next() == nullptr, "Only register for unloading once"); - for (;;) { - // Only need acquire when reading the head, when the next - // pointer is walked, which it is not here. - nmethod* head = Atomic::load(&_unlinked_head); - nmethod* next = head != nullptr ? head : nm; // Self looped means end of list - nm->set_unlinked_next(next); - if (Atomic::cmpxchg(&_unlinked_head, head, nm) == head) { - break; - } - } -} - -// Flush all the nmethods the GC unlinked -void CodeCache::flush_unlinked_nmethods() { - nmethod* nm = _unlinked_head; - _unlinked_head = nullptr; - size_t freed_memory = 0; - while (nm != nullptr) { - nmethod* next = nm->unlinked_next(); - freed_memory += nm->total_size(); - nm->flush(); - if (next == nm) { - // Self looped means end of list - break; - } - nm = next; - } +// Restart compiler if possible and required.. +void CodeCache::maybe_restart_compiler(size_t freed_memory) { // Try to start the compiler again if we freed any memory if (!CompileBroker::should_compile_new_jobs() && freed_memory != 0) { @@ -1013,7 +986,6 @@ void CodeCache::flush_unlinked_nmethods() { } uint8_t CodeCache::_unloading_cycle = 1; -nmethod* volatile CodeCache::_unlinked_head = nullptr; void CodeCache::increment_unloading_cycle() { // 2-bit value (see IsUnloadingState in nmethod.cpp for details) diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 403eacdfab3..fbcaefd2a62 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -106,7 +106,6 @@ class CodeCache : AllStatic { static TruncatedSeq _unloading_gc_intervals; static TruncatedSeq _unloading_allocation_rates; static volatile bool _unloading_threshold_gc_requested; - static nmethod* volatile _unlinked_head; static ExceptionCache* volatile _exception_cache_purge_list; @@ -213,8 +212,7 @@ class CodeCache : AllStatic { // nmethod::is_cold. static void arm_all_nmethods(); - static void flush_unlinked_nmethods(); - static void register_unlinked(nmethod* nm); + static void maybe_restart_compiler(size_t freed_memory); static void do_unloading(bool unloading_occurred); static uint8_t unloading_cycle() { return _unloading_cycle; } diff --git a/src/hotspot/share/code/compiledMethod.hpp b/src/hotspot/share/code/compiledMethod.hpp index 912ca1b3f88..4bcda08ec99 100644 --- a/src/hotspot/share/code/compiledMethod.hpp +++ b/src/hotspot/share/code/compiledMethod.hpp @@ -174,7 +174,7 @@ class CompiledMethod : public CodeBlob { void* _gc_data; - virtual void flush() = 0; + virtual void purge(bool free_code_cache_data = true) = 0; private: DeoptimizationStatus deoptimization_status() const { diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index ce516b8aef1..1b328597b7f 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -42,6 +42,7 @@ #include "compiler/oopMap.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.hpp" #include "interpreter/bytecode.hpp" #include "jvm.h" @@ -639,7 +640,7 @@ nmethod::nmethod( ByteSize basic_lock_sp_offset, OopMapSet* oop_maps ) : CompiledMethod(method, "native nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), - _unlinked_next(nullptr), + _is_unlinked(false), _native_receiver_sp_offset(basic_lock_owner_sp_offset), _native_basic_lock_sp_offset(basic_lock_sp_offset), _is_unloading_state(0) @@ -783,7 +784,7 @@ nmethod::nmethod( #endif ) : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), - _unlinked_next(nullptr), + _is_unlinked(false), _native_receiver_sp_offset(in_ByteSize(-1)), _native_basic_lock_sp_offset(in_ByteSize(-1)), _is_unloading_state(0) @@ -1406,7 +1407,7 @@ bool nmethod::make_not_entrant() { // For concurrent GCs, there must be a handshake between unlink and flush void nmethod::unlink() { - if (_unlinked_next != nullptr) { + if (_is_unlinked) { // Already unlinked. It can be invoked twice because concurrent code cache // unloading might need to restart when inline cache cleaning fails due to // running out of ICStubs, which can only be refilled at safepoints @@ -1440,10 +1441,10 @@ void nmethod::unlink() { // Register for flushing when it is safe. For concurrent class unloading, // that would be after the unloading handshake, and for STW class unloading // that would be when getting back to the VM thread. - CodeCache::register_unlinked(this); + ClassUnloadingContext::context()->register_unlinked_nmethod(this); } -void nmethod::flush() { +void nmethod::purge(bool free_code_cache_data) { MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); // completely deallocate this method @@ -1466,8 +1467,10 @@ void nmethod::flush() { Universe::heap()->unregister_nmethod(this); CodeCache::unregister_old_nmethod(this); - CodeBlob::flush(); - CodeCache::free(this); + CodeBlob::purge(); + if (free_code_cache_data) { + CodeCache::free(this); + } } oop nmethod::oop_at(int index) const { diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index cbe2bbb65a9..3be50e28e15 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -196,7 +196,7 @@ class nmethod : public CompiledMethod { address _verified_entry_point; // entry point without class check address _osr_entry_point; // entry point for on stack replacement - nmethod* _unlinked_next; + bool _is_unlinked; // Shared fields for all nmethod's int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method @@ -441,8 +441,8 @@ class nmethod : public CompiledMethod { virtual bool is_unloading(); virtual void do_unloading(bool unloading_occurred); - nmethod* unlinked_next() const { return _unlinked_next; } - void set_unlinked_next(nmethod* next) { _unlinked_next = next; } + bool is_unlinked() const { return _is_unlinked; } + void set_is_unlinked() { assert(!_is_unlinked, "already unlinked"); _is_unlinked = true; } #if INCLUDE_RTM_OPT // rtm state accessing and manipulating @@ -522,7 +522,7 @@ class nmethod : public CompiledMethod { void unlink(); // Deallocate this nmethod - called by the GC - void flush(); + void purge(bool free_code_cache_data = true); // See comment at definition of _last_seen_on_stack void mark_as_maybe_on_stack(); diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 7bfff15b316..c8a5df23b49 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1775,7 +1775,7 @@ bool CompileBroker::init_compiler_runtime() { void CompileBroker::free_buffer_blob_if_allocated(CompilerThread* thread) { BufferBlob* blob = thread->get_buffer_blob(); if (blob != nullptr) { - blob->flush(); + blob->purge(); MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 1f95f2a9ea9..6fc044939b8 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/metadataOnStackMark.hpp" -#include "classfile/stringTable.hpp" +#include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "compiler/oopMap.hpp" @@ -74,6 +74,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" #include "gc/g1/heapRegionSet.inline.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/shared/gcBehaviours.hpp" #include "gc/shared/gcHeapSummary.hpp" @@ -855,10 +856,6 @@ void G1CollectedHeap::verify_before_full_collection() { } void G1CollectedHeap::prepare_for_mutator_after_full_collection() { - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - DEBUG_ONLY(MetaspaceUtils::verify();) - // Prepare heap for normal collections. assert(num_free_regions() == 0, "we should not have added any free regions"); rebuild_region_sets(false /* free_list_only */); @@ -2596,6 +2593,33 @@ void G1CollectedHeap::complete_cleaning(bool class_unloading_occurred) { workers()->run_task(&unlink_task); } +void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjectClosure* is_alive, GCTimer* timer) { + GCTraceTime(Debug, gc, phases) debug(description, timer); + + ClassUnloadingContext ctx(workers()->active_workers(), + false /* lock_codeblob_free_separately */); + { + CodeCache::UnlinkingScope scope(is_alive); + bool unloading_occurred = SystemDictionary::do_unloading(timer); + GCTraceTime(Debug, gc, phases) t("G1 Complete Cleaning", timer); + complete_cleaning(unloading_occurred); + } + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", timer); + ctx.purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", timer); + ctx.free_code_blobs(); + } + { + GCTraceTime(Debug, gc, phases) t("Purge Class Loader Data", timer); + ClassLoaderDataGraph::purge(true /* at_safepoint */); + DEBUG_ONLY(MetaspaceUtils::verify();) + } +} + + bool G1STWSubjectToDiscoveryClosure::do_object_b(oop obj) { assert(obj != nullptr, "must not be null"); assert(_g1h->is_in_reserved(obj), "Trying to discover obj " PTR_FORMAT " not in heap", p2i(obj)); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index e1b95bf616d..9d4566916ff 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1265,6 +1265,8 @@ class G1CollectedHeap : public CollectedHeap { // Performs cleaning of data structures after class unloading. void complete_cleaning(bool class_unloading_occurred); + void unload_classes_and_code(const char* description, BoolObjectClosure* cl, GCTimer* timer); + // Verification // Perform any cleanup actions necessary before allowing a verification. diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index b040c1f4656..fb773a025e7 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -25,8 +25,6 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" -#include "classfile/systemDictionary.hpp" -#include "code/codeCache.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BatchedTask.hpp" #include "gc/g1/g1CardSetMemory.hpp" @@ -1245,6 +1243,12 @@ void G1ConcurrentMark::remark() { if (mark_finished) { weak_refs_work(); + // Unload Klasses, String, Code Cache, etc. + if (ClassUnloadingWithConcurrentMark) { + G1CMIsAliveClosure is_alive(_g1h); + _g1h->unload_classes_and_code("Class Unloading", &is_alive, _gc_timer_cm); + } + SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set(); // We're done with marking. // This is the end of the marking cycle, we're expected all @@ -1282,12 +1286,6 @@ void G1ConcurrentMark::remark() { reclaim_empty_regions(); } - // Clean out dead classes - if (ClassUnloadingWithConcurrentMark) { - GCTraceTime(Debug, gc, phases) debug("Purge Metaspace", _gc_timer_cm); - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - } - _g1h->resize_heap_if_necessary(); _g1h->uncommit_regions_if_necessary(); @@ -1612,9 +1610,6 @@ class G1CMRefProcProxyTask : public RefProcProxyTask { void G1ConcurrentMark::weak_refs_work() { ResourceMark rm; - // Is alive closure. - G1CMIsAliveClosure g1_is_alive(_g1h); - { GCTraceTime(Debug, gc, phases) debug("Reference Processing", _gc_timer_cm); @@ -1671,18 +1666,8 @@ void G1ConcurrentMark::weak_refs_work() { { GCTraceTime(Debug, gc, phases) debug("Weak Processing", _gc_timer_cm); - WeakProcessor::weak_oops_do(_g1h->workers(), &g1_is_alive, &do_nothing_cl, 1); - } - - // Unload Klasses, String, Code Cache, etc. - if (ClassUnloadingWithConcurrentMark) { - GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm); - { - CodeCache::UnlinkingScope scope(&g1_is_alive); - bool unloading_occurred = SystemDictionary::do_unloading(_gc_timer_cm); - _g1h->complete_cleaning(unloading_occurred); - } - CodeCache::flush_unlinked_nmethods(); + G1CMIsAliveClosure is_alive(_g1h); + WeakProcessor::weak_oops_do(_g1h->workers(), &is_alive, &do_nothing_cl, 1); } } diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 62e7cdfabd4..df1afe0d3e9 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -24,9 +24,6 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" -#include "classfile/systemDictionary.hpp" -#include "code/codeCache.hpp" -#include "compiler/oopMap.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCAdjustTask.hpp" @@ -41,6 +38,7 @@ #include "gc/g1/g1RegionMarkStatsCache.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/verifyOption.hpp" #include "gc/shared/weakProcessor.inline.hpp" @@ -319,14 +317,7 @@ void G1FullCollector::phase1_mark_live_objects() { // Class unloading and cleanup. if (ClassUnloading) { - GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer()); - { - CodeCache::UnlinkingScope unloading_scope(&_is_alive); - // Unload classes and purge the SystemDictionary. - bool unloading_occurred = SystemDictionary::do_unloading(scope()->timer()); - _heap->complete_cleaning(unloading_occurred); - } - CodeCache::flush_unlinked_nmethods(); + _heap->unload_classes_and_code("Phase 1: Class Unloading and Cleanup", &_is_alive, scope()->timer()); } { diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 532031a2102..9baf0c21db6 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -42,6 +42,7 @@ #include "gc/parallel/psScavenge.hpp" #include "gc/parallel/psStringDedup.hpp" #include "gc/parallel/psYoungGen.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcId.hpp" @@ -1024,9 +1025,12 @@ void PSParallelCompact::post_compact() ct->dirty_MemRegion(old_mr); } - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - DEBUG_ONLY(MetaspaceUtils::verify();) + { + // Delete metaspaces for unloaded class loaders and clean up loader_data graph + GCTraceTime(Debug, gc, phases) t("Purge Class Loader Data", gc_timer()); + ClassLoaderDataGraph::purge(true /* at_safepoint */); + DEBUG_ONLY(MetaspaceUtils::verify();) + } // Need to clear claim bits for the next mark. ClassLoaderDataGraph::clear_claimed_marks(); @@ -1764,6 +1768,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ref_processor()->start_discovery(maximum_heap_compaction); + ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* lock_codeblob_free_separately */); + marking_phase(&_gc_tracer); bool max_on_system_gc = UseMaximumCompactionOnSystemGC @@ -2053,6 +2060,8 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer); + ClassUnloadingContext* ctx = ClassUnloadingContext::context(); + bool unloading_occurred; { CodeCache::UnlinkingScope scope(is_alive_closure()); @@ -2064,8 +2073,15 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { CodeCache::do_unloading(unloading_occurred); } - // Release unloaded nmethods's memory. - CodeCache::flush_unlinked_nmethods(); + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", gc_timer()); + // Release unloaded nmethod's memory. + ctx->purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); + ctx->free_code_blobs(); + } // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(unloading_occurred); diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp index 995ebc337f0..82e0181dbc3 100644 --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp @@ -35,6 +35,7 @@ #include "gc/serial/cardTableRS.hpp" #include "gc/serial/genMarkSweep.hpp" #include "gc/serial/serialGcRefProcProxyTask.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcTimer.hpp" @@ -196,6 +197,8 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", gc_timer()); + ClassUnloadingContext* ctx = ClassUnloadingContext::context(); + bool unloading_occurred; { CodeCache::UnlinkingScope scope(&is_alive); @@ -207,8 +210,15 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { CodeCache::do_unloading(unloading_occurred); } - // Release unloaded nmethod's memory. - CodeCache::flush_unlinked_nmethods(); + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", gc_timer()); + // Release unloaded nmethod's memory. + ctx->purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); + ctx->free_code_blobs(); + } // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(unloading_occurred); diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.cpp b/src/hotspot/share/gc/shared/classUnloadingContext.cpp new file mode 100644 index 00000000000..f624eaa6e44 --- /dev/null +++ b/src/hotspot/share/gc/shared/classUnloadingContext.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2023, 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. + * + */ + +#include "precompiled.hpp" + +#include "classfile/classLoaderData.inline.hpp" +#include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" +#include "runtime/mutexLocker.hpp" +#include "utilities/growableArray.hpp" + +ClassUnloadingContext* ClassUnloadingContext::_context = nullptr; + +ClassUnloadingContext::ClassUnloadingContext(uint num_workers, bool lock_codeblob_free_separately) : + _cld_head(nullptr), + _num_nmethod_unlink_workers(num_workers), + _unlinked_nmethods(nullptr), + _lock_codeblob_free_separately(lock_codeblob_free_separately) { + + assert(_context == nullptr, "context already set"); + _context = this; + + assert(num_workers > 0, "must be"); + + _unlinked_nmethods = NEW_C_HEAP_ARRAY(NMethodSet*, num_workers, mtGC); + for (uint i = 0; i < num_workers; ++i) { + _unlinked_nmethods[i] = new NMethodSet(); + } +} + +ClassUnloadingContext::~ClassUnloadingContext() { + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + delete _unlinked_nmethods[i]; + } + FREE_C_HEAP_ARRAY(NMethodSet*, _unlinked_nmethods); + + assert(_context == this, "context not set correctly"); + _context = nullptr; +} + +bool ClassUnloadingContext::has_unloaded_classes() const { + return _cld_head != nullptr; +} + +void ClassUnloadingContext::register_unloading_class_loader_data(ClassLoaderData* cld) { + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); + + cld->unload(); + + cld->set_unloading_next(_cld_head); + _cld_head = cld; +} + +void ClassUnloadingContext::purge_class_loader_data() { + for (ClassLoaderData* cld = _cld_head; cld != nullptr;) { + assert(cld->is_unloading(), "invariant"); + + ClassLoaderData* next = cld->unloading_next(); + delete cld; + cld = next; + } +} + +void ClassUnloadingContext::classes_unloading_do(void f(Klass* const)) { + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); + for (ClassLoaderData* cld = _cld_head; cld != nullptr; cld = cld->unloading_next()) { + assert(cld->is_unloading(), "invariant"); + cld->classes_do(f); + } +} + +void ClassUnloadingContext::register_unlinked_nmethod(nmethod* nm) { + assert(_context != nullptr, "no context set"); + + assert(!nm->is_unlinked(), "Only register for unloading once"); + assert(_num_nmethod_unlink_workers == 1 || Thread::current()->is_Worker_thread(), "must be worker thread if parallel"); + + uint worker_id = _num_nmethod_unlink_workers == 1 ? 0 : WorkerThread::worker_id(); + assert(worker_id < _num_nmethod_unlink_workers, "larger than expected worker id %u", worker_id); + + _unlinked_nmethods[worker_id]->append(nm); + + nm->set_is_unlinked(); +} + +void ClassUnloadingContext::purge_nmethods() { + assert(_context != nullptr, "no context set"); + + size_t freed_memory = 0; + + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + NMethodSet* set = _unlinked_nmethods[i]; + for (nmethod* nm : *set) { + freed_memory += nm->size(); + nm->purge(false /* free_code_cache_data */); + } + } + + CodeCache::maybe_restart_compiler(freed_memory); +} + +void ClassUnloadingContext::free_code_blobs() { + assert(_context != nullptr, "no context set"); + + // Sort nmethods before freeing to benefit from optimizations. If Nmethods were + // collected in parallel, use a new temporary buffer for the result, otherwise + // sort in-place. + NMethodSet* nmethod_set = nullptr; + + bool is_parallel = _num_nmethod_unlink_workers > 1; + + // Merge all collected nmethods into a huge array. + if (is_parallel) { + int num_nmethods = 0; + + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + num_nmethods += _unlinked_nmethods[i]->length(); + } + nmethod_set = new NMethodSet(num_nmethods); + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + nmethod_set->appendAll(_unlinked_nmethods[i]); + } + } else { + nmethod_set = _unlinked_nmethods[0]; + } + + // Sort by ascending address. + auto sort_nmethods = [] (nmethod** a, nmethod** b) -> int { + uintptr_t u_a = (uintptr_t)*a; + uintptr_t u_b = (uintptr_t)*b; + if (u_a == u_b) return 0; + if (u_a < u_b) return -1; + return 1; + }; + nmethod_set->sort(sort_nmethods); + + // And free. Duplicate loop for clarity depending on where we want the locking. + if (_lock_codeblob_free_separately) { + for (nmethod* nm : *nmethod_set) { + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::free(nm); + } + } else { + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); + for (nmethod* nm : *nmethod_set) { + CodeCache::free(nm); + } + } + + if (is_parallel) { + delete nmethod_set; + } +} diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.hpp b/src/hotspot/share/gc/shared/classUnloadingContext.hpp new file mode 100644 index 00000000000..42a8f764fa4 --- /dev/null +++ b/src/hotspot/share/gc/shared/classUnloadingContext.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023, 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. + * + */ + +#ifndef SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP +#define SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP + +#include "memory/allocation.hpp" +#include "utilities/growableArray.hpp" + +class ClassLoaderData; +class Klass; +class nmethod; + +class ClassUnloadingContext : public CHeapObj { + static ClassUnloadingContext* _context; + + ClassLoaderData* volatile _cld_head; + + const uint _num_nmethod_unlink_workers; + + using NMethodSet = GrowableArrayCHeap; + NMethodSet** _unlinked_nmethods; + + bool _lock_codeblob_free_separately; + +public: + static ClassUnloadingContext* context() { assert(_context != nullptr, "context not set"); return _context; } + + // Num_nmethod_unlink_workers configures the maximum numbers of threads unlinking + // nmethods. + // lock_codeblob_free_separately determines whether freeing the code blobs takes + // the CodeCache_lock during the whole operation (=false) or per code blob + // free operation (=true). + ClassUnloadingContext(uint num_nmethod_unlink_workers, + bool lock_codeblob_free_separately); + ~ClassUnloadingContext(); + + bool has_unloaded_classes() const; + + void register_unloading_class_loader_data(ClassLoaderData* cld); + void purge_class_loader_data(); + + void classes_unloading_do(void f(Klass* const)); + + // Register unloading nmethods, potentially in parallel. + void register_unlinked_nmethod(nmethod* nm); + void purge_nmethods(); + void free_code_blobs(); + + void purge_and_free_nmethods() { + purge_nmethods(); + free_code_blobs(); + } +}; + +#endif // SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 36f229ab817..0854a4776f0 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -36,6 +36,7 @@ #include "gc/serial/markSweep.hpp" #include "gc/shared/adaptiveSizePolicy.hpp" #include "gc/shared/cardTableBarrierSet.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" @@ -555,6 +556,9 @@ void GenCollectedHeap::do_collection(bool full, CodeCache::on_gc_marking_cycle_start(); + ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* lock_codeblob_free_separately */); + collect_generation(_old_gen, full, size, @@ -570,7 +574,7 @@ void GenCollectedHeap::do_collection(bool full, _young_gen->compute_new_size(); // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); + ClassLoaderDataGraph::purge(true /* at_safepoint */); DEBUG_ONLY(MetaspaceUtils::verify();) // Need to clear claim bits for the next mark. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 92d447258f2..c5b6d787b95 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -26,6 +26,7 @@ #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahEvacOOMHandler.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -235,7 +236,7 @@ void ShenandoahCodeRoots::unlink(WorkerThreads* workers, bool unloading_occurred void ShenandoahCodeRoots::purge() { assert(ShenandoahHeap::heap()->unload_classes(), "Only when running concurrent class unloading"); - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } ShenandoahCodeRootsIterator::ShenandoahCodeRootsIterator() : diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 2333e4e21bd..2e6ac1c356a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "memory/universe.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcArguments.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTraceTime.inline.hpp" @@ -1767,6 +1768,9 @@ void ShenandoahHeap::stop() { void ShenandoahHeap::stw_unload_classes(bool full_gc) { if (!unload_classes()) return; + ClassUnloadingContext ctx(_workers->active_workers(), + false /* lock_codeblob_free_separately */); + // Unload classes and purge SystemDictionary. { ShenandoahPhaseTimings::Phase phase = full_gc ? @@ -1784,14 +1788,14 @@ void ShenandoahHeap::stw_unload_classes(bool full_gc) { _workers->run_task(&unlink_task); } // Release unloaded nmethods's memory. - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } { ShenandoahGCPhase phase(full_gc ? ShenandoahPhaseTimings::full_gc_purge_cldg : ShenandoahPhaseTimings::degen_gc_purge_cldg); - ClassLoaderDataGraph::purge(/*at_safepoint*/true); + ClassLoaderDataGraph::purge(true /* at_safepoint */); } // Resize and verify metaspace MetaspaceGC::compute_new_size(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index afd10efdfdd..81eee97f25f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -30,6 +30,7 @@ #include "code/codeCache.hpp" #include "code/dependencyContext.hpp" #include "gc/shared/gcBehaviours.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/shenandoah/shenandoahNMethod.inline.hpp" #include "gc/shenandoah/shenandoahLock.hpp" @@ -138,6 +139,9 @@ void ShenandoahUnload::unload() { assert(ClassUnloading, "Filtered by caller"); assert(heap->is_concurrent_weak_root_in_progress(), "Filtered by caller"); + ClassUnloadingContext ctx(heap->workers()->active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink); @@ -181,7 +185,7 @@ void ShenandoahUnload::unload() { { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_cldg); - ClassLoaderDataGraph::purge(/*at_safepoint*/false); + ClassLoaderDataGraph::purge(false /* at_safepoint */); } { diff --git a/src/hotspot/share/gc/x/xHeap.cpp b/src/hotspot/share/gc/x/xHeap.cpp index a242a8063be..65da4e1c983 100644 --- a/src/hotspot/share/gc/x/xHeap.cpp +++ b/src/hotspot/share/gc/x/xHeap.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/gc_globals.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/locationPrinter.hpp" #include "gc/shared/tlab_globals.hpp" #include "gc/x/xAddress.inline.hpp" @@ -320,6 +321,9 @@ void XHeap::process_non_strong_references() { // Process weak roots _weak_roots_processor.process_weak_roots(); + ClassUnloadingContext ctx(_workers.active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods _unload.unlink(); diff --git a/src/hotspot/share/gc/x/xNMethod.cpp b/src/hotspot/share/gc/x/xNMethod.cpp index d86828aa847..613e1908502 100644 --- a/src/hotspot/share/gc/x/xNMethod.cpp +++ b/src/hotspot/share/gc/x/xNMethod.cpp @@ -27,6 +27,7 @@ #include "code/icBuffer.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/x/xBarrier.inline.hpp" #include "gc/x/xGlobals.hpp" @@ -362,5 +363,5 @@ void XNMethod::unlink(XWorkers* workers, bool unloading_occurred) { } void XNMethod::purge() { - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 1b4afd4eefb..bb0653f72ea 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/gcVMOperations.hpp" #include "gc/shared/isGCActiveMark.hpp" @@ -1320,6 +1321,9 @@ void ZGenerationOld::process_non_strong_references() { // Process weak roots _weak_roots_processor.process_weak_roots(); + ClassUnloadingContext ctx(_workers.active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods _unload.unlink(); diff --git a/src/hotspot/share/gc/z/zNMethod.cpp b/src/hotspot/share/gc/z/zNMethod.cpp index e4c24660365..71d514face1 100644 --- a/src/hotspot/share/gc/z/zNMethod.cpp +++ b/src/hotspot/share/gc/z/zNMethod.cpp @@ -28,6 +28,7 @@ #include "code/icBuffer.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zArray.inline.hpp" @@ -443,5 +444,5 @@ void ZNMethod::unlink(ZWorkers* workers, bool unloading_occurred) { } void ZNMethod::purge() { - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } From 835d016ade123a053c283589da472a96a4afae1e Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Sun, 5 May 2024 04:27:07 +0000 Subject: [PATCH 244/298] 8330094: RISC-V: Save and restore FRM in the call stub Reviewed-by: fyang Backport-of: b0496096dc8d7dc7acf28aa006141a3ecea446de --- src/hotspot/cpu/riscv/frame_riscv.hpp | 2 +- src/hotspot/cpu/riscv/riscv_v.ad | 9 ------- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 27 ++++++++++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/hotspot/cpu/riscv/frame_riscv.hpp b/src/hotspot/cpu/riscv/frame_riscv.hpp index ae6242a75bd..74425d23d7b 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.hpp +++ b/src/hotspot/cpu/riscv/frame_riscv.hpp @@ -131,7 +131,7 @@ // Entry frames // n.b. these values are determined by the layout defined in // stubGenerator for the Java call stub - entry_frame_after_call_words = 34, + entry_frame_after_call_words = 35, entry_frame_call_wrapper_offset = -10, // we don't need a save area diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 06826ecf046..145453bb538 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -2942,7 +2942,6 @@ instruct vloadcon(vReg dst, immI0 src) %{ __ vsetvli_helper(bt, Matcher::vector_length(this)); __ vid_v(as_VectorRegister($dst$$reg)); if (is_floating_point_type(bt)) { - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); } %} @@ -3156,7 +3155,6 @@ instruct vcvtBtoX(vReg dst, vReg src) %{ if (is_floating_point_type(bt)) { __ integer_extend_v(as_VectorRegister($dst$$reg), bt == T_FLOAT ? T_INT : T_LONG, Matcher::vector_length(this), as_VectorRegister($src$$reg), T_BYTE); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); } else { __ integer_extend_v(as_VectorRegister($dst$$reg), bt, @@ -3203,7 +3201,6 @@ instruct vcvtStoX_fp_extend(vReg dst, vReg src) %{ __ integer_extend_v(as_VectorRegister($dst$$reg), (bt == T_FLOAT ? T_INT : T_LONG), Matcher::vector_length(this), as_VectorRegister($src$$reg), T_SHORT); __ vsetvli_helper(bt, Matcher::vector_length(this)); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg)); %} ins_pipe(pipe_slow); @@ -3242,7 +3239,6 @@ instruct vcvtItoF(vReg dst, vReg src) %{ format %{ "vcvtItoF $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this)); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); @@ -3255,7 +3251,6 @@ instruct vcvtItoD(vReg dst, vReg src) %{ format %{ "vcvtItoD $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_INT, Matcher::vector_length(this), Assembler::mf2); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfwcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); @@ -3283,7 +3278,6 @@ instruct vcvtLtoF(vReg dst, vReg src) %{ format %{ "vcvtLtoF $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfncvt_f_x_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); @@ -3295,7 +3289,6 @@ instruct vcvtLtoD(vReg dst, vReg src) %{ format %{ "vcvtLtoD $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this)); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); @@ -3353,7 +3346,6 @@ instruct vcvtFtoD(vReg dst, vReg src) %{ format %{ "vcvtFtoD $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfwcvt_f_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); @@ -3401,7 +3393,6 @@ instruct vcvtDtoF(vReg dst, vReg src) %{ format %{ "vcvtDtoF $dst, $src" %} ins_encode %{ __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2); - __ csrwi(CSR_FRM, C2_MacroAssembler::rne); __ vfncvt_f_f_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg)); %} ins_pipe(pipe_slow); diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index aab65019619..8c5e1c097ef 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -126,8 +126,9 @@ class StubGenerator: public StubCodeGenerator { // [ return_from_Java ] <--- sp // [ argument word n ] // ... - // -34 [ argument word 1 ] - // -33 [ saved f27 ] <--- sp_after_call + // -35 [ argument word 1 ] + // -34 [ saved FRM in Floating-point Control and Status Register ] <--- sp_after_call + // -33 [ saved f27 ] // -32 [ saved f26 ] // -31 [ saved f25 ] // -30 [ saved f24 ] @@ -164,8 +165,9 @@ class StubGenerator: public StubCodeGenerator { // Call stub stack layout word offsets from fp enum call_stub_layout { - sp_after_call_off = -33, + sp_after_call_off = -34, + frm_off = sp_after_call_off, f27_off = -33, f26_off = -32, f25_off = -31, @@ -213,6 +215,7 @@ class StubGenerator: public StubCodeGenerator { const Address sp_after_call (fp, sp_after_call_off * wordSize); + const Address frm_save (fp, frm_off * wordSize); const Address call_wrapper (fp, call_wrapper_off * wordSize); const Address result (fp, result_off * wordSize); const Address result_type (fp, result_type_off * wordSize); @@ -295,6 +298,16 @@ class StubGenerator: public StubCodeGenerator { __ fsd(f26, f26_save); __ fsd(f27, f27_save); + __ frrm(t0); + __ sd(t0, frm_save); + // Set frm to the state we need. We do want Round to Nearest. We + // don't want non-IEEE rounding modes. + Label skip_fsrmi; + guarantee(__ RoundingMode::rne == 0, "must be"); + __ beqz(t0, skip_fsrmi); + __ fsrmi(__ RoundingMode::rne); + __ bind(skip_fsrmi); + // install Java thread in global register now we have saved // whatever value it held __ mv(xthread, c_rarg7); @@ -414,6 +427,14 @@ class StubGenerator: public StubCodeGenerator { __ ld(x9, x9_save); + // restore frm + Label skip_fsrm; + __ ld(t0, frm_save); + __ frrm(t1); + __ beq(t0, t1, skip_fsrm); + __ fsrm(t0); + __ bind(skip_fsrm); + __ ld(c_rarg0, call_wrapper); __ ld(c_rarg1, result); __ ld(c_rarg2, result_type); From d459ae9dc922d045ea38837f260f60e685e3b368 Mon Sep 17 00:00:00 2001 From: Joachim Kern Date: Mon, 6 May 2024 06:30:01 +0000 Subject: [PATCH 245/298] 8329850: [AIX] Allow loading of different members of same shared library archive Backport-of: cfd19f017681a7aded67937c5132263bbcc7be6f --- src/hotspot/os/aix/porting_aix.cpp | 31 +++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index 68233097b49..630bdf22c44 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -906,10 +906,11 @@ struct TableLocker { ~TableLocker() { pthread_mutex_unlock(&g_handletable_mutex); } }; struct handletableentry{ - void* handle; - ino64_t inode; - dev64_t devid; - uint refcount; + void* handle; + ino64_t inode; + dev64_t devid; + char* member; + uint refcount; }; constexpr unsigned init_num_handles = 128; static unsigned max_handletable = 0; @@ -1049,6 +1050,14 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { return nullptr; } else { + // extract member string if exist duplicate it and store pointer of it + // if member does not exist store nullptr + char* member = nullptr; + const char* substr; + if (filename[strlen(filename) - 1] == ')' && (substr = strrchr(filename, '('))) { + member = os::strdup(substr); + } + unsigned i = 0; TableLocker lock; // check if library belonging to filename is already loaded. @@ -1056,7 +1065,10 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { for (i = 0; i < g_handletable_used; i++) { if ((p_handletable + i)->handle && (p_handletable + i)->inode == libstat.st_ino && - (p_handletable + i)->devid == libstat.st_dev) { + (p_handletable + i)->devid == libstat.st_dev && + (((p_handletable + i)->member == nullptr && member == nullptr) || + ((p_handletable + i)->member != nullptr && member != nullptr && + strcmp((p_handletable + i)->member, member) == 0))) { (p_handletable + i)->refcount++; result = (p_handletable + i)->handle; break; @@ -1084,6 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { (p_handletable + i)->handle = result; (p_handletable + i)->inode = libstat.st_ino; (p_handletable + i)->devid = libstat.st_dev; + (p_handletable + i)->member = member; (p_handletable + i)->refcount = 1; } else { @@ -1131,7 +1144,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { // while in the second case we simply have to nag. res = (0 == ::dlclose(libhandle)); if (!res) { - // error analysis when dlopen fails + // error analysis when dlclose fails const char* error_report = ::dlerror(); if (error_report == nullptr) { error_report = "dlerror returned no error description"; @@ -1145,7 +1158,11 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { if (i < g_handletable_used) { if (res) { // First case: libhandle was found (with refcount == 0) and ::dlclose successful, - // so delete entry from array + // so delete entry from array (do not forget to free member-string space if member exists) + if ((p_handletable + i)->member) { + os::free((p_handletable + i)->member); + (p_handletable + i)->member = nullptr; + } g_handletable_used--; // If the entry was the last one of the array, the previous g_handletable_used-- // is sufficient to remove the entry from the array, otherwise we move the last From 021372c76d583e29cf2abf4b932e31321adf4295 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 6 May 2024 08:07:34 +0000 Subject: [PATCH 246/298] 8328703: Illegal accesses in Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_ioctl0 Backport-of: 87e864bf21d71daae4e001ec4edbb4ef1f60c36d --- .../linux/native/lible/CLibrary.cpp | 16 ++++++++-------- .../macosx/native/lible/CLibrary.cpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/jdk.internal.le/linux/native/lible/CLibrary.cpp b/src/jdk.internal.le/linux/native/lible/CLibrary.cpp index 7815fe0cd2e..3215e1f5013 100644 --- a/src/jdk.internal.le/linux/native/lible/CLibrary.cpp +++ b/src/jdk.internal.le/linux/native/lible/CLibrary.cpp @@ -150,20 +150,20 @@ JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibr (JNIEnv *env, jobject, jint fd, jint cmd, jobject data) { winsize ws; - ws.ws_row = env->GetIntField(data, ws_row); - ws.ws_col = env->GetIntField(data, ws_col); - ws.ws_xpixel = env->GetIntField(data, ws_xpixel); - ws.ws_ypixel = env->GetIntField(data, ws_ypixel); + ws.ws_row = env->GetShortField(data, ws_row); + ws.ws_col = env->GetShortField(data, ws_col); + ws.ws_xpixel = env->GetShortField(data, ws_xpixel); + ws.ws_ypixel = env->GetShortField(data, ws_ypixel); if (ioctl(fd, cmd, &ws) != 0) { throw_errno(env); return ; } - env->SetIntField(data, ws_row, ws.ws_row); - env->SetIntField(data, ws_col, ws.ws_col); - env->SetIntField(data, ws_xpixel, ws.ws_xpixel); - env->SetIntField(data, ws_ypixel, ws.ws_ypixel); + env->SetShortField(data, ws_row, ws.ws_row); + env->SetShortField(data, ws_col, ws.ws_col); + env->SetShortField(data, ws_xpixel, ws.ws_xpixel); + env->SetShortField(data, ws_ypixel, ws.ws_ypixel); } /* diff --git a/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp b/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp index 760e090f5e8..3bc481f4afa 100644 --- a/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp +++ b/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp @@ -154,20 +154,20 @@ JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibrar (JNIEnv *env, jobject, jint fd, jlong cmd, jobject data) { winsize ws; - ws.ws_row = env->GetIntField(data, ws_row); - ws.ws_col = env->GetIntField(data, ws_col); - ws.ws_xpixel = env->GetIntField(data, ws_xpixel); - ws.ws_ypixel = env->GetIntField(data, ws_ypixel); + ws.ws_row = env->GetShortField(data, ws_row); + ws.ws_col = env->GetShortField(data, ws_col); + ws.ws_xpixel = env->GetShortField(data, ws_xpixel); + ws.ws_ypixel = env->GetShortField(data, ws_ypixel); if (ioctl(fd, cmd, &ws) != 0) { throw_errno(env); return ; } - env->SetIntField(data, ws_row, ws.ws_row); - env->SetIntField(data, ws_col, ws.ws_col); - env->SetIntField(data, ws_xpixel, ws.ws_xpixel); - env->SetIntField(data, ws_ypixel, ws.ws_ypixel); + env->SetShortField(data, ws_row, ws.ws_row); + env->SetShortField(data, ws_col, ws.ws_col); + env->SetShortField(data, ws_xpixel, ws.ws_xpixel); + env->SetShortField(data, ws_ypixel, ws.ws_ypixel); } /* From 3770c28c05f279ed1a3854c6f70e7e1bbee6ff0e Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 6 May 2024 08:13:04 +0000 Subject: [PATCH 247/298] 8331331: :tier1 target explanation in doc/testing.md is incorrect Backport-of: 04271dfe7a262379944e2a2cf83a98a3a1b78a74 --- doc/testing.html | 5 +++-- doc/testing.md | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/testing.html b/doc/testing.html index 19d937df1ea..f13400920c6 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -179,8 +179,9 @@

      Test selection

      The test specifications given in TEST is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, :tier1 will expand -to -jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1. +to include all subcomponent test directories that define `tier1`, +for example: +jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 .... You can always submit a list of fully qualified test descriptors in the TEST variable if you want to shortcut the parser.

      Common Test Groups

      diff --git a/doc/testing.md b/doc/testing.md index 9756a691a8c..bc154e40ae7 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -102,11 +102,11 @@ test runs, the `test TEST="x"` solution needs to be used. The test specifications given in `TEST` is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an -example, `:tier1` will expand to `jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 -jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 -jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1`. You can -always submit a list of fully qualified test descriptors in the `TEST` variable -if you want to shortcut the parser. +example, `:tier1` will expand to include all subcomponent test directories +that define `tier1`, for example: `jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 +jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 ...`. You +can always submit a list of fully qualified test descriptors in the `TEST` +variable if you want to shortcut the parser. ### Common Test Groups From abbad928945d0679745e0997d804c44fe394d3db Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Mon, 6 May 2024 08:15:30 +0000 Subject: [PATCH 248/298] 8326201: [S390] Need to bailout cleanly if creation of stubs fails when code cache is out of space Backport-of: d5f3d5c8cc347ae384dea25b1a55ed57204d1af3 --- src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp | 5 +++-- src/hotspot/cpu/s390/s390.ad | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp index 200f7ee978d..b7f1d360568 100644 --- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp +++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2018 SAP SE. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024 SAP SE. 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 @@ -428,6 +428,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { "must be aligned"); ce->emit_static_call_stub(); + CHECK_BAILOUT(); // Prepend each BRASL with a nop. __ relocate(relocInfo::static_call_type); diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index e1d3df97edf..32e5323b6b2 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -1,6 +1,6 @@ // // Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2017, 2022 SAP SE. All rights reserved. +// Copyright (c) 2017, 2024 SAP SE. 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 @@ -1447,6 +1447,7 @@ int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { address base = __ start_a_stub(size_exception_handler()); if (base == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); return 0; // CodeBuffer::expand failed } @@ -1468,6 +1469,7 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { address base = __ start_a_stub(size_deopt_handler()); if (base == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); return 0; // CodeBuffer::expand failed } From 3ff535969372b5d01517eff3d03528df13bf300e Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Mon, 6 May 2024 08:17:00 +0000 Subject: [PATCH 249/298] 8330011: [s390x] update block-comments to make code consistent Reviewed-by: lucy Backport-of: 01bda278d6a498ca89c0bc5218680cd51a04e9d3 --- src/hotspot/cpu/s390/downcallLinker_s390.cpp | 34 +++++++++++--------- src/hotspot/cpu/s390/upcallLinker_s390.cpp | 24 +++++++------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp index f831da90755..dc443666bae 100644 --- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -166,10 +166,10 @@ void DowncallStubGenerator::generate() { locs.set(StubLocations::TARGET_ADDRESS, _abi._scratch2); if (_captured_state_mask != 0) { - __ block_comment("{ _captured_state_mask is set"); + __ block_comment("_captured_state_mask_is_set {"); locs.set_frame_data(StubLocations::CAPTURED_STATE_BUFFER, allocated_frame_size); allocated_frame_size += BytesPerWord; - __ block_comment("} _captured_state_mask is set"); + __ block_comment("} _captured_state_mask_is_set"); } allocated_frame_size = align_up(allocated_frame_size, StackAlignmentInBytes); @@ -184,7 +184,7 @@ void DowncallStubGenerator::generate() { _frame_complete = __ pc() - start; // frame build complete. if (_needs_transition) { - __ block_comment("{ thread java2native"); + __ block_comment("thread_java2native {"); __ get_PC(Z_R1_scratch); address the_pc = __ pc(); __ set_last_Java_frame(Z_SP, Z_R1_scratch); @@ -194,18 +194,18 @@ void DowncallStubGenerator::generate() { // State transition __ set_thread_state(_thread_in_native); - __ block_comment("} thread java2native"); + __ block_comment("} thread_java2native"); } - __ block_comment("{ argument shuffle"); + __ block_comment("argument_shuffle {"); arg_shuffle.generate(_masm, shuffle_reg, frame::z_jit_out_preserve_size, _abi._shadow_space_bytes, locs); - __ block_comment("} argument shuffle"); + __ block_comment("} argument_shuffle"); __ call(as_Register(locs.get(StubLocations::TARGET_ADDRESS))); ////////////////////////////////////////////////////////////////////////////// if (_captured_state_mask != 0) { - __ block_comment("{ save thread local"); + __ block_comment("save_thread_local {"); out_reg_spiller.generate_spill(_masm, spill_offset); @@ -216,7 +216,7 @@ void DowncallStubGenerator::generate() { out_reg_spiller.generate_fill(_masm, spill_offset); - __ block_comment("} save thread local"); + __ block_comment("} save_thread_local"); } ////////////////////////////////////////////////////////////////////////////// @@ -227,7 +227,7 @@ void DowncallStubGenerator::generate() { Label L_after_reguard; if (_needs_transition) { - __ block_comment("{ thread native2java"); + __ block_comment("thread_native2java {"); __ set_thread_state(_thread_in_native_trans); if (!UseSystemMemoryBarrier) { @@ -244,14 +244,16 @@ void DowncallStubGenerator::generate() { // change thread state __ set_thread_state(_thread_in_Java); - __ block_comment("reguard stack check"); - __ z_cli(Address(Z_thread, JavaThread::stack_guard_state_offset() + in_ByteSize(sizeof(StackOverflow::StackGuardState) - 1)), - StackOverflow::stack_guard_yellow_reserved_disabled); + __ block_comment("reguard_stack_check {"); + __ z_cli(Address(Z_thread, + JavaThread::stack_guard_state_offset() + in_ByteSize(sizeof(StackOverflow::StackGuardState) - 1)), + StackOverflow::stack_guard_yellow_reserved_disabled); __ z_bre(L_reguard); + __ block_comment("} reguard_stack_check"); __ bind(L_after_reguard); __ reset_last_Java_frame(); - __ block_comment("} thread native2java"); + __ block_comment("} thread_native2java"); } __ pop_frame(); @@ -261,7 +263,7 @@ void DowncallStubGenerator::generate() { ////////////////////////////////////////////////////////////////////////////// if (_needs_transition) { - __ block_comment("{ L_safepoint_poll_slow_path"); + __ block_comment("L_safepoint_poll_slow_path {"); __ bind(L_safepoint_poll_slow_path); // Need to save the native result registers around any runtime calls. @@ -277,7 +279,7 @@ void DowncallStubGenerator::generate() { __ block_comment("} L_safepoint_poll_slow_path"); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_reguard"); + __ block_comment("L_reguard {"); __ bind(L_reguard); // Need to save the native result registers around any runtime calls. diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp index b748ec547cc..93f21ab10b6 100644 --- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp @@ -63,7 +63,7 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc int offset = reg_save_area_offset; - __ block_comment("{ preserve_callee_saved_regs "); + __ block_comment("preserve_callee_saved_regs {"); for (int i = 0; i < Register::number_of_registers; i++) { Register reg = as_Register(i); // Z_SP saved/restored by prologue/epilogue @@ -82,7 +82,7 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc } } - __ block_comment("} preserve_callee_saved_regs "); + __ block_comment("} preserve_callee_saved_regs"); } static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { @@ -92,7 +92,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr int offset = reg_save_area_offset; - __ block_comment("{ restore_callee_saved_regs "); + __ block_comment("restore_callee_saved_regs {"); for (int i = 0; i < Register::number_of_registers; i++) { Register reg = as_Register(i); // Z_SP saved/restored by prologue/epilogue @@ -111,7 +111,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr } } - __ block_comment("} restore_callee_saved_regs "); + __ block_comment("} restore_callee_saved_regs"); } static const int upcall_stub_code_base_size = 1024; // depends on GC (resolve_jobject) @@ -199,7 +199,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, // Java methods won't preserve them, so save them here: preserve_callee_saved_registers(_masm, abi, reg_save_area_offset); - __ block_comment("{ on_entry"); + __ block_comment("on_entry {"); __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry)); __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); __ call(call_target_address); @@ -207,14 +207,14 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ block_comment("} on_entry"); arg_spiller.generate_fill(_masm, arg_save_area_offset); - __ block_comment("{ argument shuffle"); + __ block_comment("argument_shuffle {"); arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size, locs); - __ block_comment("} argument shuffle"); + __ block_comment("} argument_shuffle"); - __ block_comment("{ receiver "); + __ block_comment("receiver {"); __ load_const_optimized(Z_ARG1, (intptr_t)receiver); __ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2); - __ block_comment("} receiver "); + __ block_comment("} receiver"); __ load_const_optimized(Z_method, (intptr_t)entry); __ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset()))); @@ -250,7 +250,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, result_spiller.generate_spill(_masm, res_save_area_offset); - __ block_comment("{ on_exit"); + __ block_comment("on_exit {"); __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_exit)); __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); __ call(call_target_address); @@ -266,7 +266,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ exception handler"); + __ block_comment("exception_handler {"); intptr_t exception_handler_offset = __ pc() - start; @@ -277,7 +277,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, __ call_c(call_target_address); __ should_not_reach_here(); - __ block_comment("} exception handler"); + __ block_comment("} exception_handler"); _masm->flush(); From 915988281c47bd03d334d98701fcbabda67318a7 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Mon, 6 May 2024 08:27:43 +0000 Subject: [PATCH 250/298] 8310513: [s390x] Intrinsify recursive ObjectMonitor locking Reviewed-by: lucy Backport-of: 47df14590c003ccb1607ec0edfe999fcf2aebd86 --- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 110 +++++++++++-------- 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 8a56f3e4c2b..2dc3167dea6 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2023 SAP SE. All rights reserved. + * Copyright (c) 2016, 2024 SAP SE. 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 @@ -3149,28 +3149,32 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis Register temp = temp2; NearLabel done, object_has_monitor; + const int hdr_offset = oopDesc::mark_offset_in_bytes(); + + assert_different_registers(temp1, temp2, oop, box); + BLOCK_COMMENT("compiler_fast_lock_object {"); // Load markWord from oop into mark. - z_lg(displacedHeader, 0, oop); + z_lg(displacedHeader, hdr_offset, oop); if (DiagnoseSyncOnValueBasedClasses != 0) { - load_klass(Z_R1_scratch, oop); - z_l(Z_R1_scratch, Address(Z_R1_scratch, Klass::access_flags_offset())); + load_klass(temp, oop); + z_l(temp, Address(temp, Klass::access_flags_offset())); assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction"); - z_nilh(Z_R1_scratch, JVM_ACC_IS_VALUE_BASED_CLASS >> 16); + z_nilh(temp, JVM_ACC_IS_VALUE_BASED_CLASS >> 16); z_brne(done); } // Handle existing monitor. // The object has an existing monitor iff (mark & monitor_value) != 0. guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word"); - z_lgr(temp, displacedHeader); - z_nill(temp, markWord::monitor_value); - z_brne(object_has_monitor); + z_tmll(displacedHeader, markWord::monitor_value); + z_brnaz(object_has_monitor); if (LockingMode == LM_MONITOR) { // Set NE to indicate 'failure' -> take slow-path + // From loading the markWord, we know that oop != nullptr z_ltgr(oop, oop); z_bru(done); } else if (LockingMode == LM_LEGACY) { @@ -3182,23 +3186,24 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis // Initialize the box (must happen before we update the object mark). z_stg(displacedHeader, BasicLock::displaced_header_offset_in_bytes(), box); - // Memory Fence (in cmpxchgd) - // Compare object markWord with mark and if equal exchange scratch1 with object markWord. - - // If the compare-and-swap succeeded, then we found an unlocked object and we - // have now locked it. - z_csg(displacedHeader, box, 0, oop); + // Compare object markWord with mark and if equal, exchange box with object markWork. + // If the compare-and-swap succeeds, then we found an unlocked object and have now locked it. + z_csg(displacedHeader, box, hdr_offset, oop); assert(currentHeader == displacedHeader, "must be same register"); // Identified two registers from z/Architecture. z_bre(done); - // We did not see an unlocked object so try the fast recursive case. - + // We did not see an unlocked object + // currentHeader contains what is currently stored in the oop's markWord. + // We might have a recursive case. Verify by checking if the owner is self. + // To do so, compare the value in the markWord (currentHeader) with the stack pointer. z_sgr(currentHeader, Z_SP); load_const_optimized(temp, (~(os::vm_page_size() - 1) | markWord::lock_mask_in_place)); z_ngr(currentHeader, temp); - // z_brne(done); - // z_release(); + + // result zero: owner is self -> recursive lock. Indicate that by storing 0 in the box. + // result not-zero: attempt failed. We don't hold the lock -> go for slow case. + z_stg(currentHeader/*==0 or not 0*/, BasicLock::displaced_header_offset_in_bytes(), box); z_bru(done); @@ -3208,28 +3213,34 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis z_bru(done); } + bind(object_has_monitor); + Register zero = temp; Register monitor_tagged = displacedHeader; // Tagged with markWord::monitor_value. - bind(object_has_monitor); // The object's monitor m is unlocked iff m->owner is null, // otherwise m->owner may contain a thread or a stack address. - // + // Try to CAS m->owner from null to current thread. - z_lghi(zero, 0); // If m->owner is null, then csg succeeds and sets m->owner=THREAD and CR=EQ. + // Otherwise, register zero is filled with the current owner. + z_lghi(zero, 0); z_csg(zero, Z_thread, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), monitor_tagged); if (LockingMode != LM_LIGHTWEIGHT) { // Store a non-null value into the box. z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box); } -#ifdef ASSERT - z_brne(done); - // We've acquired the monitor, check some invariants. - // Invariant 1: _recursions should be 0. - asm_assert_mem8_is_zero(OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions), monitor_tagged, - "monitor->_recursions should be 0", -1); - z_ltgr(zero, zero); // Set CR=EQ. -#endif + + z_bre(done); // acquired the lock for the first time. + + BLOCK_COMMENT("fast_path_recursive_lock {"); + // Check if we are already the owner (recursive lock) + z_cgr(Z_thread, zero); // owner is stored in zero by "z_csg" above + z_brne(done); // not a recursive lock + + // Current thread already owns the lock. Just increment recursion count. + z_agsi(Address(monitor_tagged, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), 1ll); + z_cgr(zero, zero); // set the CC to EQUAL + BLOCK_COMMENT("} fast_path_recursive_lock"); bind(done); BLOCK_COMMENT("} compiler_fast_lock_object"); @@ -3242,11 +3253,12 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg Register displacedHeader = temp1; Register currentHeader = temp2; Register temp = temp1; - Register monitor = temp2; const int hdr_offset = oopDesc::mark_offset_in_bytes(); - Label done, object_has_monitor; + assert_different_registers(temp1, temp2, oop, box); + + Label done, object_has_monitor, not_recursive; BLOCK_COMMENT("compiler_fast_unlock_object {"); @@ -3261,30 +3273,25 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg // The object has an existing monitor iff (mark & monitor_value) != 0. z_lg(currentHeader, hdr_offset, oop); guarantee(Immediate::is_uimm16(markWord::monitor_value), "must be half-word"); - if (LockingMode == LM_LIGHTWEIGHT) { - z_lgr(temp, currentHeader); - } - z_nill(currentHeader, markWord::monitor_value); - z_brne(object_has_monitor); + + z_tmll(currentHeader, markWord::monitor_value); + z_brnaz(object_has_monitor); if (LockingMode == LM_MONITOR) { // Set NE to indicate 'failure' -> take slow-path z_ltgr(oop, oop); z_bru(done); } else if (LockingMode == LM_LEGACY) { - // Check if it is still a light weight lock, this is true if we see + // Check if it is still a lightweight lock, this is true if we see // the stack address of the basicLock in the markWord of the object // copy box to currentHeader such that csg does not kill it. z_lgr(currentHeader, box); - z_csg(currentHeader, displacedHeader, 0, oop); + z_csg(currentHeader, displacedHeader, hdr_offset, oop); z_bru(done); // csg sets CR as desired. } else { assert(LockingMode == LM_LIGHTWEIGHT, "must be"); - // don't load currentHead again from stack-top after monitor check, as it is possible - // some other thread modified it. - // currentHeader is altered, but it's contents are copied in temp as well - lightweight_unlock(oop, temp, currentHeader, done); + lightweight_unlock(oop, currentHeader, displacedHeader, done); z_bru(done); } @@ -3293,11 +3300,22 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg // Handle existing monitor. bind(object_has_monitor); - z_lg(currentHeader, hdr_offset, oop); // CurrentHeader is tagged with monitor_value set. - load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions))); - z_brne(done); - load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); + + z_cg(Z_thread, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); z_brne(done); + + BLOCK_COMMENT("fast_path_recursive_unlock {"); + load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions))); + z_bre(not_recursive); // if 0 then jump, it's not recursive locking + + // Recursive inflated unlock + z_agsi(Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), -1ll); + z_cgr(currentHeader, currentHeader); // set the CC to EQUAL + BLOCK_COMMENT("} fast_path_recursive_unlock"); + z_bru(done); + + bind(not_recursive); + load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList))); z_brne(done); load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq))); From 2b858f5bdee5bcb29ef6ecf995400b390a2cb91f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 6 May 2024 08:37:55 +0000 Subject: [PATCH 251/298] 8328938: C2 SuperWord: disable vectorization for large stride and scale Reviewed-by: epeter, simonis Backport-of: 2931458711244e20eb7845a1aefcf6ed4206bce1 --- src/hotspot/share/opto/superword.cpp | 19 ++ .../superword/TestLargeScaleAndStride.java | 253 ++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/loopopts/superword/TestLargeScaleAndStride.java diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 6a641a44b32..cb1a2a769fc 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -4200,6 +4200,25 @@ SWPointer::SWPointer(MemNode* mem, SuperWord* slp, Node_Stack *nstack, bool anal NOT_PRODUCT(if(_slp->is_trace_alignment()) _tracer.restore_depth();) NOT_PRODUCT(_tracer.ctor_6(mem);) + // In the pointer analysis, and especially the AlignVector, analysis we assume that + // stride and scale are not too large. For example, we multiply "scale * stride", + // and assume that this does not overflow the int range. We also take "abs(scale)" + // and "abs(stride)", which would overflow for min_int = -(2^31). Still, we want + // to at least allow small and moderately large stride and scale. Therefore, we + // allow values up to 2^30, which is only a factor 2 smaller than the max/min int. + // Normal performance relevant code will have much lower values. And the restriction + // allows us to keep the rest of the autovectorization code much simpler, since we + // do not have to deal with overflows. + jlong long_scale = _scale; + jlong long_stride = slp->lp()->stride_is_con() ? slp->iv_stride() : 0; + jlong max_val = 1 << 30; + if (abs(long_scale) >= max_val || + abs(long_stride) >= max_val || + abs(long_scale * long_stride) >= max_val) { + assert(!valid(), "adr stride*scale is too large"); + return; + } + _base = base; _adr = adr; assert(valid(), "Usable"); diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestLargeScaleAndStride.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestLargeScaleAndStride.java new file mode 100644 index 00000000000..cfb2931d928 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestLargeScaleAndStride.java @@ -0,0 +1,253 @@ +/* + * 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. + */ + +/* + * @test id=vanilla + * @bug 8328938 + * @summary Test autovectorization with large scale and stride + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run main compiler.loopopts.superword.TestLargeScaleAndStride + */ + +/* + * @test id=AlignVector + * @bug 8328938 + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @requires vm.compiler2.enabled + * @run main/othervm -XX:+AlignVector compiler.loopopts.superword.TestLargeScaleAndStride + */ + +package compiler.loopopts.superword; + +import jdk.internal.misc.Unsafe; + +public class TestLargeScaleAndStride { + static final Unsafe UNSAFE = Unsafe.getUnsafe(); + static int RANGE = 100_000; + + public static void main(String[] args) { + byte[] a = new byte[100]; + fill(a); + + byte[] gold1a = a.clone(); + byte[] gold1b = a.clone(); + byte[] gold2a = a.clone(); + byte[] gold2b = a.clone(); + byte[] gold2c = a.clone(); + byte[] gold2d = a.clone(); + byte[] gold3 = a.clone(); + test1a(gold1a); + test1b(gold1b); + test2a(gold2a); + test2b(gold2b); + test2c(gold2c); + test2d(gold2d); + test3(gold3); + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test1a(c); + verify(c, gold1a); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test1b(c); + verify(c, gold1b); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test2a(c); + verify(c, gold2a); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test2b(c); + verify(c, gold2b); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test2c(c); + verify(c, gold2c); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test2d(c); + verify(c, gold2d); + } + + for (int i = 0; i < 100; i++) { + byte[] c = a.clone(); + test3(c); + verify(c, gold3); + } + } + + static void fill(byte[] a) { + for (int i = 0; i < a.length; i++) { + a[i] = (byte)i; + } + } + + static void verify(byte[] a, byte[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + throw new RuntimeException("wrong value: " + i + ": " + a[i] + " != " + b[i]); + } + } + } + + static void test1a(byte[] a) { + int scale = 1 << 31; + for (int i = 0; i < RANGE; i+=2) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 2 + // 2 * (1 >> 31) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + static void test1b(byte[] a) { + int scale = 1 << 31; + for (int i = RANGE-2; i >= 0; i-=2) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 2 + // 2 * (1 >> 31) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + static void test2a(byte[] a) { + int scale = 1 << 30; + for (int i = 0; i < RANGE; i+=4) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 4 + // 4 * (1 >> 30) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + + static void test2b(byte[] a) { + int scale = 1 << 30; + for (int i = RANGE-4; i >= 0; i-=4) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 4 + // 4 * (1 >> 30) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + static void test2c(byte[] a) { + int scale = -(1 << 30); + for (int i = 0; i < RANGE; i+=4) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 4 + // 4 * (1 >> 30) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + static void test2d(byte[] a) { + int scale = -(1 << 30); + for (int i = RANGE-4; i >= 0; i-=4) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + // i is a multiple of 4 + // 4 * (1 >> 30) -> overflow to zero + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } + + static void test3(byte[] a) { + int scale = 1 << 28; + int stride = 1 << 4; + int start = -(1 << 30); + int end = 1 << 30; + for (int i = start; i < end; i+=stride) { + long base = UNSAFE.ARRAY_BYTE_BASE_OFFSET; + int j = scale * i; // always zero + byte v0 = UNSAFE.getByte(a, base + (int)(j + 0)); + byte v1 = UNSAFE.getByte(a, base + (int)(j + 1)); + byte v2 = UNSAFE.getByte(a, base + (int)(j + 2)); + byte v3 = UNSAFE.getByte(a, base + (int)(j + 3)); + UNSAFE.putByte(a, base + (int)(j + 0), (byte)(v0 + 1)); + UNSAFE.putByte(a, base + (int)(j + 1), (byte)(v1 + 1)); + UNSAFE.putByte(a, base + (int)(j + 2), (byte)(v2 + 1)); + UNSAFE.putByte(a, base + (int)(j + 3), (byte)(v3 + 1)); + } + } +} From 16ba673e14038ed19b95e345b823316ff58a2182 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Mon, 6 May 2024 08:39:15 +0000 Subject: [PATCH 252/298] 8331639: [21u]: Bump GHA bootstrap JDK to 21.0.3 Reviewed-by: sgehwolf --- make/conf/github-actions.conf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 3a08380a8b6..0a9f21e97c4 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -29,17 +29,17 @@ GTEST_VERSION=1.13.0 JTREG_VERSION=7.3.1+1 LINUX_X64_BOOT_JDK_EXT=tar.gz -LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz -LINUX_X64_BOOT_JDK_SHA256=bb863b2d542976d1ae4b7b81af3e78b1e4247a64644350b552d298d8dc5980dc +LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jdk_x64_linux_hotspot_21.0.3_9.tar.gz +LINUX_X64_BOOT_JDK_SHA256=fffa52c22d797b715a962e6c8d11ec7d79b90dd819b5bc51d62137ea4b22a340 MACOS_X64_BOOT_JDK_EXT=tar.gz -MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-x64_bin.tar.gz -MACOS_X64_BOOT_JDK_SHA256=47cf960d9bb89dbe987535a389f7e26c42de7c984ef5108612d77c81aa8cc6a4 +MACOS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jdk_x64_mac_hotspot_21.0.3_9.tar.gz +MACOS_X64_BOOT_JDK_SHA256=f777103aab94330d14a29bd99f3a26d60abbab8e2c375cec9602746096721a7c MACOS_AARCH64_BOOT_JDK_EXT=tar.gz -MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-aarch64_bin.tar.gz -MACOS_AARCH64_BOOT_JDK_SHA256=d020f5c512c043cfb7119a591bc7e599a5bfd76d866d939f5562891d9db7c9b3 +MACOS_AARCH64_BOOT_JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.3_9.tar.gz +MACOS_AARCH64_BOOT_JDK_SHA256=b6be6a9568be83695ec6b7cb977f4902f7be47d74494c290bc2a5c3c951e254f WINDOWS_X64_BOOT_JDK_EXT=zip -WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_windows-x64_bin.zip -WINDOWS_X64_BOOT_JDK_SHA256=c92fae5e42b9aecf444a66c8ec563c652f60b1e231dfdd33a4f5a3e3603058fb +WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jdk_x64_windows_hotspot_21.0.3_9.zip +WINDOWS_X64_BOOT_JDK_SHA256=c43a66cff7a403d56c5c5e1ff10d3d5f95961abf80f97f0e35380594909f0e4d From 7a400f2a5945139efaa9323231df83cc592c68fb Mon Sep 17 00:00:00 2001 From: "Alexandru C. Moraru" Date: Mon, 6 May 2024 11:49:36 +0000 Subject: [PATCH 253/298] 8309890: TestStringDeduplicationInterned.java waits for the wrong condition Backport-of: 63fe413d93861c79af5587859f01822980969c24 --- .../jtreg/gc/stringdedup/TestStringDeduplicationTools.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java index b5441b4cbcc..31c11b66dfc 100644 --- a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java +++ b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java @@ -399,10 +399,8 @@ public static void main(String[] args) { forceDeduplication(ageThreshold, FullGC); - if (!waitForDeduplication(dupString3, baseString)) { - if (getValue(dupString3) != getValue(internedString)) { - throw new RuntimeException("String 3 doesn't match either"); - } + if (!waitForDeduplication(dupString3, internedString)) { + throw new RuntimeException("Deduplication has not occurred for string 3"); } if (afterInternedValue != getValue(dupString2)) { From ed2f5a8d6497e1a32e382b32a686f70be2e3a9fe Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 7 May 2024 08:19:02 +0000 Subject: [PATCH 254/298] 8310228: Improve error reporting for uncaught native exceptions on Windows Reviewed-by: stuefe Backport-of: 38bf1192b637cf3513cb25ac21f513bfb51cb55b --- make/test/JtregNativeHotspot.gmk | 2 + src/hotspot/os/windows/os_windows.cpp | 57 +++++++++------ .../UncaughtNativeExceptionTest.java | 71 +++++++++++++++++++ .../ErrorHandling/libNativeException.c | 32 +++++++++ 4 files changed, 140 insertions(+), 22 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java create mode 100644 test/hotspot/jtreg/runtime/ErrorHandling/libNativeException.c diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index 219537f7412..c73783e3b0a 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -1511,6 +1511,8 @@ else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMonitorWithDeadObjectTest += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -ljvm -lpthread + + BUILD_HOTSPOT_JTREG_EXCLUDE += libNativeException.c endif ifeq ($(ASAN_ENABLED), true) diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index a6aa82012e8..3359bd0c63e 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -280,10 +280,12 @@ void os::run_periodic_checks(outputStream* st) { return; } +#ifndef _WIN64 // previous UnhandledExceptionFilter, if there is one static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = nullptr; +#endif -LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo); +static LONG WINAPI Uncaught_Exception_Handler(struct _EXCEPTION_POINTERS* exceptionInfo); void os::init_system_properties_values() { // sysclasspath, java_home, dll_dir @@ -397,7 +399,7 @@ void os::init_system_properties_values() { #ifndef _WIN64 // set our UnhandledExceptionFilter and save any previous one - prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception); + prev_uef_handler = SetUnhandledExceptionFilter(Uncaught_Exception_Handler); #endif // Done @@ -2491,9 +2493,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { #if defined(_M_AMD64) || defined(_M_IX86) //----------------------------------------------------------------------------- -LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { - PCONTEXT ctx = exceptionInfo->ContextRecord; -#ifndef _WIN64 +static bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) { // handle exception caused by native method modifying control word DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; @@ -2504,34 +2504,48 @@ LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { case EXCEPTION_FLT_INVALID_OPERATION: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_UNDERFLOW: { + PCONTEXT ctx = exceptionInfo->ContextRecord; +#ifndef _WIN64 jint fp_control_word = (* (jint*) StubRoutines::x86::addr_fpu_cntrl_wrd_std()); if (fp_control_word != ctx->FloatSave.ControlWord) { // Restore FPCW and mask out FLT exceptions ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0; // Mask out pending FLT exceptions ctx->FloatSave.StatusWord &= 0xffffff00; - return EXCEPTION_CONTINUE_EXECUTION; + return true; } +#else // !_WIN64 + // On Windows, the mxcsr control bits are non-volatile across calls + // See also CR 6192333 + // + jint MxCsr = INITIAL_MXCSR; + // we can't use StubRoutines::x86::addr_mxcsr_std() + // because in Win64 mxcsr is not saved there + if (MxCsr != ctx->MxCsr) { + ctx->MxCsr = MxCsr; + return true; + } +#endif // !_WIN64 + } } + return false; +} +#endif + +#ifndef _WIN64 +static LONG WINAPI Uncaught_Exception_Handler(struct _EXCEPTION_POINTERS* exceptionInfo) { + if (handle_FLT_exception(exceptionInfo)) { + return EXCEPTION_CONTINUE_EXECUTION; + } + + // we only override this on 32 bits, so only check it there if (prev_uef_handler != nullptr) { // We didn't handle this exception so pass it to the previous // UnhandledExceptionFilter. return (prev_uef_handler)(exceptionInfo); } -#else // !_WIN64 - // On Windows, the mxcsr control bits are non-volatile across calls - // See also CR 6192333 - // - jint MxCsr = INITIAL_MXCSR; - // we can't use StubRoutines::x86::addr_mxcsr_std() - // because in Win64 mxcsr is not saved there - if (MxCsr != ctx->MxCsr) { - ctx->MxCsr = MxCsr; - return EXCEPTION_CONTINUE_EXECUTION; - } -#endif // !_WIN64 return EXCEPTION_CONTINUE_SEARCH; } @@ -2788,9 +2802,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { } #if defined(_M_AMD64) || defined(_M_IX86) - if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) { - LONG result=Handle_FLT_Exception(exceptionInfo); - if (result==EXCEPTION_CONTINUE_EXECUTION) return result; + if ((in_java || in_native) && handle_FLT_exception(exceptionInfo)) { + return EXCEPTION_CONTINUE_EXECUTION; } #endif diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java new file mode 100644 index 00000000000..260db1eef8b --- /dev/null +++ b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id + * @enablePreview + * @requires os.family == "windows" + * @library /test/lib + * @run testng UncaughtNativeExceptionTest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import org.testng.annotations.Test; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.regex.Pattern; + +import static org.testng.Assert.assertTrue; + +public class UncaughtNativeExceptionTest { + private static class Crasher { + public static void main(String[] args) throws Throwable { + System.loadLibrary("NativeException"); + throwException(); + } + + static native void throwException(); + } + + // check that we actually report the native exception, + // and don't terminate abruptly due to stack overflow error + @Test + public void testNativeExceptionReporting() throws Exception { + OutputAnalyzer output = ProcessTools.executeTestJava( + // executeTestJvm doesn't seem to forward 'java.library.path' + "-Djava.library.path=" + System.getProperty("java.library.path"), + Crasher.class.getName()); + + File hsErrFile = HsErrFileUtils.openHsErrFileFromOutput(output); + Path hsErrPath = hsErrFile.toPath(); + assertTrue(Files.exists(hsErrPath)); + + Pattern[] positivePatterns = { + Pattern.compile(".*Internal Error \\(0x2a\\).*") + }; + HsErrFileUtils.checkHsErrFileContent(hsErrFile, positivePatterns, null, true /* check end marker */, false /* verbose */); + } +} diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/libNativeException.c b/test/hotspot/jtreg/runtime/ErrorHandling/libNativeException.c new file mode 100644 index 00000000000..3bf71cf9c67 --- /dev/null +++ b/test/hotspot/jtreg/runtime/ErrorHandling/libNativeException.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023, 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. + */ + +#include + +#include + +const DWORD EX_CODE = 42; + +JNIEXPORT void JNICALL Java_UncaughtNativeExceptionTest_00024Crasher_throwException(JNIEnv* env, jclass cls) { + RaiseException(EX_CODE, EXCEPTION_NONCONTINUABLE, 0, NULL); +} From 92b43c570eb3a83dff23f757d2805d9b2a44a738 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 7 May 2024 08:20:13 +0000 Subject: [PATCH 255/298] 8317007: Add bulk removal of dead nmethods during class unloading Backport-of: f55381950266088cc0284754b16663675867ac87 --- src/hotspot/share/code/codeBlob.cpp | 4 +- src/hotspot/share/code/codeBlob.hpp | 2 +- src/hotspot/share/code/compiledMethod.hpp | 2 +- src/hotspot/share/code/nmethod.cpp | 14 +++-- src/hotspot/share/code/nmethod.hpp | 2 +- src/hotspot/share/compiler/compileBroker.cpp | 2 +- src/hotspot/share/gc/g1/g1CodeRootSet.cpp | 14 +++++ src/hotspot/share/gc/g1/g1CodeRootSet.hpp | 1 + src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 62 ++++++++++--------- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 2 + src/hotspot/share/gc/g1/heapRegionRemSet.cpp | 4 ++ src/hotspot/share/gc/g1/heapRegionRemSet.hpp | 1 + .../gc/parallel/parallelScavengeHeap.cpp | 12 ++-- .../gc/parallel/parallelScavengeHeap.hpp | 1 + .../share/gc/parallel/psParallelCompact.cpp | 5 ++ src/hotspot/share/gc/serial/genMarkSweep.cpp | 4 ++ src/hotspot/share/gc/serial/serialHeap.cpp | 1 + .../share/gc/shared/classUnloadingContext.cpp | 7 ++- .../share/gc/shared/classUnloadingContext.hpp | 5 ++ .../share/gc/shared/genCollectedHeap.cpp | 7 ++- .../share/gc/shared/genCollectedHeap.hpp | 1 + .../share/gc/shared/scavengableNMethods.cpp | 51 ++++++++++----- .../share/gc/shared/scavengableNMethods.hpp | 8 ++- .../share/gc/shenandoah/shenandoahHeap.cpp | 1 + .../share/gc/shenandoah/shenandoahUnload.cpp | 1 + src/hotspot/share/gc/x/xHeap.cpp | 1 + src/hotspot/share/gc/z/zGeneration.cpp | 1 + 27 files changed, 151 insertions(+), 65 deletions(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 058ac24e167..40d63419e7c 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -164,7 +164,7 @@ RuntimeBlob::RuntimeBlob( void RuntimeBlob::free(RuntimeBlob* blob) { assert(blob != nullptr, "caller must check for nullptr"); ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock - blob->purge(); + blob->purge(true /* free_code_cache_data */, true /* unregister_nmethod */); { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); @@ -173,7 +173,7 @@ void RuntimeBlob::free(RuntimeBlob* blob) { MemoryService::track_code_cache_memory_usage(); } -void CodeBlob::purge(bool free_code_cache_data) { +void CodeBlob::purge(bool free_code_cache_data, bool unregister_nmethod) { if (_oop_maps != nullptr) { delete _oop_maps; _oop_maps = nullptr; diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 719ca57b30f..c1c34a06c75 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -143,7 +143,7 @@ class CodeBlob { static unsigned int align_code_offset(int offset); // Deletion - virtual void purge(bool free_code_cache_data = true); + virtual void purge(bool free_code_cache_data, bool unregister_nmethod); // Typing virtual bool is_buffer_blob() const { return false; } diff --git a/src/hotspot/share/code/compiledMethod.hpp b/src/hotspot/share/code/compiledMethod.hpp index 4bcda08ec99..ca441d9ae64 100644 --- a/src/hotspot/share/code/compiledMethod.hpp +++ b/src/hotspot/share/code/compiledMethod.hpp @@ -174,7 +174,7 @@ class CompiledMethod : public CodeBlob { void* _gc_data; - virtual void purge(bool free_code_cache_data = true) = 0; + virtual void purge(bool free_code_cache_data, bool unregister_nmethod) = 0; private: DeoptimizationStatus deoptimization_status() const { diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 1b328597b7f..0a82827bd33 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1444,7 +1444,9 @@ void nmethod::unlink() { ClassUnloadingContext::context()->register_unlinked_nmethod(this); } -void nmethod::purge(bool free_code_cache_data) { +void nmethod::purge(bool free_code_cache_data, bool unregister_nmethod) { + assert(!free_code_cache_data, "must only call not freeing code cache data"); + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); // completely deallocate this method @@ -1464,13 +1466,13 @@ void nmethod::purge(bool free_code_cache_data) { ec = next; } - Universe::heap()->unregister_nmethod(this); + if (unregister_nmethod) { + Universe::heap()->unregister_nmethod(this); + } + CodeCache::unregister_old_nmethod(this); - CodeBlob::purge(); - if (free_code_cache_data) { - CodeCache::free(this); - } + CodeBlob::purge(free_code_cache_data, unregister_nmethod); } oop nmethod::oop_at(int index) const { diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 3be50e28e15..f428aa4ef3d 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -522,7 +522,7 @@ class nmethod : public CompiledMethod { void unlink(); // Deallocate this nmethod - called by the GC - void purge(bool free_code_cache_data = true); + void purge(bool free_code_cache_data, bool unregister_nmethod); // See comment at definition of _last_seen_on_stack void mark_as_maybe_on_stack(); diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index c8a5df23b49..9cf5d2ab7bb 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1775,7 +1775,7 @@ bool CompileBroker::init_compiler_runtime() { void CompileBroker::free_buffer_blob_if_allocated(CompilerThread* thread) { BufferBlob* blob = thread->get_buffer_blob(); if (blob != nullptr) { - blob->purge(); + blob->purge(true /* free_code_cache_data */, true /* unregister_nmethod */); MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); } diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp index af369e68088..a1eb7b8543a 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp @@ -189,6 +189,15 @@ class G1CodeRootSetHashTable : public CHeapObj { } } + // Removes dead/unlinked entries. + void bulk_remove() { + auto delete_check = [&] (nmethod** value) { + return (*value)->is_unlinked(); + }; + + clean(delete_check); + } + // Calculate the log2 of the table size we want to shrink to. size_t log2_target_shrink_size(size_t current_size) const { // A table with the new size should be at most filled by this factor. Otherwise @@ -257,6 +266,11 @@ bool G1CodeRootSet::remove(nmethod* method) { return _table->remove(method); } +void G1CodeRootSet::bulk_remove() { + assert(!_is_iterating, "should not mutate while iterating the table"); + _table->bulk_remove(); +} + bool G1CodeRootSet::contains(nmethod* method) { return _table->contains(method); } diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.hpp b/src/hotspot/share/gc/g1/g1CodeRootSet.hpp index d1051e6e42e..9c5ccdd1202 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.hpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.hpp @@ -44,6 +44,7 @@ class G1CodeRootSet { void add(nmethod* method); bool remove(nmethod* method); + void bulk_remove(); bool contains(nmethod* method); void clear(); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 6fc044939b8..f59de9b44e3 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -2597,6 +2597,7 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec GCTraceTime(Debug, gc, phases) debug(description, timer); ClassUnloadingContext ctx(workers()->active_workers(), + false /* unregister_nmethods_during_purge */, false /* lock_codeblob_free_separately */); { CodeCache::UnlinkingScope scope(is_alive); @@ -2608,6 +2609,10 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", timer); ctx.purge_nmethods(); } + { + GCTraceTime(Debug, gc, phases) ur("Unregister NMethods", timer); + G1CollectedHeap::heap()->bulk_unregister_nmethods(); + } { GCTraceTime(Debug, gc, phases) t("Free Code Blobs", timer); ctx.free_code_blobs(); @@ -2619,6 +2624,33 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec } } +class G1BulkUnregisterNMethodTask : public WorkerTask { + HeapRegionClaimer _hrclaimer; + + class UnregisterNMethodsHeapRegionClosure : public HeapRegionClosure { + public: + + bool do_heap_region(HeapRegion* hr) { + hr->rem_set()->bulk_remove_code_roots(); + return false; + } + } _cl; + +public: + G1BulkUnregisterNMethodTask(uint num_workers) + : WorkerTask("G1 Remove Unlinked NMethods From Code Root Set Task"), + _hrclaimer(num_workers) { } + + void work(uint worker_id) { + G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&_cl, &_hrclaimer, worker_id); + } +}; + +void G1CollectedHeap::bulk_unregister_nmethods() { + uint num_workers = workers()->active_workers(); + G1BulkUnregisterNMethodTask t(num_workers); + workers()->run_task(&t); +} bool G1STWSubjectToDiscoveryClosure::do_object_b(oop obj) { assert(obj != nullptr, "must not be null"); @@ -3039,31 +3071,6 @@ class RegisterNMethodOopClosure: public OopClosure { void do_oop(narrowOop* p) { ShouldNotReachHere(); } }; -class UnregisterNMethodOopClosure: public OopClosure { - G1CollectedHeap* _g1h; - nmethod* _nm; - -public: - UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : - _g1h(g1h), _nm(nm) {} - - void do_oop(oop* p) { - oop heap_oop = RawAccess<>::oop_load(p); - if (!CompressedOops::is_null(heap_oop)) { - oop obj = CompressedOops::decode_not_null(heap_oop); - HeapRegion* hr = _g1h->heap_region_containing(obj); - assert(!hr->is_continues_humongous(), - "trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT - " starting at " HR_FORMAT, - p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - - hr->remove_code_root(_nm); - } - } - - void do_oop(narrowOop* p) { ShouldNotReachHere(); } -}; - void G1CollectedHeap::register_nmethod(nmethod* nm) { guarantee(nm != nullptr, "sanity"); RegisterNMethodOopClosure reg_cl(this, nm); @@ -3071,9 +3078,8 @@ void G1CollectedHeap::register_nmethod(nmethod* nm) { } void G1CollectedHeap::unregister_nmethod(nmethod* nm) { - guarantee(nm != nullptr, "sanity"); - UnregisterNMethodOopClosure reg_cl(this, nm); - nm->oops_do(®_cl, true); + // We always unregister nmethods in bulk during code unloading only. + ShouldNotReachHere(); } void G1CollectedHeap::update_used_after_gc(bool evacuation_failed) { diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 9d4566916ff..447535f2f86 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1267,6 +1267,8 @@ class G1CollectedHeap : public CollectedHeap { void unload_classes_and_code(const char* description, BoolObjectClosure* cl, GCTimer* timer); + void bulk_unregister_nmethods(); + // Verification // Perform any cleanup actions necessary before allowing a verification. diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp index a805108537a..4a124c20749 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp @@ -110,6 +110,10 @@ void HeapRegionRemSet::remove_code_root(nmethod* nm) { guarantee(!_code_roots.contains(nm), "duplicate entry found"); } +void HeapRegionRemSet::bulk_remove_code_roots() { + _code_roots.bulk_remove(); +} + void HeapRegionRemSet::code_roots_do(CodeBlobClosure* blk) const { _code_roots.nmethods_do(blk); } diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp index 15c472d0ac9..facefde918f 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp @@ -151,6 +151,7 @@ class HeapRegionRemSet : public CHeapObj { void add_code_root(nmethod* nm); void add_code_root_locked(nmethod* nm); void remove_code_root(nmethod* nm); + void bulk_remove_code_roots(); // Applies blk->do_code_blob() to each of the entries in _code_roots void code_roots_do(CodeBlobClosure* blk) const; diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 45e734231a5..40488093f7d 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -527,6 +527,14 @@ void ParallelScavengeHeap::resize_all_tlabs() { CollectedHeap::resize_all_tlabs(); } +void ParallelScavengeHeap::prune_scavengable_nmethods() { + ScavengableNMethods::prune_nmethods_not_into_young(); +} + +void ParallelScavengeHeap::prune_unlinked_nmethods() { + ScavengableNMethods::prune_unlinked_nmethods(); +} + // This method is used by System.gc() and JVMTI. void ParallelScavengeHeap::collect(GCCause::Cause cause) { assert(!Heap_lock->owned_by_self(), @@ -858,10 +866,6 @@ void ParallelScavengeHeap::verify_nmethod(nmethod* nm) { ScavengableNMethods::verify_nmethod(nm); } -void ParallelScavengeHeap::prune_scavengable_nmethods() { - ScavengableNMethods::prune_nmethods(); -} - GrowableArray ParallelScavengeHeap::memory_managers() { GrowableArray memory_managers(2); memory_managers.append(_young_manager); diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index abf87b0e019..e71dc9515aa 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -174,6 +174,7 @@ class ParallelScavengeHeap : public CollectedHeap { void verify_nmethod(nmethod* nm) override; void prune_scavengable_nmethods(); + void prune_unlinked_nmethods(); size_t max_capacity() const override; diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 9baf0c21db6..741d415fe91 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1769,6 +1769,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ref_processor()->start_discovery(maximum_heap_compaction); ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* unregister_nmethods_during_purge */, false /* lock_codeblob_free_separately */); marking_phase(&_gc_tracer); @@ -2078,6 +2079,10 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { // Release unloaded nmethod's memory. ctx->purge_nmethods(); } + { + GCTraceTime(Debug, gc, phases) ur("Unregister NMethods", &_gc_timer); + ParallelScavengeHeap::heap()->prune_unlinked_nmethods(); + } { GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); ctx->free_code_blobs(); diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp index 82e0181dbc3..7d06fe588ac 100644 --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp @@ -215,6 +215,10 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Release unloaded nmethod's memory. ctx->purge_nmethods(); } + { + GCTraceTime(Debug, gc, phases) ur("Unregister NMethods", gc_timer()); + gch->prune_unlinked_nmethods(); + } { GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); ctx->free_code_blobs(); diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 8f126c3129e..9361a4e5eb9 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -28,6 +28,7 @@ #include "gc/serial/tenuredGeneration.inline.hpp" #include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/genMemoryPools.hpp" +#include "gc/shared/scavengableNMethods.hpp" #include "gc/shared/strongRootsScope.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.cpp b/src/hotspot/share/gc/shared/classUnloadingContext.cpp index f624eaa6e44..6d9674ef801 100644 --- a/src/hotspot/share/gc/shared/classUnloadingContext.cpp +++ b/src/hotspot/share/gc/shared/classUnloadingContext.cpp @@ -32,10 +32,13 @@ ClassUnloadingContext* ClassUnloadingContext::_context = nullptr; -ClassUnloadingContext::ClassUnloadingContext(uint num_workers, bool lock_codeblob_free_separately) : +ClassUnloadingContext::ClassUnloadingContext(uint num_workers, + bool unregister_nmethods_during_purge, + bool lock_codeblob_free_separately) : _cld_head(nullptr), _num_nmethod_unlink_workers(num_workers), _unlinked_nmethods(nullptr), + _unregister_nmethods_during_purge(unregister_nmethods_during_purge), _lock_codeblob_free_separately(lock_codeblob_free_separately) { assert(_context == nullptr, "context already set"); @@ -113,7 +116,7 @@ void ClassUnloadingContext::purge_nmethods() { NMethodSet* set = _unlinked_nmethods[i]; for (nmethod* nm : *set) { freed_memory += nm->size(); - nm->purge(false /* free_code_cache_data */); + nm->purge(false /* free_code_cache_data */, _unregister_nmethods_during_purge); } } diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.hpp b/src/hotspot/share/gc/shared/classUnloadingContext.hpp index 42a8f764fa4..30930967d38 100644 --- a/src/hotspot/share/gc/shared/classUnloadingContext.hpp +++ b/src/hotspot/share/gc/shared/classUnloadingContext.hpp @@ -42,6 +42,7 @@ class ClassUnloadingContext : public CHeapObj { using NMethodSet = GrowableArrayCHeap; NMethodSet** _unlinked_nmethods; + bool _unregister_nmethods_during_purge; bool _lock_codeblob_free_separately; public: @@ -49,10 +50,14 @@ class ClassUnloadingContext : public CHeapObj { // Num_nmethod_unlink_workers configures the maximum numbers of threads unlinking // nmethods. + // unregister_nmethods_during_purge determines whether unloaded nmethods should + // be unregistered from the garbage collector during purge. If not, ,the caller + // is responsible to do that later. // lock_codeblob_free_separately determines whether freeing the code blobs takes // the CodeCache_lock during the whole operation (=false) or per code blob // free operation (=true). ClassUnloadingContext(uint num_nmethod_unlink_workers, + bool unregister_nmethods_during_purge, bool lock_codeblob_free_separately); ~ClassUnloadingContext(); diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 0854a4776f0..d67a4cb636b 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -557,6 +557,7 @@ void GenCollectedHeap::do_collection(bool full, CodeCache::on_gc_marking_cycle_start(); ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* unregister_nmethods_during_purge */, false /* lock_codeblob_free_separately */); collect_generation(_old_gen, @@ -615,7 +616,11 @@ void GenCollectedHeap::verify_nmethod(nmethod* nm) { } void GenCollectedHeap::prune_scavengable_nmethods() { - ScavengableNMethods::prune_nmethods(); + ScavengableNMethods::prune_nmethods_not_into_young(); +} + +void GenCollectedHeap::prune_unlinked_nmethods() { + ScavengableNMethods::prune_unlinked_nmethods(); } HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) { diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.hpp b/src/hotspot/share/gc/shared/genCollectedHeap.hpp index f279c7588de..271703b6dc0 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp @@ -205,6 +205,7 @@ class GenCollectedHeap : public CollectedHeap { void verify_nmethod(nmethod* nm) override; void prune_scavengable_nmethods(); + void prune_unlinked_nmethods(); // Iteration functions. void oop_iterate(OopIterateClosure* cl); diff --git a/src/hotspot/share/gc/shared/scavengableNMethods.cpp b/src/hotspot/share/gc/shared/scavengableNMethods.cpp index ec9983da4a9..9f961ff4bf8 100644 --- a/src/hotspot/share/gc/shared/scavengableNMethods.cpp +++ b/src/hotspot/share/gc/shared/scavengableNMethods.cpp @@ -59,18 +59,8 @@ void ScavengableNMethods::register_nmethod(nmethod* nm) { } void ScavengableNMethods::unregister_nmethod(nmethod* nm) { - assert_locked_or_safepoint(CodeCache_lock); - - if (gc_data(nm).on_list()) { - nmethod* prev = nullptr; - for (nmethod* cur = _head; cur != nullptr; cur = gc_data(cur).next()) { - if (cur == nm) { - unlist_nmethod(cur, prev); - return; - } - prev = cur; - } - } + // All users of this method only unregister in bulk during code unloading. + ShouldNotReachHere(); } #ifndef PRODUCT @@ -172,10 +162,37 @@ void ScavengableNMethods::nmethods_do_and_prune(CodeBlobToOopClosure* cl) { debug_only(verify_unlisted_nmethods(nullptr)); } -void ScavengableNMethods::prune_nmethods() { +void ScavengableNMethods::prune_nmethods_not_into_young() { nmethods_do_and_prune(nullptr /* No closure */); } +void ScavengableNMethods::prune_unlinked_nmethods() { + assert_locked_or_safepoint(CodeCache_lock); + + debug_only(mark_on_list_nmethods()); + + nmethod* prev = nullptr; + nmethod* cur = _head; + while (cur != nullptr) { + ScavengableNMethodsData data = gc_data(cur); + debug_only(data.clear_marked()); + assert(data.on_list(), "else shouldn't be on this list"); + + nmethod* const next = data.next(); + + if (cur->is_unlinked()) { + unlist_nmethod(cur, prev); + } else { + prev = cur; + } + + cur = next; + } + + // Check for stray marks. + debug_only(verify_unlisted_nmethods(nullptr)); +} + // Walk the list of methods which might contain oops to the java heap. void ScavengableNMethods::nmethods_do(CodeBlobToOopClosure* cl) { nmethods_do_and_prune(cl); @@ -218,8 +235,9 @@ void ScavengableNMethods::mark_on_list_nmethods() { nmethod* nm = iter.method(); ScavengableNMethodsData data = gc_data(nm); assert(data.not_marked(), "clean state"); - if (data.on_list()) + if (data.on_list()) { data.set_marked(); + } } } @@ -230,7 +248,10 @@ void ScavengableNMethods::verify_unlisted_nmethods(CodeBlobClosure* cl) { while(iter.next()) { nmethod* nm = iter.method(); - verify_nmethod(nm); + // Can not verify already unlinked nmethods as they are partially invalid already. + if (!nm->is_unlinked()) { + verify_nmethod(nm); + } if (cl != nullptr && !gc_data(nm).on_list()) { cl->do_code_blob(nm); diff --git a/src/hotspot/share/gc/shared/scavengableNMethods.hpp b/src/hotspot/share/gc/shared/scavengableNMethods.hpp index 4852e6d32fb..94d594cd529 100644 --- a/src/hotspot/share/gc/shared/scavengableNMethods.hpp +++ b/src/hotspot/share/gc/shared/scavengableNMethods.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,8 +46,10 @@ class ScavengableNMethods : public AllStatic { static void unregister_nmethod(nmethod* nm); static void verify_nmethod(nmethod* nm); - // Remove nmethods that no longer have scavengable oops. - static void prune_nmethods(); + // Remove nmethods that no longer have oops into young gen. + static void prune_nmethods_not_into_young(); + // Remvoe unlinked (dead) nmethods. + static void prune_unlinked_nmethods(); // Apply closure to every scavengable nmethod. // Remove nmethods that no longer have scavengable oops. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 2e6ac1c356a..91fc66b1204 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1769,6 +1769,7 @@ void ShenandoahHeap::stop() { void ShenandoahHeap::stw_unload_classes(bool full_gc) { if (!unload_classes()) return; ClassUnloadingContext ctx(_workers->active_workers(), + true /* unregister_nmethods_during_purge */, false /* lock_codeblob_free_separately */); // Unload classes and purge SystemDictionary. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 81eee97f25f..bb13e9b8e22 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -140,6 +140,7 @@ void ShenandoahUnload::unload() { assert(heap->is_concurrent_weak_root_in_progress(), "Filtered by caller"); ClassUnloadingContext ctx(heap->workers()->active_workers(), + true /* unregister_nmethods_during_purge */, true /* lock_codeblob_free_separately */); // Unlink stale metadata and nmethods diff --git a/src/hotspot/share/gc/x/xHeap.cpp b/src/hotspot/share/gc/x/xHeap.cpp index 65da4e1c983..14661330e13 100644 --- a/src/hotspot/share/gc/x/xHeap.cpp +++ b/src/hotspot/share/gc/x/xHeap.cpp @@ -322,6 +322,7 @@ void XHeap::process_non_strong_references() { _weak_roots_processor.process_weak_roots(); ClassUnloadingContext ctx(_workers.active_workers(), + true /* unregister_nmethods_during_purge */, true /* lock_codeblob_free_separately */); // Unlink stale metadata and nmethods diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index bb0653f72ea..0b131c65248 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -1322,6 +1322,7 @@ void ZGenerationOld::process_non_strong_references() { _weak_roots_processor.process_weak_roots(); ClassUnloadingContext ctx(_workers.active_workers(), + true /* unregister_nmethods_during_purge */, true /* lock_codeblob_free_separately */); // Unlink stale metadata and nmethods From ec6b32601095017a2641f4b82143e83bef5f37b6 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 7 May 2024 09:47:45 +0000 Subject: [PATCH 256/298] 8310913: Move ReferencedKeyMap to jdk.internal so it may be shared Reviewed-by: rrich Backport-of: 6af0af593446bc33dc94bbf7334c325c4ac0ac0f --- .../classes/java/lang/invoke/MethodType.java | 133 +----------- .../classes/java/lang/runtime/Carriers.java | 3 +- .../internal/access/JavaLangRefAccess.java | 2 +- .../internal/util}/ReferenceKey.java | 12 +- .../internal/util}/ReferencedKeyMap.java | 156 +++++++++++-- .../jdk/internal/util/ReferencedKeySet.java | 205 ++++++++++++++++++ .../internal/util}/SoftReferenceKey.java | 7 +- .../internal/util}/StrongReferenceKey.java | 5 +- .../internal/util}/WeakReferenceKey.java | 7 +- .../java/lang/runtime/ReferencedKeyTest.java | 109 ---------- .../jdk/internal/util/ReferencedKeyTest.java | 175 +++++++++++++++ 11 files changed, 537 insertions(+), 277 deletions(-) rename src/java.base/share/classes/{java/lang/runtime => jdk/internal/util}/ReferenceKey.java (81%) rename src/java.base/share/classes/{java/lang/runtime => jdk/internal/util}/ReferencedKeyMap.java (63%) create mode 100644 src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java rename src/java.base/share/classes/{java/lang/runtime => jdk/internal/util}/SoftReferenceKey.java (94%) rename src/java.base/share/classes/{java/lang/runtime => jdk/internal/util}/StrongReferenceKey.java (93%) rename src/java.base/share/classes/{java/lang/runtime => jdk/internal/util}/WeakReferenceKey.java (94%) delete mode 100644 test/jdk/java/lang/runtime/ReferencedKeyTest.java create mode 100644 test/jdk/jdk/internal/util/ReferencedKeyTest.java diff --git a/src/java.base/share/classes/java/lang/invoke/MethodType.java b/src/java.base/share/classes/java/lang/invoke/MethodType.java index 951d209b69f..447a26e7600 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -33,7 +33,9 @@ import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Collections; +import java.util.function.Supplier; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; @@ -42,7 +44,8 @@ import java.util.concurrent.ConcurrentMap; import java.util.stream.Stream; -import jdk.internal.access.SharedSecrets; +import jdk.internal.util.ReferencedKeySet; +import jdk.internal.util.ReferenceKey; import jdk.internal.vm.annotation.Stable; import sun.invoke.util.BytecodeDescriptor; import sun.invoke.util.VerifyType; @@ -227,7 +230,13 @@ private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num return new IndexOutOfBoundsException(num.toString()); } - static final ConcurrentWeakInternSet internTable = new ConcurrentWeakInternSet<>(); + static final ReferencedKeySet internTable = + ReferencedKeySet.create(false, true, new Supplier<>() { + @Override + public Map, ReferenceKey> get() { + return new ConcurrentHashMap<>(512); + } + }); static final Class[] NO_PTYPES = {}; @@ -405,7 +414,7 @@ private static MethodType makeImpl(Class rtype, Class[] ptypes, boolean tr mt = new MethodType(rtype, ptypes); } mt.form = MethodTypeForm.findForm(mt); - return internTable.add(mt); + return internTable.intern(mt); } private static final @Stable MethodType[] objectOnlyTypes = new MethodType[20]; @@ -883,10 +892,6 @@ public Class[] parameterArray() { * @param x object to compare * @see Object#equals(Object) */ - // This implementation may also return true if x is a WeakEntry containing - // a method type that is equal to this. This is an internal implementation - // detail to allow for faster method type lookups. - // See ConcurrentWeakInternSet.WeakEntry#equals(Object) @Override public boolean equals(Object x) { if (this == x) { @@ -895,12 +900,6 @@ public boolean equals(Object x) { if (x instanceof MethodType) { return equals((MethodType)x); } - if (x instanceof ConcurrentWeakInternSet.WeakEntry) { - Object o = ((ConcurrentWeakInternSet.WeakEntry)x).get(); - if (o instanceof MethodType) { - return equals((MethodType)o); - } - } return false; } @@ -1392,112 +1391,4 @@ private Object readResolve() { wrapAlt = null; return mt; } - - /** - * Simple implementation of weak concurrent intern set. - * - * @param interned type - */ - private static class ConcurrentWeakInternSet { - - private final ConcurrentMap, WeakEntry> map; - private final ReferenceQueue stale; - - public ConcurrentWeakInternSet() { - this.map = new ConcurrentHashMap<>(512); - this.stale = SharedSecrets.getJavaLangRefAccess().newNativeReferenceQueue(); - } - - /** - * Get the existing interned element. - * This method returns null if no element is interned. - * - * @param elem element to look up - * @return the interned element - */ - public T get(T elem) { - if (elem == null) throw new NullPointerException(); - expungeStaleElements(); - - WeakEntry value = map.get(elem); - if (value != null) { - T res = value.get(); - if (res != null) { - return res; - } - } - return null; - } - - /** - * Interns the element. - * Always returns non-null element, matching the one in the intern set. - * Under the race against another add(), it can return different - * element, if another thread beats us to interning it. - * - * @param elem element to add - * @return element that was actually added - */ - public T add(T elem) { - if (elem == null) throw new NullPointerException(); - - // Playing double race here, and so spinloop is required. - // First race is with two concurrent updaters. - // Second race is with GC purging weak ref under our feet. - // Hopefully, we almost always end up with a single pass. - T interned; - WeakEntry e = new WeakEntry<>(elem, stale); - do { - expungeStaleElements(); - WeakEntry exist = map.putIfAbsent(e, e); - interned = (exist == null) ? elem : exist.get(); - } while (interned == null); - return interned; - } - - private void expungeStaleElements() { - Reference reference; - while ((reference = stale.poll()) != null) { - map.remove(reference); - } - } - - private static class WeakEntry extends WeakReference { - - public final int hashcode; - - public WeakEntry(T key, ReferenceQueue queue) { - super(key, queue); - hashcode = key.hashCode(); - } - - /** - * This implementation returns {@code true} if {@code obj} is another - * {@code WeakEntry} whose referent is equal to this referent, or - * if {@code obj} is equal to the referent of this. This allows - * lookups to be made without wrapping in a {@code WeakEntry}. - * - * @param obj the object to compare - * @return true if {@code obj} is equal to this or the referent of this - * @see MethodType#equals(Object) - * @see Object#equals(Object) - */ - @Override - public boolean equals(Object obj) { - Object mine = get(); - if (obj instanceof WeakEntry) { - Object that = ((WeakEntry) obj).get(); - return (that == null || mine == null) ? (this == obj) : mine.equals(that); - } - return (mine == null) ? (obj == null) : mine.equals(obj); - } - - @Override - public int hashCode() { - return hashcode; - } - - } - } - } diff --git a/src/java.base/share/classes/java/lang/runtime/Carriers.java b/src/java.base/share/classes/java/lang/runtime/Carriers.java index e0ebc998ee5..a74144fcbeb 100644 --- a/src/java.base/share/classes/java/lang/runtime/Carriers.java +++ b/src/java.base/share/classes/java/lang/runtime/Carriers.java @@ -35,6 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; import jdk.internal.misc.Unsafe; +import jdk.internal.util.ReferencedKeyMap; import static java.lang.invoke.MethodType.methodType; @@ -366,7 +367,7 @@ MethodHandle[] createComponents(CarrierShape carrierShape) { * Cache mapping {@link MethodType} to previously defined {@link CarrierElements}. */ private static final Map - methodTypeCache = ReferencedKeyMap.create(ConcurrentHashMap::new); + methodTypeCache = ReferencedKeyMap.create(false, ConcurrentHashMap::new); /** * Permute a raw constructor and component accessor {@link MethodHandle MethodHandles} to diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangRefAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangRefAccess.java index b9b180fc2da..ed9967ec3eb 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangRefAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangRefAccess.java @@ -54,7 +54,7 @@ public interface JavaLangRefAccess { /** * Constructs a new NativeReferenceQueue. * - * Invoked by MethodType.ConcurrentWeakInternSet + * Invoked by jdk.internal.util.ReferencedKeyMap */ ReferenceQueue newNativeReferenceQueue(); } diff --git a/src/java.base/share/classes/java/lang/runtime/ReferenceKey.java b/src/java.base/share/classes/jdk/internal/util/ReferenceKey.java similarity index 81% rename from src/java.base/share/classes/java/lang/runtime/ReferenceKey.java rename to src/java.base/share/classes/jdk/internal/util/ReferenceKey.java index 983d81d3a0f..a193794fe70 100644 --- a/src/java.base/share/classes/java/lang/runtime/ReferenceKey.java +++ b/src/java.base/share/classes/jdk/internal/util/ReferenceKey.java @@ -23,12 +23,9 @@ * questions. */ -package java.lang.runtime; +package jdk.internal.util; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.Objects; +import java.lang.ref.Reference; /** * View/wrapper of keys used by the backing {@link ReferencedKeyMap}. @@ -39,11 +36,8 @@ * @param key type * * @since 21 - * - * Warning: This class is part of PreviewFeature.Feature.STRING_TEMPLATES. - * Do not rely on its availability. */ -sealed interface ReferenceKey permits StrongReferenceKey, WeakReferenceKey, SoftReferenceKey { +public sealed interface ReferenceKey permits StrongReferenceKey, WeakReferenceKey, SoftReferenceKey { /** * {@return the value of the unwrapped key} */ diff --git a/src/java.base/share/classes/java/lang/runtime/ReferencedKeyMap.java b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java similarity index 63% rename from src/java.base/share/classes/java/lang/runtime/ReferencedKeyMap.java rename to src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java index 1ded08c4cba..f102e3c94e1 100644 --- a/src/java.base/share/classes/java/lang/runtime/ReferencedKeyMap.java +++ b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java @@ -23,7 +23,7 @@ * questions. */ -package java.lang.runtime; +package jdk.internal.util; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; @@ -37,9 +37,12 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.internal.access.SharedSecrets; + /** * This class provides management of {@link Map maps} where it is desirable to * remove entries automatically when the key is garbage collected. This is @@ -78,11 +81,8 @@ * @param the type of mapped values * * @since 21 - * - * Warning: This class is part of PreviewFeature.Feature.STRING_TEMPLATES. - * Do not rely on its availability. */ -final class ReferencedKeyMap implements Map { +public final class ReferencedKeyMap implements Map { /** * true if {@link SoftReference} keys are to be used, * {@link WeakReference} otherwise. @@ -95,54 +95,61 @@ final class ReferencedKeyMap implements Map { private final Map, V> map; /** - * {@link ReferenceQueue} for cleaning up {@link WeakReferenceKey EntryKeys}. + * {@link ReferenceQueue} for cleaning up entries. */ private final ReferenceQueue stale; /** * Private constructor. * - * @param isSoft true if {@link SoftReference} keys are to - * be used, {@link WeakReference} otherwise. - * @param map backing map + * @param isSoft true if {@link SoftReference} keys are to + * be used, {@link WeakReference} otherwise. + * @param map backing map + * @param stale {@link ReferenceQueue} for cleaning up entries */ - private ReferencedKeyMap(boolean isSoft, Map, V> map) { + private ReferencedKeyMap(boolean isSoft, Map, V> map, ReferenceQueue stale) { this.isSoft = isSoft; this.map = map; - this.stale = new ReferenceQueue<>(); + this.stale = stale; } /** * Create a new {@link ReferencedKeyMap} map. * - * @param isSoft true if {@link SoftReference} keys are to - * be used, {@link WeakReference} otherwise. - * @param supplier {@link Supplier} of the backing map + * @param isSoft true if {@link SoftReference} keys are to + * be used, {@link WeakReference} otherwise. + * @param supplier {@link Supplier} of the backing map * * @return a new map with {@link Reference} keys * * @param the type of keys maintained by the new map * @param the type of mapped values */ - static ReferencedKeyMap + public static ReferencedKeyMap create(boolean isSoft, Supplier, V>> supplier) { - return new ReferencedKeyMap(isSoft, supplier.get()); + return create(isSoft, false, supplier); } /** - * Create a new {@link ReferencedKeyMap} map using - * {@link WeakReference} keys. + * Create a new {@link ReferencedKeyMap} map. * - * @param supplier {@link Supplier} of the backing map + * @param isSoft true if {@link SoftReference} keys are to + * be used, {@link WeakReference} otherwise. + * @param useNativeQueue true if uses NativeReferenceQueue + * otherwise use {@link ReferenceQueue}. + * @param supplier {@link Supplier} of the backing map * * @return a new map with {@link Reference} keys * * @param the type of keys maintained by the new map * @param the type of mapped values */ - static ReferencedKeyMap - create(Supplier, V>> supplier) { - return new ReferencedKeyMap(false, supplier.get()); + public static ReferencedKeyMap + create(boolean isSoft, boolean useNativeQueue, Supplier, V>> supplier) { + return new ReferencedKeyMap(isSoft, supplier.get(), + useNativeQueue ? SharedSecrets.getJavaLangRefAccess().newNativeReferenceQueue() + : new ReferenceQueue<>() + ); } /** @@ -320,10 +327,9 @@ public String toString() { /** * Removes enqueued weak references from map. */ - @SuppressWarnings("unchecked") public void removeStaleReferences() { while (true) { - WeakReferenceKey key = (WeakReferenceKey)stale.poll(); + Object key = stale.poll(); if (key == null) { break; } @@ -331,4 +337,106 @@ public void removeStaleReferences() { } } + /** + * Puts an entry where the key and the value are the same. Used for + * interning values in a set. + * + * @implNote Requires a {@link ReferencedKeyMap} whose {@code V} type + * is a {@code ReferenceKey}. Otherwise, a {@link ClassCastException} will + * be thrown. + * + * @param setMap {@link ReferencedKeyMap} where interning takes place + * @param key key to add + * + * @param type of key + * + * @return the old key instance if found otherwise the new key instance + * + * @throws ClassCastException if {@code V} is not {@code EntryKey} + */ + static T intern(ReferencedKeyMap> setMap, T key) { + T value = existingKey(setMap, key); + if (value != null) { + return value; + } + return internKey(setMap, key); + } + + /** + * Puts an entry where the key and the value are the same. Used for + * interning values in a set. + * + * @implNote Requires a {@link ReferencedKeyMap} whose {@code V} type + * is a {@code ReferenceKey}. Otherwise, a {@link ClassCastException} will + * be thrown. + * + * @param setMap {@link ReferencedKeyMap} where interning takes place + * @param key key to add + * @param interner operation to apply to key before adding to map + * + * @param type of key + * + * @return the old key instance if found otherwise the new key instance + * + * @throws ClassCastException if {@code V} is not {@code EntryKey} + * + * @implNote This version of intern should not be called during phase1 + * using a lambda. Use an UnaryOperator instance instead. + */ + static T intern(ReferencedKeyMap> setMap, T key, UnaryOperator interner) { + T value = existingKey(setMap, key); + if (value != null) { + return value; + } + key = interner.apply(key); + return internKey(setMap, key); + } + + /** + * Check if the key already exists in the map. + * + * @param setMap {@link ReferencedKeyMap} where interning takes place + * @param key key to test + * + * @param type of key + * + * @return key if found otherwise null + */ + private static T existingKey(ReferencedKeyMap> setMap, T key) { + setMap.removeStaleReferences(); + ReferenceKey entryKey = setMap.get(setMap.lookupKey(key)); + return entryKey != null ? entryKey.get() : null; + } + + /** + * Attempt to add key to map. + * + * @param setMap {@link ReferencedKeyMap} where interning takes place + * @param key key to add + * + * @param type of key + * + * @return the old key instance if found otherwise the new key instance + */ + private static T internKey(ReferencedKeyMap> setMap, T key) { + ReferenceKey entryKey = setMap.entryKey(key); + T interned; + do { + setMap.removeStaleReferences(); + ReferenceKey existing = setMap.map.putIfAbsent(entryKey, entryKey); + if (existing == null) { + return key; + } else { + // If {@code putIfAbsent} returns non-null then was actually a + // {@code replace} and older key was used. In that case the new + // key was not used and the reference marked stale. + interned = existing.get(); + if (interned != null) { + entryKey.unused(); + } + } + } while (interned == null); + return interned; + } + } diff --git a/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java b/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java new file mode 100644 index 00000000000..807eea87dfe --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2023, 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.internal.util; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +/** + * This class provides management of {@link Set set} where it is desirable to + * remove elements automatically when the element is garbage collected. This is + * accomplished by using a backing map where the keys and values are either a + * {@link WeakReference} or a {@link SoftReference}. + *

      + * To create a {@link ReferencedKeySet} the user must provide a {@link Supplier} + * of the backing map and whether {@link WeakReference} or + * {@link SoftReference} is to be used. + * {@snippet : + * Set set; + * + * set = ReferencedKeySet.create(false, HashMap::new); + * set.add(30_000_000L); + * set.add(30_000_001L); + * set.add(30_000_002L); + * set.add(30_000_003L); + * set.add(30_000_004L); + * + * set = ReferencedKeySet.create(true, ConcurrentHashMap::new); + * set.add(40_000_000L); + * set.add(40_000_001L); + * set.add(40_000_002L); + * set.add(40_000_003L); + * set.add(40_000_004L); + * } + * + * @implNote Care must be given that the backing map does replacement by + * replacing the value in the map entry instead of deleting the old entry and + * adding a new entry, otherwise replaced entries may end up with a strongly + * referenced key. {@link HashMap} and {@link ConcurrentHashMap} are known + * to be safe. + * + * @param the type of elements maintained by this set + */ +public final class ReferencedKeySet extends AbstractSet { + /** + * Backing {@link ReferencedKeySet} map. + */ + final ReferencedKeyMap> map; + + /** + * Private constructor. + * + * @param map backing map + */ + private ReferencedKeySet(ReferencedKeyMap> map) { + this.map = map; + } + + /** + * Create a new {@link ReferencedKeySet} elements. + * + * @param isSoft true if {@link SoftReference} elements are to + * be used, {@link WeakReference} otherwise. + * @param supplier {@link Supplier} of the backing map + * + * @return a new set with {@link Reference} elements + * + * @param the type of elements maintained by this set + */ + public static ReferencedKeySet + create(boolean isSoft, Supplier, ReferenceKey>> supplier) { + return create(isSoft, false, supplier); + } + + /** + * Create a new {@link ReferencedKeySet} elements. + * + * @param isSoft true if {@link SoftReference} elements are to + * be used, {@link WeakReference} otherwise. + * @param useNativeQueue true if uses NativeReferenceQueue + * otherwise use {@link ReferenceQueue}. + * @param supplier {@link Supplier} of the backing map + * + * @return a new set with {@link Reference} elements + * + * @param the type of elements maintained by this set + */ + public static ReferencedKeySet + create(boolean isSoft, boolean useNativeQueue, Supplier, ReferenceKey>> supplier) { + return new ReferencedKeySet<>(ReferencedKeyMap.create(isSoft, useNativeQueue, supplier)); + } + + /** + * Removes enqueued weak references from set. + */ + public void removeStaleReferences() { + map.removeStaleReferences(); + } + + @Override + public Iterator iterator() { + return map.keySet().iterator(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + @SuppressWarnings("unchecked") + public boolean contains(Object o) { + return map.containsKey((T)o); + } + + @Override + public boolean add(T e) { + return intern(e) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove(o) != null; + } + + @Override + public void clear() { + map.clear(); + } + + /** + * Gets an existing element from the set, returning null if not present or + * the old element if previously added. + * + * @param e element to get + * + * @return the old element if present, otherwise, null + */ + public T get(T e) { + ReferenceKey key = map.get(e); + + return key == null ? null : key.get(); + } + + /** + * Intern an element to the set, returning the element if newly added or the + * old element if previously added. + * + * @param e element to add + * + * @return the old element if present, otherwise, the new element + */ + public T intern(T e) { + return ReferencedKeyMap.intern(map, e); + } + + /** + * Intern an element to the set, returning the element if newly added or the + * old element if previously added. + * + * @param e element to add + * @param interner operation to apply to key before adding to set + * + * @return the old element if present, otherwise, the new element + * + * @implNote This version of intern should not be called during phase1 + * using a lambda. Use an UnaryOperator instance instead. + */ + public T intern(T e, UnaryOperator interner) { + return ReferencedKeyMap.intern(map, e, interner); + } +} diff --git a/src/java.base/share/classes/java/lang/runtime/SoftReferenceKey.java b/src/java.base/share/classes/jdk/internal/util/SoftReferenceKey.java similarity index 94% rename from src/java.base/share/classes/java/lang/runtime/SoftReferenceKey.java rename to src/java.base/share/classes/jdk/internal/util/SoftReferenceKey.java index 3bb524e13dd..f7e94e79f0b 100644 --- a/src/java.base/share/classes/java/lang/runtime/SoftReferenceKey.java +++ b/src/java.base/share/classes/jdk/internal/util/SoftReferenceKey.java @@ -23,7 +23,7 @@ * questions. */ -package java.lang.runtime; +package jdk.internal.util; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; @@ -35,9 +35,6 @@ * @param key type * * @since 21 - * - * Warning: This class is part of PreviewFeature.Feature.STRING_TEMPLATES. - * Do not rely on its availability. */ final class SoftReferenceKey extends SoftReference implements ReferenceKey { /** @@ -76,6 +73,8 @@ public boolean equals(Object obj) { if (obj instanceof ReferenceKey key) { obj = key.get(); } + // Note: refersTo is insufficient since keys require equivalence. + // refersTo would also require a cast to type T. return Objects.equals(get(), obj); } diff --git a/src/java.base/share/classes/java/lang/runtime/StrongReferenceKey.java b/src/java.base/share/classes/jdk/internal/util/StrongReferenceKey.java similarity index 93% rename from src/java.base/share/classes/java/lang/runtime/StrongReferenceKey.java rename to src/java.base/share/classes/jdk/internal/util/StrongReferenceKey.java index 3665cad96cc..e3264cd0dca 100644 --- a/src/java.base/share/classes/java/lang/runtime/StrongReferenceKey.java +++ b/src/java.base/share/classes/jdk/internal/util/StrongReferenceKey.java @@ -23,7 +23,7 @@ * questions. */ -package java.lang.runtime; +package jdk.internal.util; import java.util.Objects; @@ -34,9 +34,6 @@ * @param key type * * @since 21 - * - * Warning: This class is part of PreviewFeature.Feature.STRING_TEMPLATES. - * Do not rely on its availability. */ final class StrongReferenceKey implements ReferenceKey { T key; diff --git a/src/java.base/share/classes/java/lang/runtime/WeakReferenceKey.java b/src/java.base/share/classes/jdk/internal/util/WeakReferenceKey.java similarity index 94% rename from src/java.base/share/classes/java/lang/runtime/WeakReferenceKey.java rename to src/java.base/share/classes/jdk/internal/util/WeakReferenceKey.java index 5d18c2e45a0..3fe6d6026d7 100644 --- a/src/java.base/share/classes/java/lang/runtime/WeakReferenceKey.java +++ b/src/java.base/share/classes/jdk/internal/util/WeakReferenceKey.java @@ -23,7 +23,7 @@ * questions. */ -package java.lang.runtime; +package jdk.internal.util; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; @@ -35,9 +35,6 @@ * @param key type * * @since 21 - * - * Warning: This class is part of PreviewFeature.Feature.STRING_TEMPLATES. - * Do not rely on its availability. */ final class WeakReferenceKey extends WeakReference implements ReferenceKey { /** @@ -76,6 +73,8 @@ public boolean equals(Object obj) { if (obj instanceof ReferenceKey key) { obj = key.get(); } + // Note: refersTo is insufficient since keys require equivalence. + // refersTo would also require a cast to type T. return Objects.equals(get(), obj); } diff --git a/test/jdk/java/lang/runtime/ReferencedKeyTest.java b/test/jdk/java/lang/runtime/ReferencedKeyTest.java deleted file mode 100644 index 9234cffb98a..00000000000 --- a/test/jdk/java/lang/runtime/ReferencedKeyTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary Test features provided by the ReferencedKeyMap class. - * @modules java.base/java.lang.runtime - * @enablePreview - * @compile --patch-module java.base=${test.src} ReferencedKeyTest.java - * @run main/othervm --patch-module java.base=${test.class.path} java.lang.runtime.ReferencedKeyTest - */ - -package java.lang.runtime; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; - -public class ReferencedKeyTest { - static long BASE_KEY = 10_000_000L; - - public static void main(String[] args) throws Throwable { - mapTest(false, HashMap::new); - mapTest(true, HashMap::new); - mapTest(false, ConcurrentHashMap::new); - mapTest(true, ConcurrentHashMap::new); - } - - static void assertTrue(boolean test, String message) { - if (!test) { - throw new RuntimeException(message); - } - } - - static void mapTest(boolean isSoft, Supplier, String>> supplier) { - Map map = ReferencedKeyMap.create(isSoft, supplier); - populate(map); - collect(); - // assertTrue(map.isEmpty() || isSoft, "Weak not collecting"); - populate(map); - methods(map); - } - - static void methods(Map map) { - assertTrue(map.size() == 26, "missing key"); - assertTrue(map.containsKey(BASE_KEY + 'a' -'a'), "missing key"); - assertTrue(map.get(BASE_KEY + 'b' -'a').equals("b"), "wrong key"); - assertTrue(map.containsValue("c"), "missing value"); - map.remove(BASE_KEY + 'd' -'a'); - assertTrue(map.get(BASE_KEY + 'd' -'a') == null, "not removed"); - map.putAll(Map.of(1L, "A", 2L, "B")); - assertTrue(map.get(2L).equals("B"), "collection not added"); - assertTrue(map.keySet().contains(1L), "key missing"); - assertTrue(map.values().contains("A"), "key missing"); - assertTrue(map.entrySet().contains(Map.entry(1L, "A")), "key missing"); - map.putIfAbsent(3L, "C"); - assertTrue(map.get(3L).equals("C"), "key missing"); - map.putIfAbsent(2L, "D"); - assertTrue(map.get(2L).equals("B"), "key replaced"); - map.remove(3L); - assertTrue(map.get(3L) == null, "key not removed"); - map.replace(2L, "D"); - assertTrue(map.get(2L).equals("D"), "key not replaced"); - map.replace(2L, "B", "E"); - assertTrue(map.get(2L).equals("D"), "key replaced"); - } - - static void collect() { - System.gc(); - sleep(); - } - - static void sleep() { - try { - Thread.sleep(100L); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - static void populate(Map map) { - for (int i = 0; i < 26; i++) { - Long key = BASE_KEY + i; - String value = String.valueOf((char) ('a' + i)); - map.put(key, value); - } - } -} diff --git a/test/jdk/jdk/internal/util/ReferencedKeyTest.java b/test/jdk/jdk/internal/util/ReferencedKeyTest.java new file mode 100644 index 00000000000..c5edaedd2e2 --- /dev/null +++ b/test/jdk/jdk/internal/util/ReferencedKeyTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8285932 8310913 + * @summary Test features provided by the ReferencedKeyMap/ReferencedKeySet classes. + * @modules java.base/jdk.internal.util + * @compile --patch-module java.base=${test.src} ReferencedKeyTest.java + * @run main/othervm --patch-module java.base=${test.class.path} jdk.internal.util.ReferencedKeyTest + */ + +package jdk.internal.util; + +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BooleanSupplier; +import java.util.function.Supplier; + +public class ReferencedKeyTest { + static long BASE_KEY = 10_000_000L; + + public static void main(String[] args) { + mapTest(false, HashMap::new); + mapTest(true, HashMap::new); + mapTest(false, ConcurrentHashMap::new); + mapTest(true, ConcurrentHashMap::new); + + setTest(false, HashMap::new); + setTest(true, HashMap::new); + setTest(false, ConcurrentHashMap::new); + setTest(true, ConcurrentHashMap::new); + } + + static void assertTrue(boolean test, String message) { + if (!test) { + throw new RuntimeException(message); + } + } + + static void mapTest(boolean isSoft, Supplier, String>> supplier) { + Map map = ReferencedKeyMap.create(isSoft, supplier); + populate(map); + if (!isSoft) { + if (!collect(() -> map.isEmpty())) { + throw new RuntimeException("WeakReference map not collecting!"); + } + } + populate(map); + methods(map); + } + + static void setTest(boolean isSoft, Supplier, ReferenceKey>> supplier) { + ReferencedKeySet set = ReferencedKeySet.create(isSoft, supplier); + populate(set); + if (!isSoft) { + if (!collect(() -> set.isEmpty())) { + throw new RuntimeException("WeakReference set not collecting!"); + } + } + populate(set); + methods(set); + } + + static void methods(Map map) { + assertTrue(map.size() == 26, "missing key"); + assertTrue(map.containsKey(BASE_KEY + 'a' -'a'), "missing key"); + assertTrue(map.get(BASE_KEY + 'b' -'a').equals("b"), "wrong key"); + assertTrue(map.containsValue("c"), "missing value"); + map.remove(BASE_KEY + 'd' -'a'); + assertTrue(map.get(BASE_KEY + 'd' -'a') == null, "not removed"); + map.putAll(Map.of(1L, "A", 2L, "B")); + assertTrue(map.get(2L).equals("B"), "collection not added"); + assertTrue(map.containsKey(1L), "key missing"); + assertTrue(map.containsValue("A"), "key missing"); + assertTrue(map.entrySet().contains(Map.entry(1L, "A")), "key missing"); + map.putIfAbsent(3L, "C"); + assertTrue(map.get(3L).equals("C"), "key missing"); + map.putIfAbsent(2L, "D"); + assertTrue(map.get(2L).equals("B"), "key replaced"); + map.remove(3L); + assertTrue(map.get(3L) == null, "key not removed"); + map.replace(2L, "D"); + assertTrue(map.get(2L).equals("D"), "key not replaced"); + map.replace(2L, "B", "E"); + assertTrue(map.get(2L).equals("D"), "key replaced"); + } + + static void methods(ReferencedKeySet set) { + assertTrue(set.size() == 26, "missing key"); + assertTrue(set.contains(BASE_KEY + 3), "missing key"); + set.remove(BASE_KEY + 3); + assertTrue(!set.contains(BASE_KEY + 3), "not removed"); + Long element1 = set.get(BASE_KEY + 2); + Long element2 = set.get(BASE_KEY + 3); + Long element3 = set.get(BASE_KEY + 4); + Long intern1 = set.intern(BASE_KEY + 2); + Long intern2 = set.intern(BASE_KEY + 3); + Long intern3 = set.intern(BASE_KEY + 4, e -> e); + assertTrue(element1 != null, "missing key"); + assertTrue(element2 == null, "not removed"); + assertTrue(element1 == intern1, "intern failed"); // must be same object + assertTrue(intern2 != null, "intern failed"); + assertTrue(element3 == intern3, "intern failed"); + } + + // Borrowed from jdk.test.lib.util.ForceGC but couldn't use from java.base/jdk.internal.util + static boolean collect(BooleanSupplier booleanSupplier) { + ReferenceQueue queue = new ReferenceQueue<>(); + Object obj = new Object(); + PhantomReference ref = new PhantomReference<>(obj, queue); + obj = null; + Reference.reachabilityFence(obj); + Reference.reachabilityFence(ref); + long timeout = 1000L; + long quanta = 200L; + long retries = timeout / quanta; + + for (; retries >= 0; retries--) { + if (booleanSupplier.getAsBoolean()) { + return true; + } + + System.gc(); + + try { + queue.remove(quanta); + } catch (InterruptedException ie) { + // ignore, the loop will try again + } + } + + return booleanSupplier.getAsBoolean(); + } + + static void populate(Map map) { + for (int i = 0; i < 26; i++) { + Long key = BASE_KEY + i; + String value = String.valueOf((char) ('a' + i)); + map.put(key, value); + } + } + + static void populate(Set set) { + for (int i = 0; i < 26; i++) { + Long value = BASE_KEY + i; + set.add(value); + } + } +} From 41fda4a528e1b1a0620445392fb8a1579b3c32f2 Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Tue, 7 May 2024 13:17:45 +0000 Subject: [PATCH 257/298] 8319376: ParallelGC: Forwarded objects found during heap inspection Backport-of: 59e9981ec21258b8aa5f93cb1fb9b0ccf9f846af --- src/hotspot/share/gc/parallel/mutableSpace.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/parallel/mutableSpace.cpp b/src/hotspot/share/gc/parallel/mutableSpace.cpp index 69ebf86c7c2..cdbd0ac4813 100644 --- a/src/hotspot/share/gc/parallel/mutableSpace.cpp +++ b/src/hotspot/share/gc/parallel/mutableSpace.cpp @@ -236,7 +236,18 @@ void MutableSpace::oop_iterate(OopIterateClosure* cl) { void MutableSpace::object_iterate(ObjectClosure* cl) { HeapWord* p = bottom(); while (p < top()) { - cl->do_object(cast_to_oop(p)); + oop obj = cast_to_oop(p); + // When promotion-failure occurs during Young GC, eden/from space is not cleared, + // so we can encounter objects with "forwarded" markword. + // They are essentially dead, so skipping them + if (!obj->is_forwarded()) { + cl->do_object(obj); + } +#ifdef ASSERT + else { + assert(obj->forwardee() != obj, "must not be self-forwarded"); + } +#endif p += cast_to_oop(p)->size(); } } From 93d091ad35cccc9c7010ae6481a61feee7830e92 Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Tue, 7 May 2024 13:20:39 +0000 Subject: [PATCH 258/298] 8314573: G1: Heap resizing at Remark does not take existing eden regions into account Backport-of: 762b652912939b37fbd68955617705c62b9fc3a5 --- src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp b/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp index 1a7c11a685b..8645b847045 100644 --- a/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp @@ -217,7 +217,14 @@ size_t G1HeapSizingPolicy::full_collection_resize_amount(bool& expand) { // Capacity, free and used after the GC counted as full regions to // include the waste in the following calculations. const size_t capacity_after_gc = _g1h->capacity(); - const size_t used_after_gc = capacity_after_gc - _g1h->unused_committed_regions_in_bytes(); + const size_t used_after_gc = capacity_after_gc - + _g1h->unused_committed_regions_in_bytes() - + // Discount space used by current Eden to establish a + // situation during Remark similar to at the end of full + // GC where eden is empty. During Remark there can be an + // arbitrary number of eden regions which would skew the + // results. + _g1h->eden_regions_count() * HeapRegion::GrainBytes; size_t minimum_desired_capacity = target_heap_capacity(used_after_gc, MinHeapFreeRatio); size_t maximum_desired_capacity = target_heap_capacity(used_after_gc, MaxHeapFreeRatio); From ddecbe52018fdb7556b04b20e8529eb430d3aa75 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 9 May 2024 09:38:17 +0000 Subject: [PATCH 259/298] 8330815: Use pattern matching for instanceof in KeepAliveCache Backport-of: 0ec3c0b1e698f7ad39b4da2edb062721e4670f58 --- .../share/classes/sun/net/www/http/KeepAliveCache.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java index 6c601793c49..153de588938 100644 --- a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.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 @@ -389,9 +389,9 @@ public KeepAliveKey(URL url, Object obj) { */ @Override public boolean equals(Object obj) { - if ((obj instanceof KeepAliveKey) == false) + if (!(obj instanceof KeepAliveKey kae)) return false; - KeepAliveKey kae = (KeepAliveKey)obj; + return host.equals(kae.host) && (port == kae.port) && protocol.equals(kae.protocol) @@ -405,7 +405,7 @@ public boolean equals(Object obj) { @Override public int hashCode() { String str = protocol+host+port; - return this.obj == null? str.hashCode() : + return this.obj == null ? str.hashCode() : str.hashCode() + this.obj.hashCode(); } } From c12dfc3571235bb57b2287e06c0cebb764f47a9a Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 9 May 2024 09:38:35 +0000 Subject: [PATCH 260/298] 8330523: Reduce runtime and improve efficiency of KeepAliveTest Backport-of: 8eac95ec3cd4b215556d788b9ade7a6e2f9deaa3 --- .../www/http/HttpClient/KeepAliveTest.java | 1373 +++-------------- 1 file changed, 218 insertions(+), 1155 deletions(-) diff --git a/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java b/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java index 344ff5f89e9..02e60ebc75f 100644 --- a/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java +++ b/test/jdk/sun/net/www/http/HttpClient/KeepAliveTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -24,177 +24,29 @@ /* * @test * @library /test/lib - * @bug 8291226 8291638 - * @modules java.base/sun.net:+open - * java.base/sun.net.www.http:+open - * java.base/sun.net.www:+open + * @bug 8291226 8291638 8330523 + * @modules java.base/sun.net.www.http:+open * java.base/sun.net.www.protocol.http:+open - * @run main/othervm KeepAliveTest 0 - * @run main/othervm KeepAliveTest 1 - * @run main/othervm KeepAliveTest 2 - * @run main/othervm KeepAliveTest 3 - * @run main/othervm KeepAliveTest 4 - * @run main/othervm KeepAliveTest 5 - * @run main/othervm KeepAliveTest 6 - * @run main/othervm KeepAliveTest 7 - * @run main/othervm KeepAliveTest 8 - * @run main/othervm KeepAliveTest 9 - * @run main/othervm KeepAliveTest 10 - * @run main/othervm KeepAliveTest 11 - * @run main/othervm KeepAliveTest 12 - * @run main/othervm KeepAliveTest 13 - * @run main/othervm KeepAliveTest 14 - * @run main/othervm KeepAliveTest 15 - * @run main/othervm KeepAliveTest 16 - * @run main/othervm KeepAliveTest 17 - * @run main/othervm KeepAliveTest 18 - * @run main/othervm KeepAliveTest 19 - * @run main/othervm KeepAliveTest 20 - * @run main/othervm KeepAliveTest 21 - * @run main/othervm KeepAliveTest 22 - * @run main/othervm KeepAliveTest 23 - * @run main/othervm KeepAliveTest 24 - * @run main/othervm KeepAliveTest 25 - * @run main/othervm KeepAliveTest 26 - * @run main/othervm KeepAliveTest 27 - * @run main/othervm KeepAliveTest 28 - * @run main/othervm KeepAliveTest 29 - * @run main/othervm KeepAliveTest 30 - * @run main/othervm KeepAliveTest 31 - * @run main/othervm KeepAliveTest 32 - * @run main/othervm KeepAliveTest 33 - * @run main/othervm KeepAliveTest 34 - * @run main/othervm KeepAliveTest 35 - * @run main/othervm KeepAliveTest 36 - * @run main/othervm KeepAliveTest 37 - * @run main/othervm KeepAliveTest 38 - * @run main/othervm KeepAliveTest 39 - * @run main/othervm KeepAliveTest 40 - * @run main/othervm KeepAliveTest 41 - * @run main/othervm KeepAliveTest 42 - * @run main/othervm KeepAliveTest 43 - * @run main/othervm KeepAliveTest 44 - * @run main/othervm KeepAliveTest 45 - * @run main/othervm KeepAliveTest 46 - * @run main/othervm KeepAliveTest 47 - * @run main/othervm KeepAliveTest 48 - * @run main/othervm KeepAliveTest 49 - * @run main/othervm KeepAliveTest 50 - * @run main/othervm KeepAliveTest 51 - * @run main/othervm KeepAliveTest 52 - * @run main/othervm KeepAliveTest 53 - * @run main/othervm KeepAliveTest 54 - * @run main/othervm KeepAliveTest 55 - * @run main/othervm KeepAliveTest 56 - * @run main/othervm KeepAliveTest 57 - * @run main/othervm KeepAliveTest 58 - * @run main/othervm KeepAliveTest 59 - * @run main/othervm KeepAliveTest 60 - * @run main/othervm KeepAliveTest 61 - * @run main/othervm KeepAliveTest 62 - * @run main/othervm KeepAliveTest 63 - * @run main/othervm KeepAliveTest 64 - * @run main/othervm KeepAliveTest 65 - * @run main/othervm KeepAliveTest 66 - * @run main/othervm KeepAliveTest 67 - * @run main/othervm KeepAliveTest 68 - * @run main/othervm KeepAliveTest 69 - * @run main/othervm KeepAliveTest 70 - * @run main/othervm KeepAliveTest 71 - * @run main/othervm KeepAliveTest 72 - * @run main/othervm KeepAliveTest 73 - * @run main/othervm KeepAliveTest 74 - * @run main/othervm KeepAliveTest 75 - * @run main/othervm KeepAliveTest 76 - * @run main/othervm KeepAliveTest 77 - * @run main/othervm KeepAliveTest 78 - * @run main/othervm KeepAliveTest 79 - * @run main/othervm KeepAliveTest 80 - * @run main/othervm KeepAliveTest 81 - * @run main/othervm KeepAliveTest 82 - * @run main/othervm KeepAliveTest 83 - * @run main/othervm KeepAliveTest 84 - * @run main/othervm KeepAliveTest 85 - * @run main/othervm KeepAliveTest 86 - * @run main/othervm KeepAliveTest 87 - * @run main/othervm KeepAliveTest 88 - * @run main/othervm KeepAliveTest 89 - * @run main/othervm KeepAliveTest 90 - * @run main/othervm KeepAliveTest 91 - * @run main/othervm KeepAliveTest 92 - * @run main/othervm KeepAliveTest 93 - * @run main/othervm KeepAliveTest 94 - * @run main/othervm KeepAliveTest 95 - * @run main/othervm KeepAliveTest 96 - * @run main/othervm KeepAliveTest 97 - * @run main/othervm KeepAliveTest 98 - * @run main/othervm KeepAliveTest 99 - * @run main/othervm KeepAliveTest 100 - * @run main/othervm KeepAliveTest 101 - * @run main/othervm KeepAliveTest 102 - * @run main/othervm KeepAliveTest 103 - * @run main/othervm KeepAliveTest 104 - * @run main/othervm KeepAliveTest 105 - * @run main/othervm KeepAliveTest 106 - * @run main/othervm KeepAliveTest 107 - * @run main/othervm KeepAliveTest 108 - * @run main/othervm KeepAliveTest 109 - * @run main/othervm KeepAliveTest 110 - * @run main/othervm KeepAliveTest 111 - * @run main/othervm KeepAliveTest 112 - * @run main/othervm KeepAliveTest 113 - * @run main/othervm KeepAliveTest 114 - * @run main/othervm KeepAliveTest 115 - * @run main/othervm KeepAliveTest 116 - * @run main/othervm KeepAliveTest 117 - * @run main/othervm KeepAliveTest 118 - * @run main/othervm KeepAliveTest 119 - * @run main/othervm KeepAliveTest 120 - * @run main/othervm KeepAliveTest 121 - * @run main/othervm KeepAliveTest 122 - * @run main/othervm KeepAliveTest 123 - * @run main/othervm KeepAliveTest 124 - * @run main/othervm KeepAliveTest 125 - * @run main/othervm KeepAliveTest 126 - * @run main/othervm KeepAliveTest 127 - * @run main/othervm KeepAliveTest 128 - * @run main/othervm KeepAliveTest 129 - * @run main/othervm KeepAliveTest 130 - * @run main/othervm KeepAliveTest 131 - * @run main/othervm KeepAliveTest 132 - * @run main/othervm KeepAliveTest 133 - * @run main/othervm KeepAliveTest 134 - * @run main/othervm KeepAliveTest 135 - * @run main/othervm KeepAliveTest 136 - * @run main/othervm KeepAliveTest 137 - * @run main/othervm KeepAliveTest 138 - * @run main/othervm KeepAliveTest 139 - * @run main/othervm KeepAliveTest 140 - * @run main/othervm KeepAliveTest 141 - * @run main/othervm KeepAliveTest 142 - * @run main/othervm KeepAliveTest 143 - * @run main/othervm KeepAliveTest 144 - * @run main/othervm KeepAliveTest 145 - * @run main/othervm KeepAliveTest 146 - * @run main/othervm KeepAliveTest 147 - * @run main/othervm KeepAliveTest 148 - * @run main/othervm KeepAliveTest 149 - * @run main/othervm KeepAliveTest 150 - * @run main/othervm KeepAliveTest 151 - * @run main/othervm KeepAliveTest 152 - * @run main/othervm KeepAliveTest 153 - * @run main/othervm KeepAliveTest 154 - * @run main/othervm KeepAliveTest 155 - * @run main/othervm KeepAliveTest 156 - * @run main/othervm KeepAliveTest 157 - * @run main/othervm KeepAliveTest 158 - * @run main/othervm KeepAliveTest 159 + * @run main/othervm KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=100 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.proxy=200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=100 -Dhttp.keepAlive.time.proxy=200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=-100 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.proxy=-200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=-100 -Dhttp.keepAlive.time.proxy=-200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=0 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.proxy=0 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=0 -Dhttp.keepAlive.time.proxy=0 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=0 -Dhttp.keepAlive.time.proxy=-200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=-100 -Dhttp.keepAlive.time.proxy=0 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=100 -Dhttp.keepAlive.time.proxy=0 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=0 -Dhttp.keepAlive.time.proxy=200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=100 -Dhttp.keepAlive.time.proxy=-200 KeepAliveTest + * @run main/othervm -Dhttp.keepAlive.time.server=-100 -Dhttp.keepAlive.time.proxy=200 KeepAliveTest */ - -import java.nio.charset.StandardCharsets; -import java.io.InputStream; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.lang.reflect.Constructor; @@ -206,841 +58,59 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map.Entry; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Phaser; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; + +import jdk.test.lib.net.URIBuilder; + import sun.net.www.http.HttpClient; import sun.net.www.http.KeepAliveCache; import sun.net.www.protocol.http.HttpURLConnection; -import jdk.test.lib.net.URIBuilder; public class KeepAliveTest { - private static final Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); - private static final String NOT_CACHED = "NotCached"; - private static final String CLIENT_SEPARATOR = ";"; - private static final String NEW_LINE = "\r\n"; - private volatile int SERVER_PORT = 0; + /* - * isProxySet is shared variable between server thread and client thread(main) and it should be set and reset to false for each and - * every scenario. - * isProxySet variable should be set by server thread before proceeding to client thread(main). + * This test covers a matrix of 10 server scenarios and 16 client scenarios. */ - private volatile boolean isProxySet = false; + private static final Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); + + private static final String NEW_LINE = "\r\n"; + private static final String CONNECTION_KEEP_ALIVE_ONLY = "Connection: keep-alive"; private static final String PROXY_CONNECTION_KEEP_ALIVE_ONLY = "Proxy-Connection: keep-alive"; private static final String KEEP_ALIVE_TIMEOUT_NEG = "Keep-alive: timeout=-20"; private static final String KEEP_ALIVE_TIMEOUT_ZERO = "Keep-alive: timeout=0"; private static final String KEEP_ALIVE_TIMEOUT = "Keep-alive: timeout=20"; private static final String KEEP_ALIVE_PROXY_TIMEOUT = "Keep-alive: timeout=120"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_NEGATIVE = "http.keepAlive.time.server=-100"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_NEGATIVE = "http.keepAlive.time.proxy=-200"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_ZERO = "http.keepAlive.time.server=0"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_ZERO = "http.keepAlive.time.proxy=0"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_POSITIVE = "http.keepAlive.time.server=100"; - private static final String CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_POSITIVE = "http.keepAlive.time.proxy=200"; - private static final String CONNECTION_KEEP_ALIVE_WITH_TIMEOUT = CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE - + KEEP_ALIVE_TIMEOUT; - /* - * Following Constants represents Client Side Properties and is used as reference in below table as - * CLIENT_INPUT_CONSTANT_NAMES - */ - private static final String SERVER_100_NEGATIVE = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_NEGATIVE; - private static final String PROXY_200_NEGATIVE = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_NEGATIVE; - private static final String SERVER_ZERO = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_ZERO; - private static final String PROXY_ZERO = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_ZERO; - private static final String SERVER_100 = CLIENT_HTTP_KEEP_ALIVE_TIME_SERVER_POSITIVE; - private static final String PROXY_200 = CLIENT_HTTP_KEEP_ALIVE_TIME_PROXY_POSITIVE; - - /* - * CONSTANTS A,B,C,D,E,NI,F,G,H,I represents ServerScenarios and is used as reference in below table - * as SERVER_RESPONSE_CONSTANT_NAME - */ - private static final String A = CONNECTION_KEEP_ALIVE_ONLY; - private static final String B = CONNECTION_KEEP_ALIVE_WITH_TIMEOUT; - private static final String C = PROXY_CONNECTION_KEEP_ALIVE_ONLY; - private static final String D = PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + CONNECTION_KEEP_ALIVE_ONLY; - private static final String E = C + NEW_LINE + KEEP_ALIVE_PROXY_TIMEOUT; - private static final String NI = "NO_INPUT"; - private static final String F = A + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG; - private static final String G = A + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO; - private static final String H = C + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG; - private static final String I = C + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO; - - /* - * There are 160 scenarios run by this program. - * For every scenario there is mapping between serverScenarios[int],clientScenarios[int] and expectedOutput[int] - * - * serverScenarios[0] clientScenarios[0] expectedOutput[0] - * serverScenarios[1] clientScenarios[1] expectedOutput[1] - * serverScenarios[2] clientScenarios[2] expectedOutput[2] - * - * ... - * - * serverScenarios[159] cientScenarios[159] expectedOutput[159] - * - * whereas serverScenarios[int] is retrieved using getServerScenario(int) - * whereas clientScenarios[int] is retrieved using clientScenario[getClientScenarioNumber[int]] - * and - * expectedOutput[int] is retrieved using expectedOuput[int] directly. - * - */ - - /* Here is the complete table of server_response, client system properties input and expected cached timeout at client side */ - /* ScNo | SERVER RESPONSE (SERVER_RESPONSE_CONSTANT_NAME)| CLIENT SYSTEM PROPERTIES INPUT (CLIENT_INPUT_CONSTANT_NAMES) | EXPECTED CACHED TIMEOUT AT CLIENT SIDE - ***************************************************************************************************************************************** - * 0 | Connection: keep-alive (A) | No Input Provided (NI) | Default Timeout set to 5 - *--------------------------------------------------------------------------------------------------------------------------- - * 1 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 (SERVER_100)| Client Timeout set to 100 - *-------------------------------------------------------------------------------------------------------------------------- - * 2 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=200 (PROXY_200) | Default Timeout set to 5 - *--------------------------------------------------------------------------------------------------------------------------- - * 3 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 100 - * | | (SERVER_100 && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 4 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 | Default Timeout set to 5 - * | | (SERVER_100_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 5 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=-200 | Default Timeout set to 5 - * | | (PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 6 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Default Timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 7 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 | Connection Closed Immediately - * | | (SERVER_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 8 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.proxy=0 | Default Timeout set to 5 - * | | (PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 9 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Connection Closed Immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 10 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Connection Closed Immediately - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 11 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Default Timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 12 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 - * | | (SERVER_100 && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 13 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Connection Closed Immediately - * | | (SERVER_ZERO && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 14 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 15 | Connection: keep-alive (A) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Default Timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 16 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | No Input Provided (NI) | Timeout set to 20 - *------------------------------------------------------------------------------------------------------------------------ - * 17 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 | Timeout set to 20 - * | | (SERVER_100) | - *--------------------------------------------------------------------------------------------------------------------------- - * 18 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 - * | | (PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 19 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 - * | | (SERVER_100 && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 20 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 | Timeout set to 20 - * | | (SERVER_100_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 21 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 - * | | (PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 22 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *--------------------------------------------------------------------------------------------------------------------------- - * 23 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 | Timeout set to 20 - * | | (SERVER_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 24 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 - * | | (PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 25 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 - * | | (SERVER_ZERO && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 26 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 27 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 28 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 20 - * | | (SERVER_100 && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 29 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 - * | | (SERVER_ZERO && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 30 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 20 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 31 |Connection: keep-alive\r\nKeep-alive: timeout=20 (B) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 32 |Proxy-Connection: keep-alive (C) | No Input Provided (NI) | Default timeout set to 60 - *--------------------------------------------------------------------------------------------------------------------------- - * 33 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 | Default timeout set to 60 - * | | (SERVER_100) | - *--------------------------------------------------------------------------------------------------------------------------- - * 34 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------- - * 35 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100 && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------- - * 36 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=-100 | Default timeout set to 60 - * | | (SERVER_100_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 37 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 38 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | |(SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *--------------------------------------------------------------------------------------------------------------------------- - * 39 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 | Default timeout set to 60 - * | | (SERVER_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 40 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 41 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 42 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 43 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 44 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100 && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 45 |Proxy-Connection: keep-alive (C) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_ZERO && PROXY_200) | - *--------------------------------------------------------------------------------------------------------------------------- - * 46 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------- - * 47 |Proxy-Connection: keep-alive (C) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------- - * 48 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | No Input Provided (NI) | Default timeout set to 60 - *----------------------------------------------------------------------------------------------------------------------------- - * 49 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 | Default timeout set to 60 - * | | (SERVER_100) | - *--------------------------------------------------------------------------------------------------------------------------- - * 50 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------ - * 51 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100 && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------ - * 52 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 | Default timeout set to 60 - * | | (SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------ - * 53 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------ - * 54 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100&& | - * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE | - *------------------------------------------------------------------------------------------------------------------------------- - * 55 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 | Default timeout set to 60 - * | | (SERVER_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 56 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 57 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 58 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Default timeout set to 60 - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 59 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 60 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100 && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 61 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_ZERO && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------ - * 62 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------ - * 63 |Connection:keep-alive\r\nProxy-connection:keep-alive (D) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------- - * 64 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| No Input Provided (NI) | Timeout set to 120 - *------------------------------------------------------------------------------------------------------------------------------- - * 65 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 | Timeout set to 120 - * | | (SERVER_100) | - *------------------------------------------------------------------------------------------------------------------------------- - * 66 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 - * | | (PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------- - * 67 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 - * | | (SERVER_100 && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------- - * 68 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 | Timeout set to 120 - * | | (SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------- - * 69 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 - * | | (PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------- - * 70 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *------------------------------------------------------------------------------------------------------------------------------- - * 71 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 | Timeout set to 120 - * | | (SERVER_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------- - * 72 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 - * | | (PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------- - * 73 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 - * | | (SERVER_ZERO && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------- - * 74 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------- - * 75 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------- - * 76 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 120 - * | | (SERVER_100 && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------- - * 77 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 - * | | (SERVER_ZERO && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------- - * 78 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | Timeout set to 120 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------- - * 79 |Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 (E)| -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 120 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *----------------------------------------------------------------------------------------------------------------------------- - * 80 |No Input (NI) | No Input Provided (NI) | default timeout set to 5 - *----------------------------------------------------------------------------------------------------------------------------- - * 81 |No Input (NI) | -Dhttp.keepAlive.time.server=100 | Timeout set to 100 - * | | (SERVER_100) | - *----------------------------------------------------------------------------------------------------------------------------- - * 82 |No Input (NI) | -Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 - * | | (PROXY_200) | - *----------------------------------------------------------------------------------------------------------------------------- - * 83 |No Input (NI) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | client timeot set to 100 - * | | (SERVER_100 && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------ - * 84 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------ - * 85 |No Input (NI) | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 - * | | (PROXY_200_NEGATIVE) | - *---------------------------------------------------------------------------------------------------------------------------- - * 86 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *------------------------------------------------------------------------------------------------------------------------------ - * 87 |No Input (NI) | -Dhttp.keepAlive.time.server=0 | close connection immediately - * | | (SERVER_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 88 |No Input (NI) | -Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 - * | | (PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 89 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 90 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 91 |No Input (NI) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 92 |No Input (NI) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 - * | | (SERVER_100 && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 93 |No Input (NI) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 94 |No Input (NI) |-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 95 |No Input (NI) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 96 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) | No Input Provided (NI) | default timeout set to 5 - *-------------------------------------------------------------------------------------------------------------------------------- - * 97 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 | Timeout set to 100 - * | | (SERVER_100) | - *-------------------------------------------------------------------------------------------------------------------------------- - * 98 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 - * | | (PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 99 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 100 - * | |(SERVER_100 && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 100 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 | default timeout set to 5 - * | |(SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 101 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 - * | |(PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 102 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *------------------------------------------------------------------------------------------------------------------------------------- - * 103 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 | close connection immediately - * | | (SERVER_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 104 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 - * | | (PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 105 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 106 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO_NEGATIVE)| - *------------------------------------------------------------------------------------------------------------------------------------- - * 107 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=0 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 108 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=0 | Timeout set to 100 - * | | (SERVER_100 && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 109 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=0 && | - * | |-Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 110 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | Timeout set to 100 - * | |(SERVER_100 && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 111 |Connection: keep-alive\r\nKeep-alive: timeout=-20 (F) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | default timeout set to 5 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 112 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | No Input Provided (NI) | close connection immediately - *------------------------------------------------------------------------------------------------------------------------------------- - * 113 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 | close connection immediately - * | | (SERVER_100) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 114 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 115 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_100 && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 116 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 | close connection immediately - * | | (SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------ - * 117 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 118 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) |-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 119 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 | close connection immediately - * | | (SERVER_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 120 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------ - * 121 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 122 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 123 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 124 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100 && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 125 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 126 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 127 |Connection: keep-alive\r\nKeep-alive: timeout=0 (G) | -Dhttp.keepAlive.time.server=-100 &&| - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 128 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| No Input Provided (NI) | default timeout set to 60 - --------------------------------------------------------------------------------------------------------------------------------------- - * 129 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 | default timeout set to 60 - * | | (SERVER_100) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 130 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 131 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100 && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 132 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=-100 | default timeout set to 60 - * | | (SERVER_100_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 133 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 - * | | (PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 134 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE)| - *--------------------------------------------------------------------------------------------------------------------------------- - * 135 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 | default timeout set to 60 - * | | (SERVER_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 136 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (PROXY_ZERO) | - *---------------------------------------------------------------------------------------------------------------------------------- - * 137 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 138 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *--------------------------------------------------------------------------------------------------------------------------------------- - * 139 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 140 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100 && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 141 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)| -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | Timeout set to 20 - * | | (SERVER_ZERO && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 142 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=100 && | - * | |-Dhttp.keepAlive.time.proxy=-200 | default timeout set to 60 - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 143 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=-20 (H)|-Dhttp.keepAlive.time.server=-100 && | - * | |-Dhttp.keepAlive.time.proxy=200 | Timeout set to 200 - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 144 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | No Input Provided (NI) | close connection immediately - *-------------------------------------------------------------------------------------------------------------------------------------- - * 145 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 | close connection immediately - * | | (SERVER_100) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 146 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 147 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_100 && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 148 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 | close connection immediately - * | | (SERVER_100_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 149 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 150 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_200_NEGATIVE) | - *------------------------------------------------------------------------------------------------------------------------------------ - * 151 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 | close connection immediately - * | | (SERVER_ZERO) | - *----------------------------------------------------------------------------------------------------------------------------------- - * 152 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (PROXY_ZERO) | - *--------------------------------------------------------------------------------------------------------------------------------- - * 153 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_ZERO && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------ - * 154 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 155 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_ZERO) | - *------------------------------------------------------------------------------------------------------------------------------------- - * 156 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=0 | close connection immediately - * | | (SERVER_100 && PROXY_ZERO) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 157 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=0 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_ZERO && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 158 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=100 && | - * | | -Dhttp.keepAlive.time.proxy=-200 | close connection immediately - * | | (SERVER_100 && PROXY_200_NEGATIVE) | - *-------------------------------------------------------------------------------------------------------------------------------------- - * 159 |Proxy-Connection:keep-alive\r\nKeep-alive:timeout=0 (I) | -Dhttp.keepAlive.time.server=-100 && | - * | | -Dhttp.keepAlive.time.proxy=200 | close connection immediately - * | | (SERVER_100_NEGATIVE && PROXY_200) | - *-------------------------------------------------------------------------------------------------------------------------------------- - */ - - /* private static final String[] serverScenarios = { - A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, - B, B, B, B, B, B, B, B, B, B,B, B, B, B, B, B, - C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, - D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, - E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, - NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, NI, - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, - G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, - I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I - }; */ - /* - * following are client scenarios which are repeated. - */ - private static final String[] a = { - NI, SERVER_100, PROXY_200, SERVER_100 + CLIENT_SEPARATOR + PROXY_200, SERVER_100_NEGATIVE, - PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, - SERVER_ZERO, PROXY_ZERO, SERVER_ZERO + CLIENT_SEPARATOR + PROXY_ZERO, - SERVER_ZERO + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_ZERO, - SERVER_100 + CLIENT_SEPARATOR + PROXY_ZERO, SERVER_ZERO + CLIENT_SEPARATOR + PROXY_200, - SERVER_100 + CLIENT_SEPARATOR + PROXY_200_NEGATIVE, SERVER_100_NEGATIVE + CLIENT_SEPARATOR + PROXY_200 - }; + private static final String CONNECTION_KEEP_ALIVE_WITH_TIMEOUT = CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_TIMEOUT; - /* private String[] clientScenarios = { - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], - }; */ - - private static final String[] clientScenarios = { - a[0] , a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15] + private static final String[] serverHeaders = { + null, + CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE, + CONNECTION_KEEP_ALIVE_WITH_TIMEOUT + NEW_LINE, + PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE, + PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE, + PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_PROXY_TIMEOUT + NEW_LINE, + CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG + NEW_LINE, + CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO + NEW_LINE, + PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_TIMEOUT_NEG + NEW_LINE, + PROXY_CONNECTION_KEEP_ALIVE_ONLY + NEW_LINE + KEEP_ALIVE_TIMEOUT_ZERO + NEW_LINE }; - private static final int[] expectedValues = { - 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, - 20, 20 , 20, 20, 20, 20, 20, 20, 20, 20 , 20, 20, 20, 20, 20, 20, - 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, - 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, - 120, 120, 120, 120,120,120,120,120,120, 120, 120, 120, 120, 120, 120, 120, - 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, - 5, 100, 5, 100, 5, 5, 5, 0, 5, 0, 0, 5, 100, 0, 100, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 60, 60, 200, 200, 60, 60, 60, 60, 0, 0, 60, 0, 0, 200, 60, 200, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - private final CountDownLatch countDownLatch = new CountDownLatch(1); - - private final CountDownLatch serverCountDownLatch = new CountDownLatch(1); - - /* - * setting of client properties -Dhttp.keepAlive.time.server and -Dhttp.keepAlive.time.proxy is handled through this method. - * There are 16 client scenarios in total starting with scenarioNumber 0(zero) and ending with 15. - * Server Scenarios are grouped into batch of 16 scenarios. - * There are 10 batches in total and each batch contains 16 scenarios so 10 * 16 = 160 scenarios in total. - * 16 Client Scenarios are used repeatedly for every server scenario batch. - * for serverscenario[0],serverscenario[16],serverscenario[32] ... serverscenario[144] is mapped to clientscenario[0] - * for serverscenario[1],serverscenario[17],serverscenario[33] ... serverscenario[145] is mapped to clientscenario[1] - * for serverscenario[2],serverscenario[18],serverscenario[34] ... serverscenario[146] is mapped to clientscenario[2] - * ... - * for serverscenario[15],serverscenario[31],serverscenario[47] ... serverscenario[159] is mapped to clientscenario[15] - */ - private int getClientScenarioNumber(int scenarioNumber) { - return scenarioNumber % 16 ; - } + private static KeepAliveCache keepAliveCache; - /* - * Returns SERVER_RESPONSE as String based on integer inputParameter scenarioNumber. - * Server Scenarios are grouped into batch of 16 scenarios starting with scenarioNumber 0 (zero) - * so there are 10 batches in total and each batch contains 16 scenarios so 10 * 16 = 160 scenarios in total. - * For each batch of 16 scenarios, there will be common SERVER_RESPONSE for all 16 scenarios in batch. - * for scenario numbers from 0 to 15 server response is: Connection:keep-alive - * for scenario numbers from 16 to 31 server response is: SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=20 - * for scenario numbers from 32 to 47 server response is: SERVER_RESPONSE=Proxy-Connection: keep-alive - * for scenario numbers from 48 to 63 server response is: SERVER_RESPONSE=Connection:keep-alive\r\nProxy-connection:keep-alive - * for scenario numbers from 64 to 79 server response is: SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 - * for scenario numbers from 80 to 95 server response is: SERVER_RESPONSE=No Input - * for scenario numbers from 96 to 111 server response is: SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=-20 - * for scenario numbers from 112 to 127 server resonse is: Connection: keep-alive\r\nKeep-alive: timeout=0 - * for scenario numbers from 128 to 143 server response is: Proxy-connection:keep-alive\r\nKeep-alive:timeout=-20 - * for scenario numbers from 144 to 159 server response is: Proxy-connection:keep-alive\r\nKeep-alive:timeout=0 - */ - private String getServerScenario(int scenarioNumber) { - /* - * ServerResponse for scenarios from 0 to 15 - * SERVER_RESPONSE:Connection:keep-alive - */ - if(scenarioNumber >= 0 && scenarioNumber <= 15) { - return A; - } - /* - * ServerResponse for scenarios from 16 to 31 - * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=20 - */ - else if (scenarioNumber >= 16 && scenarioNumber <= 31){ - return B; - } - /* - * ServerResponse for scenarios from 32 to 47 - * SERVER_RESPONSE=Proxy-Connection: keep-alive - */ - else if (scenarioNumber >= 32 && scenarioNumber <= 47){ - return C; - } - /* - * ServerResponse for scenarios from 48 to 63 - * SERVER_RESPONSE=Connection:keep-alive\r\nProxy-connection:keep-alive - */ - else if (scenarioNumber >= 48 && scenarioNumber <= 63){ - return D; - /* - * ServerResponse for scenarios from 64 to 79 - * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=120 - */ - } else if (scenarioNumber >= 64 && scenarioNumber <= 79){ - return E; - } - /* - * ServerResponse for scenarios from 80 to 95 - * SERVER_RESPONSE=No Input - */ - else if (scenarioNumber >= 80 && scenarioNumber <= 95){ - return NI; - } - /* - * ServerResponse for scenarios from 96 to 111 - * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=-20 - */ - else if (scenarioNumber >= 96 && scenarioNumber <= 111){ - return F; - } - /* - * ServerResponse for scenarios from 112 to 127 - * SERVER_RESPONSE=Connection: keep-alive\r\nKeep-alive: timeout=0 - */ - else if (scenarioNumber >= 112 && scenarioNumber <= 127){ - return G; - } - /* - * ServerResponse for scenarios from 128 to 143 - * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=-20 - */ - else if (scenarioNumber >= 128 && scenarioNumber <= 143){ - return H; - } - /* - * ServerResponse for scenarios from 144 to 159 - * SERVER_RESPONSE=Proxy-connection:keep-alive\r\nKeep-alive:timeout=0 - */ - else if (scenarioNumber >= 144 && scenarioNumber <= 159){ - return I; - } - /*Invalid Case*/ - return null; - } + private static Constructor keepAliveKeyClassconstructor; - private void startScenario(int scenarioNumber) throws Exception { - System.out.println("serverScenarios[" + scenarioNumber + "]=" + getServerScenario(scenarioNumber)); - System.out.println("clientScenarios[" + scenarioNumber + "]=" + clientScenarios[getClientScenarioNumber(scenarioNumber)]); - if(expectedValues[scenarioNumber] == 0) { - System.out.println("ExpectedOutput=" + NOT_CACHED); - } else { - System.out.println("ExpectedOutput=" + expectedValues[scenarioNumber]); - } - System.out.println(); - startServer(scenarioNumber); - runClient(scenarioNumber); - } + // variables set by server thread + private volatile int serverPort; + private volatile boolean isProxySet; - private void startServer(int scenarioNumber) { - Thread server = new Thread(new Runnable() { - @Override - public void run() { - try { - executeServer(scenarioNumber); - } catch (IOException e) { - e.printStackTrace(); - } - } - }, "SERVER"); - server.start(); - } + private static final Phaser serverGate = new Phaser(2); private void readAll(Socket s) throws IOException { byte[] buf = new byte[128]; @@ -1058,215 +128,208 @@ private void readAll(Socket s) throws IOException { } } - private void executeServer(int scenarioNumber) throws IOException { - String serverScenarioContent = null; - if (!getServerScenario(scenarioNumber).equalsIgnoreCase(NI)) { - serverScenarioContent = getServerScenario(scenarioNumber) + NEW_LINE; - /* - * isProxySet should be set before Server is moved to Listen State. - */ - if (serverScenarioContent.contains("Proxy")) { - isProxySet = true; - } else { - isProxySet = false; - } + private void executeServer(int scenarioNumber) { + String scenarioHeaders = serverHeaders[scenarioNumber]; + if (scenarioHeaders != null) { + // isProxySet should be set before Server is moved to Listen State. + isProxySet = scenarioHeaders.contains("Proxy"); } - ServerSocket serverSocket = null; - Socket socket = null; - OutputStreamWriter out = null; - InetAddress loopback = InetAddress.getLoopbackAddress(); - try { - serverSocket = new ServerSocket(); - serverSocket.bind(new InetSocketAddress(loopback, 0)); - SERVER_PORT = serverSocket.getLocalPort(); - //serverReady = true; - this.serverCountDownLatch.countDown(); - System.out - .println("SERVER_PORT= " + SERVER_PORT +" isProxySet=" + isProxySet); - /* - * Server will be waiting for clients to connect. - */ - socket = serverSocket.accept(); - readAll(socket); - out = new OutputStreamWriter(socket.getOutputStream()); - String BODY = "SERVER REPLY: Hello world"; - String CLEN = "Content-Length: " + BODY.length() + NEW_LINE; - /* send the header */ - out.write("HTTP/1.1 200 OK\r\n"); - out.write("Content-Type: text/plain; charset=iso-8859-1\r\n"); - /* - * append each scenario content from array. - */ - if(serverScenarioContent != null) { - out.write(serverScenarioContent); - } - out.write(CLEN); - out.write(NEW_LINE); - out.write(BODY); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (out != null) { - out.flush(); - out.close(); - } - if (socket != null) { - socket.close(); - } - if (serverSocket != null) { - serverSocket.close(); + try (ServerSocket serverSocket = new ServerSocket()) { + serverSocket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + serverPort = serverSocket.getLocalPort(); + serverGate.arrive(); + + // Server will be waiting for clients to connect. + try (Socket socket = serverSocket.accept()) { + readAll(socket); + try (OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream())) { + String BODY = "SERVER REPLY: Hello world"; + String CLEN = "Content-Length: " + BODY.length() + NEW_LINE; + + // send common headers + out.write("HTTP/1.1 200 OK\r\n"); + out.write("Content-Type: text/plain; charset=iso-8859-1\r\n"); + + // set scenario headers + if (scenarioHeaders != null) { + out.write(scenarioHeaders); + } + + // send content + out.write(CLEN); + out.write(NEW_LINE); + out.write(BODY); + } } + } catch (IOException ioe) { + throw new RuntimeException("IOException in server thread", ioe); } } - private void runClient(int scenarioNumber) throws Exception { - try { - connectToServerURL(scenarioNumber); - } finally { - System.out.println("client count down latch:" + scenarioNumber); - this.countDownLatch.countDown(); - System.out.println(); - System.out.println(); - } - } + private void fetchInfo(int expectedValue, HttpURLConnection httpUrlConnection) throws Exception { + Object expectedKeepAliveKey = keepAliveKeyClassconstructor.newInstance(httpUrlConnection.getURL(), null); + Object clientVectorObjectInMap = keepAliveCache.get(expectedKeepAliveKey); + System.out.println("ClientVector for KeepAliveKey:" + clientVectorObjectInMap); + HttpClient httpClientCached = keepAliveCache.get(httpUrlConnection.getURL(), null); + System.out.println("HttpClient in Cache:" + httpClientCached); - private void connectToServerURL(int scenarioNumber) throws Exception { - // System.setProperty("java.net.useSystemProxies", "false"); - // System.setProperty("http.nonProxyHosts", ""); - // System.setProperty("http.proxyHost", "localhost"); - // System.setProperty("http.proxyPort", String.valueOf(SERVER_PORT)); - System.out.println("Following are Existing System Properties if set any"); - System.out.println("http.keepAlive.time.server:" + System.getProperty("http.keepAlive.time.server")); - System.out.println("http.keepAlive.time.proxy:" + System.getProperty("http.keepAlive.time.proxy")); - System.setProperty("java.net.useSystemProxies", "false"); - System.out.println("http.proxyPort:"+System.getProperty("http.proxyPort")); - System.out.println("http.proxyHost:"+System.getProperty("http.proxyHost")); - System.clearProperty("http.keepAlive.time.server"); - System.clearProperty("http.keepAlive.time.proxy"); - // fetch clientScenearios for each scenarioNumber from array and set it to - // System property. - if (!clientScenarios[getClientScenarioNumber(scenarioNumber)].equalsIgnoreCase(NI)) { - System.out.println("Client Input Parsing"); - for (String clientScenarioString : clientScenarios[getClientScenarioNumber(scenarioNumber)].split(CLIENT_SEPARATOR)) { - System.out.println(clientScenarioString); - String key = clientScenarioString.split("=")[0]; - String value = clientScenarioString.split("=")[1]; - System.setProperty(key, value); + if (httpClientCached != null) { + System.out.println("KeepingAlive:" + httpClientCached.isKeepingAlive()); + System.out.println("UsingProxy:" + httpClientCached.getUsingProxy()); + System.out.println("ProxiedHost:" + httpClientCached.getProxyHostUsed()); + System.out.println("ProxiedPort:" + httpClientCached.getProxyPortUsed()); + Class clientVectorClass = Class.forName("sun.net.www.http.KeepAliveCache$ClientVector"); + Field napField = clientVectorClass.getDeclaredField("nap"); + napField.setAccessible(true); + int napValue = (int) napField.get(clientVectorObjectInMap); + int actualValue = napValue / 1000; + if (expectedValue == actualValue) { + System.out.printf("Cache time:%d\n", actualValue); + } else { + throw new RuntimeException("Sleep time of " + actualValue + " not expected (" + expectedValue + ")"); + } + } else { + if (expectedValue == 0) { + System.out.println("Connection not cached."); + } else { + throw new RuntimeException("Connection was not cached although expected with sleep time of:" + expectedValue); } } + } + + private void connectToServerURL(int expectedValue) throws Exception { // wait until ServerSocket moves to listening state. - this.serverCountDownLatch.await(); - System.out.println("client started"); - URL url = URIBuilder.newBuilder().scheme("http").loopback().port(SERVER_PORT).toURL(); - System.out.println("connecting from client to SERVER URL:" + url); + serverGate.arriveAndAwaitAdvance(); + URL url = URIBuilder.newBuilder().scheme("http").loopback().port(serverPort).toURL(); + System.out.println("connecting to server URL: " + url + ", isProxySet: " + isProxySet); HttpURLConnection httpUrlConnection = null; - /* - * isProxySet is set to true when Expected Server Response contains Proxy-Connection header. - */ + + // isProxySet is set to true when Expected Server Response contains Proxy-Connection header. if (isProxySet) { - httpUrlConnection = (sun.net.www.protocol.http.HttpURLConnection) url - .openConnection(new Proxy(Type.HTTP, new InetSocketAddress("localhost", SERVER_PORT))); + httpUrlConnection = (HttpURLConnection) url + .openConnection(new Proxy(Type.HTTP, new InetSocketAddress("localhost", serverPort))); } else { - httpUrlConnection = (sun.net.www.protocol.http.HttpURLConnection) url.openConnection(); + httpUrlConnection = (HttpURLConnection) url.openConnection(); } - InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream()); - BufferedReader bufferedReader = null; - try { - bufferedReader = new BufferedReader(inputStreamReader); + + try (InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream()); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { while (true) { - String eachLine = bufferedReader.readLine(); - if (eachLine == null) { + String line = bufferedReader.readLine(); + if (line == null) { break; } - System.out.println(eachLine); - } - } finally { - if (bufferedReader != null) { - bufferedReader.close(); + System.out.println(line); } } - // System.out.println("ResponseCode:" + httpUrlConnection.getResponseCode()); - // System.out.println("ResponseMessage:" + httpUrlConnection.getResponseMessage()); - // System.out.println("Content:" + httpUrlConnection.getContent()); - // Thread.sleep(2000); for (Entry> header : httpUrlConnection.getHeaderFields().entrySet()) { System.out.println(header.getKey() + "=" + header.getValue()); } - fetchInfo(scenarioNumber, httpUrlConnection); + fetchInfo(expectedValue, httpUrlConnection); } - private void fetchInfo(int scenarioNumber, sun.net.www.protocol.http.HttpURLConnection httpUrlConnection) - throws Exception { - Field field = Class.forName("sun.net.www.protocol.http.HttpURLConnection").getDeclaredField("http"); - field.setAccessible(true); - HttpClient httpClient = (HttpClient) field.get(httpUrlConnection); - // System.out.println("httpclient=" + httpClient); - Field keepAliveField = Class.forName("sun.net.www.http.HttpClient").getDeclaredField("kac"); - keepAliveField.setAccessible(true); - KeepAliveCache keepAliveCache = (KeepAliveCache) keepAliveField.get(httpClient); - System.out.println("keepAliveCache" + keepAliveCache); - System.out.println("SERVER URL:" + httpUrlConnection.getURL()); - /* - * create KeepAliveKey(URL,Object) object and compare created KeepAliveKey and - * existing using equals() method: KeepAliveKey.equals() - */ - Class keepAliveKeyClass = Class.forName("sun.net.www.http.KeepAliveKey"); - // System.out.println("keepAliveKeyClass=" + keepAliveKeyClass); - Constructor keepAliveKeyClassconstructor = keepAliveKeyClass.getDeclaredConstructors()[0]; - keepAliveKeyClassconstructor.setAccessible(true); - Object expectedKeepAliveKey = keepAliveKeyClassconstructor.newInstance(httpUrlConnection.getURL(), null); - System.out.println("ExpectedKeepAliveKey=" + expectedKeepAliveKey); - Object clientVectorObjectInMap = keepAliveCache.get(expectedKeepAliveKey); - System.out.println("ClientVector=" + clientVectorObjectInMap); - HttpClient httpClientCached = keepAliveCache.get(httpUrlConnection.getURL(), null); - System.out.println("HttpClient in Cache:" + httpClientCached); - if(httpClientCached != null) { - System.out.println("KeepingAlive:" + httpClientCached.isKeepingAlive()); - System.out.println("UsingProxy:" + httpClientCached.getUsingProxy()); - System.out.println("ProxiedHost:" + httpClientCached.getProxyHostUsed()); - System.out.println("ProxiedPort:" + httpClientCached.getProxyPortUsed()); - System.out.println("ProxyPortUsingSystemProperty:" + System.getProperty("http.proxyPort")); - System.out.println("ProxyHostUsingSystemProperty:" + System.getProperty("http.proxyHost")); - System.out.println("http.keepAlive.time.server=" + System.getProperty("http.keepAlive.time.server")); - System.out.println("http.keepAlive.time.proxy=" + System.getProperty("http.keepAlive.time.proxy")); - Class clientVectorClass = Class.forName("sun.net.www.http.KeepAliveCache$ClientVector"); - // System.out.println("clientVectorClass=" + clientVectorClass); - Field napField = clientVectorClass.getDeclaredField("nap"); - napField.setAccessible(true); - int napValue = (int) napField.get(clientVectorObjectInMap); - int actualValue = napValue / 1000; - // System.out.println("nap=" + napValue / 1000); - System.out.printf("ExpectedOutput:%d ActualOutput:%d ", expectedValues[scenarioNumber], actualValue); - System.out.println(); - if (expectedValues[scenarioNumber] != actualValue) { - throw new RuntimeException( - "ExpectedOutput:" + expectedValues[scenarioNumber] + " ActualOutput: " + actualValue); + private int getExpectedCachingValue(int serverScenario) { + if (serverScenario == 2) { + // Connection: keep-alive && Keep-alive: timeout=20 + // + // server side keep-alive timeout is what counts here + return 20; + } else if (serverScenario == 3 || serverScenario == 4 || serverScenario == 8) { + // Proxy-Connection: keep-alive + // Connection:keep-alive && Proxy-connection:keep-alive + // Proxy-Connection:keep-alive && Keep-alive:timeout=-20 + // + // Proxy-connection:keep-alive is set, timeout could be invalid -> value of http.keepAlive.time.proxy or default of 60 + int httpKeepAliveTimeProxy; + try { + httpKeepAliveTimeProxy = Integer.valueOf(System.getProperty("http.keepAlive.time.proxy")); + } catch (NumberFormatException e) { + httpKeepAliveTimeProxy = -1; } + return httpKeepAliveTimeProxy < 0 ? 60 : httpKeepAliveTimeProxy; + } else if (serverScenario == 5) { + // Proxy-connection:keep-alive && Keep-alive:timeout=120 + // + // server side keep-alive timeout is what counts here + return 120; + } else if (serverScenario == 7 || serverScenario == 9) { + // Connection: keep-alive && Keep-alive: timeout=0 + // Proxy-Connection:keep-alive && Keep-alive:timeout=0 + // + // no caching + return 0; } else { - //executed when value is not cached. - String expected = expectedValues[scenarioNumber] == 0 ? NOT_CACHED - : String.valueOf(expectedValues[scenarioNumber]); - System.out.println("ExpectedOutput:" + expected + " ActualOutput:" + NOT_CACHED); - if (!expected.equalsIgnoreCase(NOT_CACHED)) { - throw new RuntimeException("ExpectedOutput:" + expected + " ActualOutput:" + NOT_CACHED); + // No server parameters + // Connection: keep-alive + // Connection: keep-alive && Keep-alive: timeout=-20 + // + // Nothing or Connection:keep-alive is set, timeout could be invalid -> value of http.keepAlive.time.server or default of 5 + int httpKeepAliveTimeServer; + try { + httpKeepAliveTimeServer = Integer.valueOf(System.getProperty("http.keepAlive.time.server")); + } catch (NumberFormatException e) { + httpKeepAliveTimeServer = -1; } - } + return httpKeepAliveTimeServer < 0 ? 5 : httpKeepAliveTimeServer; + } } - public static void main(String[] args) throws Exception { - if (args.length != 1) { - throw new IllegalArgumentException("Usage:java KeepAliveTest.java "); + private void runScenario(int scenarioNumber) throws Exception { + int expectedValue = getExpectedCachingValue(scenarioNumber); + System.out.println("Expecting Cache Time of " + expectedValue + " for server headers:"); + if (serverHeaders[scenarioNumber] == null) { + System.out.println(); + } else { + System.out.print(serverHeaders[scenarioNumber]); } + Thread server = Thread.ofPlatform().start(() -> executeServer(scenarioNumber)); + connectToServerURL(expectedValue); + server.join(); + System.out.println(); + } + + private static void initialize() throws Exception { + System.clearProperty("http.proxyPort"); + System.clearProperty("http.proxyHost"); + System.setProperty("java.net.useSystemProxies", "false"); + + Field keepAliveField = sun.net.www.http.HttpClient.class.getDeclaredField("kac"); + keepAliveField.setAccessible(true); + keepAliveCache = (KeepAliveCache) keepAliveField.get(null); + System.out.println("KeepAliveCache: " + keepAliveCache); + keepAliveKeyClassconstructor = Class.forName("sun.net.www.http.KeepAliveKey").getDeclaredConstructors()[0]; + keepAliveKeyClassconstructor.setAccessible(true); + logger.setLevel(Level.FINEST); ConsoleHandler h = new ConsoleHandler(); h.setLevel(Level.FINEST); logger.addHandler(h); - KeepAliveTest keepAliveTest = new KeepAliveTest(); - if (args.length != 0) { - keepAliveTest.startScenario(Integer.valueOf(args[0])); + + System.out.println("Client properties: http.keepAlive.time.server=" + System.getProperty("http.keepAlive.time.server") + + ", http.keepAlive.time.proxy=" + System.getProperty("http.keepAlive.time.proxy")); + } + + public static void main(String[] args) throws Exception { + if (args.length > 1) { + throw new IllegalArgumentException("Usage:java KeepAliveTest.java "); + } else if (args.length == 1) { + // an individual test scenario + try { + int scenarioNumber = Integer.valueOf(args[0]); + if (scenarioNumber < 0 || scenarioNumber > 9) { + throw new IllegalArgumentException("Scenario " + scenarioNumber + " does not exist"); + } + initialize(); + new KeepAliveTest().runScenario(scenarioNumber); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Scenario must be a number, got " + args[0]); + } + } else { + // all server scenarios + initialize(); + for (int i = 0; i < 10; i++) { + new KeepAliveTest().runScenario(i); + } } - // make main thread wait until server and client is completed. - keepAliveTest.countDownLatch.await(); } } From e3a9226e0d481ea1ad9747ec9d40f40bbcb650f3 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 10 May 2024 06:41:33 +0000 Subject: [PATCH 261/298] 8330524: Linux ppc64le compile warning with clang in os_linux_ppc.cpp Backport-of: 252c62a66dd955a5d22f307544f38cc0dd4f2550 --- src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index 2e603ac0690..30d7833ab96 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 2012, 2024 SAP SE. 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 @@ -255,7 +255,7 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, stub = SharedRuntime::get_handle_wrong_method_stub(); } - else if ((sig == USE_POLL_BIT_ONLY ? SIGTRAP : SIGSEGV) && + else if ((sig == (USE_POLL_BIT_ONLY ? SIGTRAP : SIGSEGV)) && // A linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults // in 64bit mode (cf. http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.6), // especially when we try to read from the safepoint polling page. So the check From fa874b3d901cce493426a7a7df52cace9de3857c Mon Sep 17 00:00:00 2001 From: Chad Rakoczy Date: Mon, 13 May 2024 09:00:54 +0000 Subject: [PATCH 262/298] 8325621: Improve jspawnhelper version checks Backport-of: a232e8fb4e6e9e2e9a5285bf01c93b8d1d995f04 --- make/modules/java.base/Launcher.gmk | 3 +- make/modules/java.base/lib/CoreLibraries.gmk | 1 + .../unix/native/jspawnhelper/jspawnhelper.c | 28 +++++++++++++++---- .../unix/native/libjava/ProcessImpl_md.c | 14 +++++++--- .../ProcessBuilder/JspawnhelperWarnings.java | 21 +++++++++++++- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/make/modules/java.base/Launcher.gmk b/make/modules/java.base/Launcher.gmk index 11af61b082e..64db79060c4 100644 --- a/make/modules/java.base/Launcher.gmk +++ b/make/modules/java.base/Launcher.gmk @@ -78,7 +78,8 @@ ifeq ($(call isTargetOs, macosx aix linux), true) NAME := jspawnhelper, \ SRC := $(TOPDIR)/src/$(MODULE)/unix/native/jspawnhelper, \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKEXE) -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \ + CFLAGS := $(CFLAGS_JDKEXE) $(VERSION_CFLAGS) \ + -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \ EXTRA_OBJECT_FILES := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc$(OBJ_SUFFIX), \ LDFLAGS := $(LDFLAGS_JDKEXE), \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \ diff --git a/make/modules/java.base/lib/CoreLibraries.gmk b/make/modules/java.base/lib/CoreLibraries.gmk index 8b1a0a90fd4..6aa9fd6586c 100644 --- a/make/modules/java.base/lib/CoreLibraries.gmk +++ b/make/modules/java.base/lib/CoreLibraries.gmk @@ -59,6 +59,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJAVA, \ CFLAGS := $(CFLAGS_JDKLIB) \ $(LIBJAVA_CFLAGS), \ jdk_util.c_CFLAGS := $(VERSION_CFLAGS), \ + ProcessImpl_md.c_CFLAGS := $(VERSION_CFLAGS), \ WARNINGS_AS_ERRORS_xlc := false, \ DISABLED_WARNINGS_gcc_ProcessImpl_md.c := unused-result, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ diff --git a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c index 974329a2857..1b4236b2150 100644 --- a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c +++ b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,10 @@ extern int errno; #define ERR_PIPE 2 #define ERR_ARGS 3 +#ifndef VERSION_STRING +#error VERSION_STRING must be defined +#endif + void error (int fd, int err) { if (write (fd, &err, sizeof(err)) != sizeof(err)) { /* Not sure what to do here. I have no one to speak to. */ @@ -59,6 +64,7 @@ void error (int fd, int err) { } void shutItDown() { + fprintf(stdout, "jspawnhelper version %s\n", VERSION_STRING); fprintf(stdout, "This command is not for general use and should "); fprintf(stdout, "only be run as the result of a call to\n"); fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java "); @@ -141,19 +147,29 @@ int main(int argc, char *argv[]) { int r, fdinr, fdinw, fdout; sigset_t unblock_signals; - if (argc != 2) { - shutItDown(); - } - #ifdef DEBUG jtregSimulateCrash(0, 4); #endif - r = sscanf (argv[1], "%d:%d:%d", &fdinr, &fdinw, &fdout); + + if (argc != 3) { + fprintf(stdout, "Incorrect number of arguments: %d\n", argc); + shutItDown(); + } + + if (strcmp(argv[1], VERSION_STRING) != 0) { + fprintf(stdout, "Incorrect Java version: %s\n", argv[1]); + shutItDown(); + } + + r = sscanf (argv[2], "%d:%d:%d", &fdinr, &fdinw, &fdout); if (r == 3 && fcntl(fdinr, F_GETFD) != -1 && fcntl(fdinw, F_GETFD) != -1) { fstat(fdinr, &buf); - if (!S_ISFIFO(buf.st_mode)) + if (!S_ISFIFO(buf.st_mode)) { + fprintf(stdout, "Incorrect input pipe\n"); shutItDown(); + } } else { + fprintf(stdout, "Incorrect FD array data: %s\n", argv[2]); shutItDown(); } diff --git a/src/java.base/unix/native/libjava/ProcessImpl_md.c b/src/java.base/unix/native/libjava/ProcessImpl_md.c index 9ed0ed30959..558882f61e1 100644 --- a/src/java.base/unix/native/libjava/ProcessImpl_md.c +++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c @@ -300,6 +300,10 @@ Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz) #define WTERMSIG(status) ((status)&0x7F) #endif +#ifndef VERSION_STRING +#error VERSION_STRING must be defined +#endif + static const char * getBytes(JNIEnv *env, jbyteArray arr) { @@ -488,7 +492,7 @@ spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) pid_t resultPid; int i, offset, rval, bufsize, magic; char *buf, buf1[(3 * 11) + 3]; // "%d:%d:%d\0" - char *hlpargs[3]; + char *hlpargs[4]; SpawnInfo sp; /* need to tell helper which fd is for receiving the childstuff @@ -497,11 +501,13 @@ spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) snprintf(buf1, sizeof(buf1), "%d:%d:%d", c->childenv[0], c->childenv[1], c->fail[1]); /* NULL-terminated argv array. * argv[0] contains path to jspawnhelper, to follow conventions. - * argv[1] contains the fd string as argument to jspawnhelper + * argv[1] contains the version string as argument to jspawnhelper + * argv[2] contains the fd string as argument to jspawnhelper */ hlpargs[0] = (char*)helperpath; - hlpargs[1] = buf1; - hlpargs[2] = NULL; + hlpargs[1] = VERSION_STRING; + hlpargs[2] = buf1; + hlpargs[3] = NULL; /* Following items are sent down the pipe to the helper * after it is spawned. diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java index 0ff68186502..daffb4b8c84 100644 --- a/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java +++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperWarnings.java @@ -25,7 +25,7 @@ /* * @test - * @bug 8325567 + * @bug 8325567 8325621 * @requires (os.family == "linux") | (os.family == "aix") | (os.family == "mac") * @library /test/lib * @run driver JspawnhelperWarnings @@ -47,11 +47,30 @@ private static void tryWithNArgs(int nArgs) throws Exception { OutputAnalyzer oa = new OutputAnalyzer(p); oa.shouldHaveExitValue(1); oa.shouldContain("This command is not for general use"); + if (nArgs != 2) { + oa.shouldContain("Incorrect number of arguments"); + } else { + oa.shouldContain("Incorrect Java version"); + } + } + + private static void testVersion() throws Exception { + String[] args = new String[3]; + args[0] = Paths.get(System.getProperty("java.home"), "lib", "jspawnhelper").toString(); + args[1] = "wrongVersion"; + args[2] = "1:1:1"; + Process p = ProcessTools.startProcess("jspawnhelper", new ProcessBuilder(args)); + OutputAnalyzer oa = new OutputAnalyzer(p); + oa.shouldHaveExitValue(1); + oa.shouldContain("This command is not for general use"); + oa.shouldContain("Incorrect Java version: wrongVersion"); } public static void main(String[] args) throws Exception { for (int nArgs = 0; nArgs < 10; nArgs++) { tryWithNArgs(nArgs); } + + testVersion(); } } From 153de5aeba5bd8378b5a625d482ece524453e5f7 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 13 May 2024 09:02:17 +0000 Subject: [PATCH 263/298] 8320370: NMT: Change MallocMemorySnapshot to simplify code. Reviewed-by: stuefe Backport-of: a7f60164063bdf95437326e7550fd65ff91b5566 --- src/hotspot/share/services/mallocTracker.cpp | 4 +--- src/hotspot/share/services/mallocTracker.hpp | 6 +++--- src/hotspot/share/services/nmtCommon.hpp | 2 -- src/hotspot/share/services/virtualMemoryTracker.cpp | 9 +-------- src/hotspot/share/services/virtualMemoryTracker.hpp | 5 ++--- 5 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/hotspot/share/services/mallocTracker.cpp b/src/hotspot/share/services/mallocTracker.cpp index 2e8b369d3ac..064002c707c 100644 --- a/src/hotspot/share/services/mallocTracker.cpp +++ b/src/hotspot/share/services/mallocTracker.cpp @@ -44,7 +44,7 @@ #include "utilities/ostream.hpp" #include "utilities/vmError.hpp" -size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)]; +MallocMemorySnapshot MallocMemorySummary::_snapshot; void MemoryCounter::update_peak(size_t size, size_t cnt) { size_t peak_sz = peak_size(); @@ -79,9 +79,7 @@ void MallocMemorySnapshot::make_adjustment() { } void MallocMemorySummary::initialize() { - assert(sizeof(_snapshot) >= sizeof(MallocMemorySnapshot), "Sanity Check"); // Uses placement new operator to initialize static area. - ::new ((void*)_snapshot)MallocMemorySnapshot(); MallocLimitHandler::initialize(MallocLimit); } diff --git a/src/hotspot/share/services/mallocTracker.hpp b/src/hotspot/share/services/mallocTracker.hpp index ed66f643c74..d6ea25fa9d6 100644 --- a/src/hotspot/share/services/mallocTracker.hpp +++ b/src/hotspot/share/services/mallocTracker.hpp @@ -140,7 +140,7 @@ class MallocMemorySummary; // A snapshot of malloc'd memory, includes malloc memory // usage by types and memory used by tracking itself. -class MallocMemorySnapshot : public ResourceObj { +class MallocMemorySnapshot { friend class MallocMemorySummary; private: @@ -198,7 +198,7 @@ class MallocMemorySnapshot : public ResourceObj { class MallocMemorySummary : AllStatic { private: // Reserve memory for placement of MallocMemorySnapshot object - static size_t _snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)]; + static MallocMemorySnapshot _snapshot; static bool _have_limits; // Called when a total limit break was detected. @@ -245,7 +245,7 @@ class MallocMemorySummary : AllStatic { } static MallocMemorySnapshot* as_snapshot() { - return (MallocMemorySnapshot*)_snapshot; + return &_snapshot; } // MallocLimit: returns true if allocating s bytes on f would trigger diff --git a/src/hotspot/share/services/nmtCommon.hpp b/src/hotspot/share/services/nmtCommon.hpp index 71a48f656d0..590838b8a69 100644 --- a/src/hotspot/share/services/nmtCommon.hpp +++ b/src/hotspot/share/services/nmtCommon.hpp @@ -31,8 +31,6 @@ #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" -#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_up(sizeof(obj), sizeof(type))/sizeof(type)) - // Native memory tracking level // // The meaning of the different states: diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index 4e94a43c117..5c0ab5e592f 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -32,7 +32,7 @@ #include "services/virtualMemoryTracker.hpp" #include "utilities/ostream.hpp" -size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)]; +VirtualMemorySnapshot VirtualMemorySummary::_snapshot; void VirtualMemory::update_peak(size_t size) { size_t peak_sz = peak_size(); @@ -46,12 +46,6 @@ void VirtualMemory::update_peak(size_t size) { } } -void VirtualMemorySummary::initialize() { - assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); - // Use placement operator new to initialize static data area. - ::new ((void*)_snapshot) VirtualMemorySnapshot(); -} - void VirtualMemorySummary::snapshot(VirtualMemorySnapshot* s) { // Only if thread stack is backed by virtual memory if (ThreadStackTracker::track_as_vm()) { @@ -334,7 +328,6 @@ address ReservedMemoryRegion::thread_stack_uncommitted_bottom() const { bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) { assert(_reserved_regions == nullptr, "only call once"); if (level >= NMT_summary) { - VirtualMemorySummary::initialize(); _reserved_regions = new (std::nothrow, mtNMT) SortedLinkedList(); return (_reserved_regions != nullptr); diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index 3839df113d7..d9c20d957dc 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -134,7 +134,6 @@ class VirtualMemorySnapshot : public ResourceObj { class VirtualMemorySummary : AllStatic { public: - static void initialize(); static inline void record_reserved_memory(size_t size, MEMFLAGS flag) { as_snapshot()->by_type(flag)->reserve_memory(size); @@ -169,11 +168,11 @@ class VirtualMemorySummary : AllStatic { static void snapshot(VirtualMemorySnapshot* s); static VirtualMemorySnapshot* as_snapshot() { - return (VirtualMemorySnapshot*)_snapshot; + return &_snapshot; } private: - static size_t _snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)]; + static VirtualMemorySnapshot _snapshot; }; From bddd6a7f61ba99fdebbb9f6f3aa275923fe53bc3 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 13 May 2024 20:22:03 +0000 Subject: [PATCH 264/298] 8321925: sun/security/mscapi/KeytoolChangeAlias.java fails with "Alias <246810> does not exist" Backport-of: b6233c3de773fb57b23704f1fec05d8b2d9c11c0 --- .../security/mscapi/KeytoolChangeAlias.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java b/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java index 4cf36977264..729809bb8d4 100644 --- a/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java +++ b/test/jdk/sun/security/mscapi/KeytoolChangeAlias.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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,6 +25,7 @@ import jdk.test.lib.security.CertUtils; import java.security.KeyStore; +import java.security.SecureRandom; /* * @test @@ -35,15 +36,17 @@ */ public class KeytoolChangeAlias { public static void main(String[] args) throws Exception { - + SecureRandom random = new SecureRandom(); + String alias = Integer.toString(random.nextInt(1000, 8192)); + String newAlias = alias + "1"; KeyStore ks = KeyStore.getInstance("Windows-MY"); ks.load(null, null); try { - ks.setCertificateEntry("246810", CertUtils.getCertFromFile("246810.cer")); + ks.setCertificateEntry(alias, CertUtils.getCertFromFile("246810.cer")); - if (ks.containsAlias("13579")) { - ks.deleteEntry("13579"); + if (ks.containsAlias(newAlias)) { + ks.deleteEntry(newAlias); } int before = ks.size(); @@ -52,8 +55,8 @@ public static void main(String[] args) throws Exception { SecurityTools.keytool("-changealias", "-storetype", "Windows-My", - "-alias", "246810", - "-destalias", "13579").shouldHaveExitValue(0); + "-alias", alias, + "-destalias", newAlias).shouldHaveExitValue(0); ks.load(null, null); @@ -63,13 +66,23 @@ public static void main(String[] args) throws Exception { + ". After: " + ks.size()); } - if (!ks.containsAlias("13579")) { + if (!ks.containsAlias(newAlias)) { throw new Exception("error: cannot find the new alias name" + " in the Windows-MY store"); } } finally { - ks.deleteEntry("13579"); - ks.deleteEntry("246810"); + try { + ks.deleteEntry(newAlias); + } catch (Exception e) { + System.err.println("Couldn't delete alias " + newAlias); + e.printStackTrace(System.err); + } + try { + ks.deleteEntry(alias); + } catch (Exception e) { + System.err.println("Couldn't delete alias " + alias); + e.printStackTrace(System.err); + } ks.store(null, null); } } From fbb0f4c46446ab50a632b7d73244e5c334eb60c5 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 13 May 2024 20:22:20 +0000 Subject: [PATCH 265/298] 8311964: Some jtreg tests failing on x86 with error 'unrecognized VM options' (C2 flags) Backport-of: 024133b089d911dcc3ea70dfdaa6b150b14a9eb4 --- .../jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java | 1 + .../loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java | 1 + .../compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java | 1 + 3 files changed, 3 insertions(+) diff --git a/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java b/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java index 878c04ecd83..e956a9d0915 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestBackedgeLoadArrayFillMain.java @@ -28,6 +28,7 @@ * @summary ArrayFill: if store is on backedge, last iteration is not to be executed. * @library /test/lib * @compile TestBackedgeLoadArrayFill.jasm + * @requires vm.compiler2.enabled * @run main/othervm * -XX:CompileCommand=compileonly,TestBackedgeLoadArrayFill*::test* * -XX:-TieredCompilation -Xcomp -XX:+OptimizeFill diff --git a/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java b/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java index 9379814b5ff..75b107e0e4b 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopWithUnmergedBackedgesMain.java @@ -26,6 +26,7 @@ * @bug 8296412 * @compile TestInfiniteLoopWithUnmergedBackedges.jasm * @summary Infinite loops may not have the backedges merged, before we call IdealLoopTree::check_safepts + * @requires vm.compiler2.enabled * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:-LoopUnswitching * -XX:CompileCommand=compileonly,TestInfiniteLoopWithUnmergedBackedges::test* * TestInfiniteLoopWithUnmergedBackedgesMain diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java b/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java index 76a6d075c06..66cc87b6e4b 100644 --- a/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java +++ b/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckCmpUOverflowVsSub.java @@ -25,6 +25,7 @@ * @test * @bug 8299959 * @summary In CmpU::Value, the sub computation may be narrower than the overflow computation. + * @requires vm.compiler2.enabled * * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+StressCCP -Xcomp -XX:-TieredCompilation * -XX:CompileCommand=compileonly,compiler.rangechecks.TestRangeCheckCmpUOverflowVsSub::test From 035e3144674d494919283941a2e1f3f6dddefaeb Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Tue, 14 May 2024 09:05:36 +0000 Subject: [PATCH 266/298] 8324243: Compilation failures in java.desktop module with gcc 14 Backport-of: 8e5f6ddb68572c0cc8b6e256e423706f6f7cec94 --- make/modules/java.desktop/lib/Awt2dLibraries.gmk | 4 +++- .../linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c | 2 +- .../native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c | 2 +- src/java.desktop/share/native/libfontmanager/sunFont.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index d6a4e6df4fc..a33f219e83e 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -477,8 +477,10 @@ else # noexcept-type required for GCC 7 builds. Not required for GCC 8+. # expansion-to-defined required for GCC 9 builds. Not required for GCC 10+. # maybe-uninitialized required for GCC 8 builds. Not required for GCC 9+. + # calloc-transposed-args required for GCC 14 builds. (fixed upstream in Harfbuzz 032c931e1c0cfb20f18e5acb8ba005775242bd92) HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := class-memaccess noexcept-type \ - expansion-to-defined dangling-reference maybe-uninitialized + expansion-to-defined dangling-reference maybe-uninitialized \ + calloc-transposed-args HARFBUZZ_DISABLED_WARNINGS_clang := missing-field-initializers range-loop-analysis HARFBUZZ_DISABLED_WARNINGS_microsoft := 4267 4244 diff --git a/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c index 6ff6fc681e2..d7a3f1115b5 100644 --- a/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c +++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c @@ -218,7 +218,7 @@ MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) { return NULL; } } - jdk_message = (MidiMessage*) calloc(sizeof(MidiMessage), 1); + jdk_message = (MidiMessage*) calloc(1, sizeof(MidiMessage)); if (!jdk_message) { ERROR0("< ERROR: MIDI_IN_GetMessage(): out of memory\n"); return NULL; diff --git a/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c index d528e4869ac..96193b5f734 100644 --- a/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c +++ b/src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c @@ -383,7 +383,7 @@ INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex, TRACE0("> openMidiDevice()\n"); - (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1); + (*handle) = (MidiDeviceHandle*) calloc(1, sizeof(MidiDeviceHandle)); if (!(*handle)) { ERROR0("ERROR: openDevice: out of memory\n"); return MIDI_OUT_OF_MEMORY; diff --git a/src/java.desktop/share/native/libfontmanager/sunFont.c b/src/java.desktop/share/native/libfontmanager/sunFont.c index 661dccae0c5..4704f18ea4a 100644 --- a/src/java.desktop/share/native/libfontmanager/sunFont.c +++ b/src/java.desktop/share/native/libfontmanager/sunFont.c @@ -67,7 +67,7 @@ int isNullScalerContext(void *context) { */ JNIEXPORT jlong JNICALL Java_sun_font_NullFontScaler_getGlyphImage (JNIEnv *env, jobject scaler, jlong pContext, jint glyphCode) { - void *nullscaler = calloc(sizeof(GlyphInfo), 1); + void *nullscaler = calloc(1, sizeof(GlyphInfo)); return ptr_to_jlong(nullscaler); } From 5b5d778e43b9e31e2319a5ccb4c059cad0fa1388 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Wed, 15 May 2024 08:37:09 +0000 Subject: [PATCH 267/298] 8309871: jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java timed out Backport-of: b9df827adc92cb1fc65f6b1efdf82dcae00a4e2d --- .../jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java index ee1c9d37922..478e7a7f77e 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java @@ -47,7 +47,7 @@ * @key jfr * @requires vm.hasJFR * @library /test/lib - * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetEndTime + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.api.consumer.recordingstream.TestSetEndTime */ public final class TestSetEndTime { From 2429a900447789af4f4a371c7b67b4d906ae27db Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 15 May 2024 09:16:28 +0000 Subject: [PATCH 268/298] 8325255: jdk.internal.util.ReferencedKeySet::add using wrong test Backport-of: a7461de231da20ed78a7c6ad8275f1bafbfa556c --- .../jdk/internal/util/ReferencedKeyMap.java | 26 +++++++++++++++++++ .../jdk/internal/util/ReferencedKeySet.java | 2 +- .../jdk/internal/util/ReferencedKeyTest.java | 6 +++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java index f102e3c94e1..be392c3ae2d 100644 --- a/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java +++ b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java @@ -439,4 +439,30 @@ private static T internKey(ReferencedKeyMap> setMap, T ke return interned; } + + /** + * Attempt to add key to map if absent. + * + * @param setMap {@link ReferencedKeyMap} where interning takes place + * @param key key to add + * + * @param type of key + * + * @return true if the key was added + */ + static boolean internAddKey(ReferencedKeyMap> setMap, T key) { + ReferenceKey entryKey = setMap.entryKey(key); + setMap.removeStaleReferences(); + ReferenceKey existing = setMap.map.putIfAbsent(entryKey, entryKey); + if (existing == null) { + return true; + } else { + // If {@code putIfAbsent} returns non-null then was actually a + // {@code replace} and older key was used. In that case the new + // key was not used and the reference marked stale. + entryKey.unused(); + return false; + } + } + } diff --git a/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java b/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java index 807eea87dfe..21b940439e0 100644 --- a/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java +++ b/src/java.base/share/classes/jdk/internal/util/ReferencedKeySet.java @@ -148,7 +148,7 @@ public boolean contains(Object o) { @Override public boolean add(T e) { - return intern(e) == null; + return ReferencedKeyMap.internAddKey(map, e); } @Override diff --git a/test/jdk/jdk/internal/util/ReferencedKeyTest.java b/test/jdk/jdk/internal/util/ReferencedKeyTest.java index c5edaedd2e2..75690fa6e25 100644 --- a/test/jdk/jdk/internal/util/ReferencedKeyTest.java +++ b/test/jdk/jdk/internal/util/ReferencedKeyTest.java @@ -127,6 +127,12 @@ static void methods(ReferencedKeySet set) { assertTrue(element1 == intern1, "intern failed"); // must be same object assertTrue(intern2 != null, "intern failed"); assertTrue(element3 == intern3, "intern failed"); + + Long value1 = Long.valueOf(BASE_KEY + 999); + Long value2 = Long.valueOf(BASE_KEY + 999); + assertTrue(set.add(value1), "key not added"); + assertTrue(!set.add(value1), "key added after second attempt"); + assertTrue(!set.add(value2), "key should not have been added"); } // Borrowed from jdk.test.lib.util.ForceGC but couldn't use from java.base/jdk.internal.util From 59ca0093a82483726ca1a1f021d3d80c804c585b Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Wed, 15 May 2024 10:14:41 +0000 Subject: [PATCH 269/298] 8331942: On Linux aarch64, CDS archives should be using 64K alignment by default Backport-of: d2d37c913e5b55f7aec2c7a6b5a2328348ded223 --- make/autoconf/jdk-options.m4 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index f56081223a6..0797e823a58 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -190,6 +190,17 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS], fi AC_SUBST(INCLUDE_SA) + # Setup default CDS alignment. On platforms where one build may run on machines with different + # page sizes, the JVM choses a compatible alignment to fit all possible page sizes. This slightly + # increases archive size. + # The only platform having this problem at the moment is Linux on aarch64, which may encounter + # three different page sizes: 4K, 64K, and if run on Mac m1 hardware, 16K. + COMPATIBLE_CDS_ALIGNMENT_DEFAULT=false + if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + COMPATIBLE_CDS_ALIGNMENT_DEFAULT=true + fi + AC_SUBST(COMPATIBLE_CDS_ALIGNMENT_DEFAULT) + # Compress jars COMPRESS_JARS=false @@ -673,7 +684,7 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE], # AC_DEFUN([JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT], [ - UTIL_ARG_ENABLE(NAME: compatible-cds-alignment, DEFAULT: false, + UTIL_ARG_ENABLE(NAME: compatible-cds-alignment, DEFAULT: $COMPATIBLE_CDS_ALIGNMENT_DEFAULT, RESULT: ENABLE_COMPATIBLE_CDS_ALIGNMENT, DESC: [enable use alternative compatible cds core region alignment], DEFAULT_DESC: [disabled], From 87318f8783e26cb204792166155b6714312fef07 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 15 May 2024 11:05:31 +0000 Subject: [PATCH 270/298] 8331352: error: template-id not allowed for constructor/destructor in C++20 Backport-of: 45792c5829fb1d5ee016c4a1fd6badb5d2b4239c --- src/hotspot/share/gc/z/zArray.inline.hpp | 2 +- src/hotspot/share/utilities/chunkedList.hpp | 2 +- src/hotspot/share/utilities/events.hpp | 2 +- src/hotspot/share/utilities/linkedlist.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/z/zArray.inline.hpp b/src/hotspot/share/gc/z/zArray.inline.hpp index e4de7a37040..2ec87a76156 100644 --- a/src/hotspot/share/gc/z/zArray.inline.hpp +++ b/src/hotspot/share/gc/z/zArray.inline.hpp @@ -96,7 +96,7 @@ ZActivatedArray::ZActivatedArray(bool locked) _array() {} template -ZActivatedArray::~ZActivatedArray() { +ZActivatedArray::~ZActivatedArray() { FreeHeap(_lock); } diff --git a/src/hotspot/share/utilities/chunkedList.hpp b/src/hotspot/share/utilities/chunkedList.hpp index 81898ac53b2..9a600e4ce1b 100644 --- a/src/hotspot/share/utilities/chunkedList.hpp +++ b/src/hotspot/share/utilities/chunkedList.hpp @@ -44,7 +44,7 @@ template class ChunkedList : public CHeapObj { } public: - ChunkedList() : _top(_values), _next_used(nullptr), _next_free(nullptr) {} + ChunkedList() : _top(_values), _next_used(nullptr), _next_free(nullptr) {} bool is_full() const { return _top == end(); diff --git a/src/hotspot/share/utilities/events.hpp b/src/hotspot/share/utilities/events.hpp index b400fd707fa..f7d2d193a86 100644 --- a/src/hotspot/share/utilities/events.hpp +++ b/src/hotspot/share/utilities/events.hpp @@ -99,7 +99,7 @@ template class EventLogBase : public EventLog { EventRecord* _records; public: - EventLogBase(const char* name, const char* handle, int length = LogEventsBufferEntries): + EventLogBase(const char* name, const char* handle, int length = LogEventsBufferEntries): _mutex(Mutex::event, name), _name(name), _handle(handle), diff --git a/src/hotspot/share/utilities/linkedlist.hpp b/src/hotspot/share/utilities/linkedlist.hpp index 5b8e258d539..eec7ea1e48d 100644 --- a/src/hotspot/share/utilities/linkedlist.hpp +++ b/src/hotspot/share/utilities/linkedlist.hpp @@ -82,7 +82,7 @@ template class LinkedListNode : public AnyObj { template class LinkedList : public AnyObj { protected: LinkedListNode* _head; - NONCOPYABLE(LinkedList); + NONCOPYABLE(LinkedList); public: LinkedList() : _head(nullptr) { } From fdb82f42f1b6f51ad0c54a08e0b9346d65a70643 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 15 May 2024 11:05:49 +0000 Subject: [PATCH 271/298] 8328997: Remove unnecessary template parameter lists in GrowableArray Backport-of: 3d2283800acee58dbf046c8b401a5a144ab65ed1 --- src/hotspot/share/utilities/growableArray.hpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/utilities/growableArray.hpp b/src/hotspot/share/utilities/growableArray.hpp index d9c47e8360f..5b67bc88e1b 100644 --- a/src/hotspot/share/utilities/growableArray.hpp +++ b/src/hotspot/share/utilities/growableArray.hpp @@ -118,7 +118,7 @@ class GrowableArrayView : public GrowableArrayBase { protected: E* _data; // data array - GrowableArrayView(E* data, int capacity, int initial_len) : + GrowableArrayView(E* data, int capacity, int initial_len) : GrowableArrayBase(capacity, initial_len), _data(data) {} ~GrowableArrayView() {} @@ -126,7 +126,7 @@ class GrowableArrayView : public GrowableArrayBase { public: const static GrowableArrayView EMPTY; - bool operator==(const GrowableArrayView& rhs) const { + bool operator==(const GrowableArrayView& rhs) const { if (_len != rhs._len) return false; for (int i = 0; i < _len; i++) { @@ -137,7 +137,7 @@ class GrowableArrayView : public GrowableArrayBase { return true; } - bool operator!=(const GrowableArrayView& rhs) const { + bool operator!=(const GrowableArrayView& rhs) const { return !(*this == rhs); } @@ -345,7 +345,7 @@ template class GrowableArrayFromArray : public GrowableArrayView { public: - GrowableArrayFromArray(E* data, int len) : + GrowableArrayFromArray(E* data, int len) : GrowableArrayView(data, len, len) {} }; @@ -480,7 +480,7 @@ class GrowableArrayWithAllocator : public GrowableArrayView { return this->at(location); } - void swap(GrowableArrayWithAllocator* other) { + void swap(GrowableArrayWithAllocator* other) { ::swap(this->_data, other->_data); ::swap(this->_len, other->_len); ::swap(this->_capacity, other->_capacity); @@ -682,8 +682,8 @@ class GrowableArrayMetadata { // See: init_checks. template -class GrowableArray : public GrowableArrayWithAllocator > { - friend class GrowableArrayWithAllocator >; +class GrowableArray : public GrowableArrayWithAllocator> { + friend class GrowableArrayWithAllocator; friend class GrowableArrayTest; static E* allocate(int max) { @@ -731,7 +731,7 @@ class GrowableArray : public GrowableArrayWithAllocator > { GrowableArray() : GrowableArray(2 /* initial_capacity */) {} explicit GrowableArray(int initial_capacity) : - GrowableArrayWithAllocator >( + GrowableArrayWithAllocator( allocate(initial_capacity), initial_capacity), _metadata() { @@ -739,7 +739,7 @@ class GrowableArray : public GrowableArrayWithAllocator > { } GrowableArray(int initial_capacity, MEMFLAGS memflags) : - GrowableArrayWithAllocator >( + GrowableArrayWithAllocator( allocate(initial_capacity, memflags), initial_capacity), _metadata(memflags) { @@ -747,7 +747,7 @@ class GrowableArray : public GrowableArrayWithAllocator > { } GrowableArray(int initial_capacity, int initial_len, const E& filler) : - GrowableArrayWithAllocator >( + GrowableArrayWithAllocator( allocate(initial_capacity), initial_capacity, initial_len, filler), _metadata() { @@ -755,7 +755,7 @@ class GrowableArray : public GrowableArrayWithAllocator > { } GrowableArray(int initial_capacity, int initial_len, const E& filler, MEMFLAGS memflags) : - GrowableArrayWithAllocator >( + GrowableArrayWithAllocator( allocate(initial_capacity, memflags), initial_capacity, initial_len, filler), _metadata(memflags) { @@ -763,7 +763,7 @@ class GrowableArray : public GrowableArrayWithAllocator > { } GrowableArray(Arena* arena, int initial_capacity, int initial_len, const E& filler) : - GrowableArrayWithAllocator >( + GrowableArrayWithAllocator( allocate(initial_capacity, arena), initial_capacity, initial_len, filler), _metadata(arena) { @@ -847,15 +847,15 @@ class GrowableArrayIterator : public StackObj { public: GrowableArrayIterator() : _array(nullptr), _position(0) { } - GrowableArrayIterator& operator++() { ++_position; return *this; } - E operator*() { return _array->at(_position); } + GrowableArrayIterator& operator++() { ++_position; return *this; } + E operator*() { return _array->at(_position); } - bool operator==(const GrowableArrayIterator& rhs) { + bool operator==(const GrowableArrayIterator& rhs) { assert(_array == rhs._array, "iterator belongs to different array"); return _position == rhs._position; } - bool operator!=(const GrowableArrayIterator& rhs) { + bool operator!=(const GrowableArrayIterator& rhs) { assert(_array == rhs._array, "iterator belongs to different array"); return _position != rhs._position; } From 30f0779c73c030d1f4cd94baf750c70b82b62f73 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 15 May 2024 11:41:41 +0000 Subject: [PATCH 272/298] 8331167: UBSan enabled build fails in adlc on macOS Backport-of: 4edac349a5d695ce7923344ad5ad0400842241eb --- src/hotspot/share/adlc/adlparse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index 0d2da75906f..e8f67e99c62 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -5192,7 +5192,7 @@ void ADLParser::skipws_common(bool do_preproc) { if (*_ptr == '\n') { // keep proper track of new lines if (!do_preproc) break; // let caller handle the newline next_line(); - _ptr = _curline; next = _ptr + 1; + _ptr = _curline; if (_ptr != nullptr) next = _ptr + 1; } else if ((*_ptr == '/') && (*next == '/')) // C++ comment do { _ptr++; next++; } while(*_ptr != '\n'); // So go to end of line From 9b8f98871a66bde6db87d76758b149d8a2c601e4 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 15 May 2024 11:43:03 +0000 Subject: [PATCH 273/298] 8330615: avoid signed integer overflows in zip_util.c readCen / hashN Backport-of: 5af6b45eefd227e3e046ca22a404ae8a23174160 --- src/java.base/share/native/libzip/zip_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/native/libzip/zip_util.c b/src/java.base/share/native/libzip/zip_util.c index e4daedbe873..8597e8b60d1 100644 --- a/src/java.base/share/native/libzip/zip_util.c +++ b/src/java.base/share/native/libzip/zip_util.c @@ -442,7 +442,7 @@ hash(const char *s) static unsigned int hashN(const char *s, int length) { - int h = 0; + unsigned int h = 0; while (length-- > 0) h = 31*h + *s++; return h; From 87fe0d28ed581b107917ffcbb9ec29e6dbb906d3 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 15 May 2024 11:48:42 +0000 Subject: [PATCH 274/298] 8329663: hs_err file event log entry for thread adding/removing should print current thread Backport-of: 3ebf8c9359da2f45e4cefb7be2276d33c30979aa --- src/hotspot/share/runtime/threads.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 3e121e3bf74..ef5ccec9ec8 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -1008,7 +1008,7 @@ void Threads::add(JavaThread* p, bool force_daemon) { ObjectSynchronizer::inc_in_use_list_ceiling(); // Possible GC point. - Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p)); + Events::log(Thread::current(), "Thread added: " INTPTR_FORMAT, p2i(p)); // Make new thread known to active EscapeBarrier EscapeBarrier::thread_added(p); @@ -1071,7 +1071,7 @@ void Threads::remove(JavaThread* p, bool is_daemon) { ObjectSynchronizer::dec_in_use_list_ceiling(); // Since Events::log uses a lock, we grab it outside the Threads_lock - Events::log(p, "Thread exited: " INTPTR_FORMAT, p2i(p)); + Events::log(Thread::current(), "Thread exited: " INTPTR_FORMAT, p2i(p)); } // Operations on the Threads list for GC. These are not explicitly locked, From 6b0467c4736b9bda7fc7650f510754ef91be79f0 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 16 May 2024 02:02:08 +0000 Subject: [PATCH 275/298] 8299023: TestPLABResize.java and TestPLABPromotion.java are failing intermittently Backport-of: f50df105912858198809b50432ef5a4ab184528d --- test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java | 4 ++-- test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java index 1c07eeefe94..95740559cc0 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,7 @@ * @bug 8141278 8141141 * @summary Test PLAB promotion * @requires vm.gc.G1 - * @requires !vm.flightRecorder + * @requires vm.flagless * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules java.management diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java index 82246d790f4..48423218868 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,7 @@ * @bug 8141278 8141141 * @summary Test for PLAB resizing * @requires vm.gc.G1 - * @requires !vm.flightRecorder + * @requires vm.flagless * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules java.management From 0a2e2e707dce937cd134f07a692084449247db5b Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Thu, 16 May 2024 21:52:11 +0000 Subject: [PATCH 276/298] 8308144: Uncontrolled memory consumption in SSLFlowDelegate.Reader Backport-of: 099a8f5b2f924fddd43ff72f3f7c6f34b6c15b0f --- .../net/http/common/SSLFlowDelegate.java | 54 +- .../whitebox/SSLFlowDelegateTestDriver.java | 33 + .../net/http/SSLFlowDelegateTest.java | 595 ++++++++++++++++++ 3 files changed, 662 insertions(+), 20 deletions(-) create mode 100644 test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java create mode 100644 test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java index 09845636b89..c662983d0af 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java @@ -54,17 +54,27 @@ import java.util.function.IntBinaryOperator; /** - * Implements SSL using two SubscriberWrappers. + * Implements SSL using two {@link SubscriberWrapper}s. * - *

      Constructor takes two Flow.Subscribers: one that receives the network - * data (after it has been encrypted by SSLFlowDelegate) data, and one that - * receives the application data (before it has been encrypted by SSLFlowDelegate). + *

      Constructor takes two {@linkplain Flow.Subscriber subscribers} - {@code downReader} + * and {@code downWriter}. {@code downReader} receives the application data (after it has + * been decrypted by SSLFlowDelegate). {@code downWriter} receives the network data (after it has + * been encrypted by SSLFlowDelegate). * - *

      Methods upstreamReader() and upstreamWriter() return the corresponding - * Flow.Subscribers containing Flows for the encrypted/decrypted upstream data. - * See diagram below. + *

      Method {@link #upstreamWriter()} returns a {@linkplain Subscriber subscriber} which should + * be subscribed with a {@linkplain Flow.Publisher publisher} which publishes application data + * that can then be encrypted into network data by this SSLFlowDelegate and handed off to the + * {@code downWriter}. * - *

      How Flow.Subscribers are used in this class, and where they come from: + *

      Method {@link #upstreamReader()} returns a {@link Subscriber subscriber} which should be + * subscribed with a {@linkplain Flow.Publisher publisher} which publishes encrypted network data + * that can then be decrypted into application data by this SSLFlowDelegate and handed off to the + * {@code downReader}. + * + *

      Errors are reported to the {@code downReader} subscriber. + * + *

      The diagram below illustrates how the Flow.Subscribers are used in this class, and where + * they come from: *

        * {@code
        *
      @@ -73,17 +83,21 @@
        * --------->  data flow direction
        *
        *
      - *                         +------------------+
      - *        upstreamWriter   |                  | downWriter
      - *        ---------------> |                  | ------------>
      - *  obtained from this     |                  | supplied to constructor
      - *                         | SSLFlowDelegate  |
      - *        downReader       |                  | upstreamReader
      - *        <--------------- |                  | <--------------
      - * supplied to constructor |                  | obtained from this
      - *                         +------------------+
      - *
      - * Errors are reported to the downReader Flow.Subscriber
      + *                  |                                   ^
      + *  upstreamWriter  |                                   | downReader
      + *  obtained from   |                                   | supplied to
      + * upstreamWriter() |                                   | constructor
      + *                  v                                   |
      + *      +-----------------------------------------------------------+
      + *      *                                            decrypts       *
      + *      *                       SSLFlowDelegate                     *
      + *      *        encrypts                                           *
      + *      +-----------------------------------------------------------+
      + *                  |                                   ^
      + *    downWriter    |                                   | upstreamReader
      + *    supplied to   |                                   | obtained from
      + *    constructor   |                                   | upstreamReader()
      + *                  v                                   |
        *
        * }
        * 
      @@ -477,7 +491,7 @@ else if (this.completing) { readBufferLock.unlock(); } // request more data and return. - requestMore(); + requestMoreDataIfNeeded(); return; } if (complete && result.status() == Status.CLOSED) { diff --git a/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java b/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java new file mode 100644 index 00000000000..083a291751f --- /dev/null +++ b/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8308144 + * @summary tests that the SSLFlowDelegate doesn't accumulate application data when the + * downReader doesn't request any + * @modules java.net.http/jdk.internal.net.http + * @run testng/othervm -Djdk.internal.httpclient.debug=true + * -Djavax.net.debug=ssl:handshake + * java.net.http/jdk.internal.net.http.SSLFlowDelegateTest + */ diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java new file mode 100644 index 00000000000..45af27a96a8 --- /dev/null +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2023, 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. + */ + +package jdk.internal.net.http; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Flow; +import java.util.concurrent.Flow.Subscriber; +import java.util.concurrent.SubmissionPublisher; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; + +import jdk.internal.net.http.common.Logger; +import jdk.internal.net.http.common.SSLFlowDelegate; +import jdk.internal.net.http.common.SubscriberWrapper; +import jdk.internal.net.http.common.Utils; +import org.testng.Assert; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +// jtreg test definition for this test resides in SSLFlowDelegateTestDriver.java +public class SSLFlowDelegateTest { + private static final String ALPN = "foobar"; + private static final String debugTag = SSLFlowDelegateTest.class.getSimpleName(); + private static final Random random = new Random(); + private static final byte DATA_BYTE = (byte) random.nextInt(); + + private ExecutorService executor; + private SSLContext sslContext; + private SSLParameters sslParams; + private SSLServerSocket sslServerSocket; + private SSLEngine clientEngine; + private CompletableFuture testCompletion; + + @BeforeTest + public void beforeTest() throws Exception { + this.executor = Executors.newCachedThreadPool(); + this.sslContext = new jdk.internal.net.http.SimpleSSLContext().get(); + this.testCompletion = new CompletableFuture<>(); + + final SSLParameters sp = new SSLParameters(); + sp.setApplicationProtocols(new String[]{ALPN}); + this.sslParams = sp; + + this.sslServerSocket = startServer(this.sslContext); + println(debugTag, "Server started at " + this.sslServerSocket.getInetAddress() + ":" + + this.sslServerSocket.getLocalPort()); + + this.clientEngine = createClientEngine(this.sslContext); + } + + @AfterTest + public void afterTest() throws Exception { + if (this.sslServerSocket != null) { + println(debugTag, "Closing server socket " + this.sslServerSocket); + this.sslServerSocket.close(); + } + if (this.executor != null) { + println(debugTag, "Shutting down the executor " + this.executor); + this.executor.shutdownNow(); + } + } + + private static void println(final String debugTag, final String msg) { + println(debugTag, msg, null); + } + + private static void println(final String debugTag, final String msg, final Throwable t) { + final Logger logger = Utils.getDebugLogger(() -> debugTag); + logger.log(msg); + if (t != null) { + t.printStackTrace(); + } + } + + private SSLServerSocket createSSLServerSocket( + final SSLContext ctx, final InetSocketAddress bindAddr) throws IOException { + final SSLServerSocketFactory fac = ctx.getServerSocketFactory(); + final SSLServerSocket sslServerSocket = (SSLServerSocket) fac.createServerSocket(); + sslServerSocket.setReuseAddress(false); + sslServerSocket.setSSLParameters(this.sslParams); + sslServerSocket.bind(bindAddr); + return sslServerSocket; + } + + private SSLServerSocket startServer(final SSLContext ctx) throws Exception { + final SSLServerSocket sslServerSocket = createSSLServerSocket(ctx, + new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + final Runnable serverResponsePusher = new ServerResponsePusher(sslServerSocket, + this.testCompletion); + final Thread serverThread = new Thread(serverResponsePusher, "serverResponsePusher"); + // start the thread which will accept() a socket connection and send data over it + serverThread.start(); + return sslServerSocket; + } + + private SSLEngine createClientEngine(final SSLContext ctx) { + final SSLEngine clientEngine = ctx.createSSLEngine(); + clientEngine.setSSLParameters(this.sslParams); + clientEngine.setUseClientMode(true); + return clientEngine; + } + + /** + * Constructs a {@code SSLFlowDelegate} with a {@code downReader} which only requests one + * item and then never requests any more. After that one item has been received by the + * {@code downReader}, this test feeds the + * {@linkplain SSLFlowDelegate#upstreamReader() upstreamReader} with (network SSL) data in + * such a manner that while + * {@link SSLEngine#unwrap(ByteBuffer, ByteBuffer) unwrapping} it in the internal implementation + * of {@code SSLFlowDelegate}, it will often trigger {@code BUFFER_UNDERFLOW} state. + * This test then verifies that the {@code SSLFlowDelegate} when it reaches such a state will + * not keep asking for more (network SSL) data and decrypting it to application data and + * accumulating it (since the {@code downReader} won't be using any of this accumulated data). + */ + @Test + public void testUnsolicitedBytes() throws Exception { + // initiate a connection to the server + try (final Socket socket = new Socket(sslServerSocket.getInetAddress(), + sslServerSocket.getLocalPort())) { + println(debugTag, "connected to server, local socket: " + socket); + // this future is completed when the AppResponseReceiver subscriber receives + // the sole item that is requests for (through just one subscription.request(1)) + final CompletableFuture soleExpectedAppData = new CompletableFuture<>(); + // the "testCompletion" CompletableFuture represents that future that's used + // in various places in this test. If the "testCompletion" completes before + // the "soleExpectedAppData" completes (typically due to some exception), + // then we complete the "soleExpectedAppData" too. + this.testCompletion.whenComplete((r, t) -> { + if (soleExpectedAppData.isDone()) { + return; + } + if (t == null) { + soleExpectedAppData.complete(-1L); // -1 indicates no item received + return; + } + soleExpectedAppData.completeExceptionally(t); + }); + // the "downReader" Subscriber which is passed to the constructor of SSLFlowDelegate. + // This subscriber receives the (decrypted) application data. This subscriber requests + // only one item (no restriction on how many bytes are received in this one item). + final AppResponseReceiver appResponseReceiver = new AppResponseReceiver( + this.testCompletion, soleExpectedAppData); + // the "downWriter" Subscriber which is passed to the constructor of the + // SSLFlowDelegate. + // This subscriber receives the (encrypted) network data and just writes it out to the + // connected socket's OutputStream. Makes no restrictions on how much items (and thus + // bytes) it receives and just keeps writing as and when it receives the data. + final SocketWriter networkDataWriter = new SocketWriter(socket, this.testCompletion); + // construct the SSLFlowDelegate + final SSLFlowDelegate sslFlowDelegate = new SSLFlowDelegate(clientEngine, executor, + appResponseReceiver, networkDataWriter); + // the SocketReader runs in a thread and it keeps reading data from the connected + // socket's InputStream. This data keeps coming from the ServerResponsePusher which too + // is running in a thread of its own and is writing it out over the connected socket's + // OutputStream. The SocketReader and ServerResponsePusher are convenience constructs + // which use the simple APIs (InputStream/OutputStream) provided by SSLServerSocket + // and (SSL)Socket to generate SSL network data. This generated data is then fed to + // the relevant subscribers of SSLFlowDelegate. The SocketReader and the + // ServerResponsePusher play no other role than just generating this SSL network data. + final SocketReader socketReader = new SocketReader(socket, executor, + sslFlowDelegate.upstreamReader(), this.testCompletion); + // start reading from the socket in separate thread + new Thread(socketReader, "socketReader").start(); + + // we use this publisher only to trigger the SSL handshake and the publisher itself + // doesn't publish any data i.e. there is no application client "request" data needed + // in this test + final Flow.Publisher> publisher = new ZeroDataPublisher<>(); + println(debugTag, "Subscribing the upstreamWriter() to trigger SSL handshake"); + // now connect all the pieces. + // this call to subscribe the upstreamWriter() triggers the SSL handshake (doesn't + // matter if our zero app data publisher publishes no app data; SSL handshake + // doesn't require app data). see SSLFlowDelegate$Writer.onSubscribe() where + // it triggers the SSL handshake when this subscription happens + publisher.subscribe(sslFlowDelegate.upstreamWriter()); + println(debugTag, "Waiting for handshake to complete"); + final String negotiatedALPN = sslFlowDelegate.alpn().join(); + println(debugTag, "handshake completed, with negotiated ALPN: " + negotiatedALPN); + Assert.assertEquals(negotiatedALPN, ALPN, "unexpected ALPN negotiated"); + try { + // now wait for the initial (and the only) chunk of application data to be + // received by the AppResponseReceiver + println(debugTag, "waiting for the sole expected chunk of application data to" + + " become available to " + appResponseReceiver); + final long numAppDataBytesReceived = soleExpectedAppData.join(); + println(debugTag, "Received " + numAppDataBytesReceived + " app data bytes," + + " no more app data expected"); + // at this point, we have received the only expected item in the downReader + // i.e. the AppResponseReceiver. We no longer expect the SSLFlowDelegate to be + // accumulating any decrypted application data (because the downReader hasn't + // requested any). + // We will now let the SocketReader and the ServerResponsePusher threads to keep + // generating and feeding the SSL network data to the SSLFlowDelegate subscribers, + // until they are "done" (either normally or exceptionally). Those threads decide + // when to stop generating the SSL network data. + this.testCompletion.join(); + } catch (CompletionException ce) { + // fail with a Assert.fail instead of throwing an exception, thus providing a + // better failure report + failTest(ce); + } + println(debugTag, "now checking if any unsolicited bytes accumulated"); + // SSL network data generation has completed, now check if the SSLFlowDelegate + // decrypted and accumulated any application data when it shouldn't have. + assertNoUnsolicitedBytes(sslFlowDelegate); + println(debugTag, "testing completed successfully, no unsolicited bytes accumulated"); + } + } + + private void failTest(final CompletionException ce) { + final Throwable cause = ce.getCause(); + Assert.fail(cause.getMessage() == null ? "test failed" : cause.getMessage(), cause); + } + + // uses reflection to get hold of the SSLFlowDelegate.reader.outputQ member field, + // which is a ConcurrentLinkedQueue holding the decrypted application data that + // is supposed to be sent to the downReader subscriber of the SSLFlowDelegate. + // Asserts that this outputQ has 0 bytes of data accumulated + private void assertNoUnsolicitedBytes(final SSLFlowDelegate sslFlowDelegate) throws Exception { + final Field readerField = SSLFlowDelegate.class.getDeclaredField("reader"); + readerField.setAccessible(true); + + final Field readerOutputQField = SubscriberWrapper.class.getDeclaredField("outputQ"); + readerOutputQField.setAccessible(true); + + final Object reader = readerField.get(sslFlowDelegate); + final ConcurrentLinkedQueue> outputQ = + ConcurrentLinkedQueue.class.cast(readerOutputQField.get(reader)); + long numUnsolicitated = 0; + List accumulations; + while ((accumulations = outputQ.poll()) != null) { + println(debugTag, "found some items in outputQ"); + for (final ByteBuffer buf : accumulations) { + if (!buf.hasRemaining()) { + continue; + } + try { + numUnsolicitated = Math.addExact(numUnsolicitated, buf.remaining()); + } catch (ArithmeticException ame) { + numUnsolicitated = Long.MAX_VALUE; + break; + } + } + println(debugTag, "num unsolicited bytes so far = " + numUnsolicitated); + } + Assert.assertEquals(numUnsolicitated, 0, + "SSLFlowDelegate has accumulated " + numUnsolicitated + " unsolicited bytes"); + } + + // A publisher which accepts only one subscriber and doesn't ever publish any data + private static final class ZeroDataPublisher implements Flow.Publisher { + private final AtomicBoolean hasSubscriber = new AtomicBoolean(); + + @Override + public void subscribe(final Subscriber subscriber) { + if (!hasSubscriber.compareAndSet(false, true)) { + // we allow only one subscriber + throw new IllegalStateException("Cannot subscribe more than once"); + } + subscriber.onSubscribe(new Flow.Subscription() { + @Override + public void request(long n) { + // no-op, we don't publish any data + } + + @Override + public void cancel() { + // no-op + } + }); + } + } + + // a Subscriber which subscribers for encrypted SSL network data that it will then + // write to a connected (SSL) Socket's OutputStream + private static final class SocketWriter implements Subscriber> { + private static final String debugTag = SocketWriter.class.getSimpleName(); + + private final Socket socket; + private final CompletableFuture completion; + private volatile Flow.Subscription subscription; + private final AtomicLong numBytesWritten = new AtomicLong(); + + private SocketWriter(final Socket socket, final CompletableFuture completion) { + this.socket = socket; + this.completion = completion; + } + + @Override + public void onSubscribe(final Flow.Subscription subscription) { + this.subscription = subscription; + println(debugTag, "onSubscribe invoked, requesting for data to write to socket"); + subscription.request(1); + } + + @Override + public void onNext(final List bufs) { + try { + final OutputStream os = + new BufferedOutputStream(this.socket.getOutputStream()); + + // these buffers contain encrypted SSL network data that we receive + // from the SSLFlowDelegate. We just write them out to the + // Socket's OutputStream. + for (final ByteBuffer buf : bufs) { + int len = buf.remaining(); + int written = writeToStream(os, buf); + assert len == written; + this.numBytesWritten.addAndGet(len); + assert !buf.hasRemaining() + : "buffer has " + buf.remaining() + " bytes left"; + this.subscription.request(1); // willing to write out more data when available + } + } catch (Throwable e) { + println(debugTag, "failed: " + e, e); + completion.completeExceptionally(e); + } + } + + @Override + public void onError(final Throwable throwable) { + println(debugTag, "error: " + throwable, throwable); + completion.completeExceptionally(throwable); + } + + @Override + public void onComplete() { + println(debugTag, "onComplete(), total bytes written: " + this.numBytesWritten.get()); + } + + private int writeToStream(final OutputStream os, final ByteBuffer buf) throws IOException { + final byte[] b = buf.array(); + final int offset = buf.arrayOffset() + buf.position(); + final int n = buf.limit() - buf.position(); + os.write(b, offset, n); + buf.position(buf.limit()); + os.flush(); + return n; + } + } + + // a background task that keeps reading encrypted SSL network data from a connected + // (SSL) Socket and publishes this data to the SSLFlowDelegate's upstreamReader() subscriber. + // Very importantly, irrespective of how many bytes of data this SocketReader reads + // of the Socket's InputStream in one read() operation, it publishes this data to the + // upstreamReader() subscriber in very small chunks, so that when the upstreamReader() + // subscriber receives it and starts unwrapping that SSL network data, it often + // encounters a BUFFER_UNDERFLOW state. + private static final class SocketReader implements Runnable { + private static final String debugTag = SocketReader.class.getSimpleName(); + + // the size of data that will be published to the upstreamReader() subscriber. + // small enough; no other meaning to this value + private static final int VERY_SMALL_DATA_SIZE = 123; + + private final Socket socket; + private final SubmissionPublisher> publisher; + private final CompletableFuture completion; + + private SocketReader(final Socket socket, final Executor executor, + final Subscriber> incomingNetworkDataSubscriber, + final CompletableFuture completion) { + this.socket = socket; + this.completion = completion; + this.publisher = new SubmissionPublisher<>(executor, Flow.defaultBufferSize(), + (s, t) -> completion.completeExceptionally(t)); + this.publisher.subscribe(incomingNetworkDataSubscriber); + } + + @Override + public void run() { + try { + // reads off the SSLSocket the data from the "server" + final InputStream is = socket.getInputStream(); + long numBytesRead = 0; + long numBytesPublished = 0; + while (true) { + final byte[] buf = new byte[10240]; // this size doesn't matter + final int n = is.read(buf); + if (n == -1) { + println(debugTag, "got EOF, now closing resources; total read " + + numBytesRead + " bytes, total published " + numBytesPublished + + " bytes"); + closeAndComplete(is); + return; + } + println(debugTag, "read " + n + " bytes from socket"); + numBytesRead = Math.addExact(numBytesRead, n); + int remaining = n; + int index = 0; + while (remaining > 0) { + final int chunkSize = Math.min(remaining, VERY_SMALL_DATA_SIZE); + final byte[] chunk = Arrays.copyOfRange(buf, index, index + chunkSize); + index += chunkSize; + remaining -= chunkSize; + final int lagOrDrops = publisher.offer( + List.of(ByteBuffer.wrap(chunk)), 2, TimeUnit.SECONDS, null); + if (lagOrDrops < 0) { + println(debugTag, "dropped a chunk, re-offering"); + // dropped, we now re-attempt once more and if that too is dropped, + // we stop + final int newLagOrDrops = publisher.offer( + List.of(ByteBuffer.wrap(chunk)), 2, TimeUnit.SECONDS, null); + if (newLagOrDrops < 0) { + println(debugTag, "dropped the re-offered chunk; closing resources," + + " total bytes read: " + numBytesRead + + " total bytes published: " + numBytesPublished); + closeAndComplete(is); + return; + } + } + numBytesPublished += chunkSize; + println(debugTag, "published " + numBytesPublished + " bytes of total " + + numBytesRead + " bytes read"); + } + } + } catch (Throwable e) { + println(debugTag, "failed: " + e, e); + completion.completeExceptionally(e); + } + } + + private void closeAndComplete(final InputStream is) { + publisher.close(); + completion.complete(null); + Utils.close(is); + } + } + + // a background task which accepts one socket connection on a SSLServerSocket and keeps + // writing (application) data to the OutputStream of that socket. + private static final class ServerResponsePusher implements Runnable { + private static final String debugTag = ServerResponsePusher.class.getSimpleName(); + private final SSLServerSocket sslServerSocket; + private final CompletableFuture completion; + + private ServerResponsePusher(final SSLServerSocket sslServerSocket, + final CompletableFuture completion) { + this.sslServerSocket = sslServerSocket; + this.completion = completion; + } + + @Override + public void run() { + try { + // accept a connection + try (final Socket socket = this.sslServerSocket.accept()) { + println(debugTag, "Accepted connection from " + socket); + try (final OutputStream os = socket.getOutputStream()) { + final byte[] resp = new byte[10240]; // this size doesn't matter + Arrays.fill(resp, DATA_BYTE); + long numWritten = 0; + // reasonable number of times to generate enough network data + final int numTimes = 50; + for (int i = 0; i < numTimes; i++) { + println(debugTag, "writing " + resp.length + " bytes, " + + numWritten + " written so far"); + os.write(resp); + numWritten += resp.length; + os.flush(); + } + println(debugTag, "stopped writing, total bytes written: " + numWritten); + } + } + } catch (Throwable e) { + println(debugTag, "error: " + e, e); + this.completion.completeExceptionally(e); + } + } + } + + // the "downReader" Subscriber which is passed to the constructor of SSLFlowDelegate. + // This subscriber receives the (decrypted) application data. This subscriber requests + // only one item (no restriction on how many bytes are received in this one item). + private static final class AppResponseReceiver implements Subscriber> { + private static final String debugTag = AppResponseReceiver.class.getSimpleName(); + + private final byte[] expectedData = new byte[1024]; // no significance of the size + + private final AtomicLong numBytesReceived; + private volatile Flow.Subscription subscription; + private final CompletableFuture completion; + private final CompletableFuture soleExpectedAppData; + private boolean receivedOneItem; + + private AppResponseReceiver(final CompletableFuture completion, + final CompletableFuture soleExpectedAppData) { + this.numBytesReceived = new AtomicLong(0); + this.soleExpectedAppData = soleExpectedAppData; + this.completion = completion; + Arrays.fill(expectedData, DATA_BYTE); + } + + @Override + public void onSubscribe(Flow.Subscription subscription) { + println(debugTag, "onSubscribe invoked"); + this.subscription = subscription; + subscription.request(1); // the sole item request this subscriber will make + } + + @Override + public void onNext(final List buffers) { + if (receivedOneItem) { + // don't throw an exception since that will go against the Subscriber's + // specification, instead complete the future exceptionally + completion.completeExceptionally(new AssertionError("onNext() called more than" + + " once, even though no request was made")); + return; + } + receivedOneItem = true; + // these buffers contain (decrypted) application data that the SSLFlowDelegate has + // forwarded to this subscriber + for (final ByteBuffer buf : buffers) { + final int numBytes = buf.remaining(); + // verify the content of the received application data + while (buf.hasRemaining()) { + final int size = Math.min(buf.remaining(), expectedData.length); + final byte[] actual = new byte[size]; + buf.get(actual); + // this is just convenience/performance optimization - instead of checking + // one byte at a time, we compare multiple bytes + final int index = Arrays.mismatch(expectedData, 0, size, actual, 0, size); + if (index != -1) { + final String errMsg = "Unexpected byte received: " + actual[index]; + println(debugTag, "Cancelling subscription due to error: " + errMsg); + subscription.cancel(); + completion.completeExceptionally(new AssertionError(errMsg)); + return; + } + } + numBytesReceived.addAndGet(numBytes); + } + println(debugTag, "Received " + numBytesReceived.get() + " bytes," + + " will not request any more data"); + soleExpectedAppData.complete(numBytesReceived.get()); + } + + @Override + public void onError(final Throwable throwable) { + completion.completeExceptionally(throwable); + } + + @Override + public void onComplete() { + final long n = numBytesReceived.get(); + println(debugTag, "Completed: received " + n + " bytes"); + } + } +} From f953b8a1daf823ea895aa99f99e2a10626e1397c Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 17 May 2024 07:45:55 +0000 Subject: [PATCH 277/298] 8312218: Print additional debug information when hitting assert(in_hash) Backport-of: 7cbab1f39636f3cf32f1276bc46feaa8107a14e6 --- src/hotspot/share/opto/compile.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 77fab1daaf7..22817951242 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -4907,7 +4907,16 @@ void Compile::remove_speculative_types(PhaseIterGVN &igvn) { const Type* t_no_spec = t->remove_speculative(); if (t_no_spec != t) { bool in_hash = igvn.hash_delete(n); - assert(in_hash, "node should be in igvn hash table"); +#ifdef ASSERT + if (!in_hash) { + tty->print_cr("current graph:"); + n->dump_bfs(MaxNodeLimit, nullptr, "S$"); + tty->cr(); + tty->print_cr("erroneous node:"); + n->dump(); + assert(false, "node should be in igvn hash table"); + } +#endif tn->set_type(t_no_spec); igvn.hash_insert(n); igvn._worklist.push(n); // give it a chance to go away From 9047499a46447986e27e81927e7be222ad6b8406 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 17 May 2024 07:54:12 +0000 Subject: [PATCH 278/298] 8331298: avoid alignment checks in UBSAN enabled build Backport-of: 60b61e588c1252b4b1fbc64d0f818a85670f7146 --- make/autoconf/jdk-options.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index 0797e823a58..58e04be8a99 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -502,7 +502,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER], [ # GCC reports lots of likely false positives for stringop-truncation and format-overflow. # Silence them for now. - UBSAN_CHECKS="-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-sanitize=shift-base" + UBSAN_CHECKS="-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-sanitize=shift-base -fno-sanitize=alignment" UBSAN_CFLAGS="$UBSAN_CHECKS -Wno-stringop-truncation -Wno-format-overflow -fno-omit-frame-pointer -DUNDEFINED_BEHAVIOR_SANITIZER" UBSAN_LDFLAGS="$UBSAN_CHECKS" UTIL_ARG_ENABLE(NAME: ubsan, DEFAULT: false, RESULT: UBSAN_ENABLED, From 2dc90b51516e0a04878dd0f5e9a6a704977a36f7 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Fri, 17 May 2024 08:05:35 +0000 Subject: [PATCH 279/298] 8320715: Improve the tests of test/hotspot/jtreg/compiler/intrinsics/float16 Backport-of: 5dcf3a56cb425c3419273636729d2d83603be0d2 --- .../float16/Binary16Conversion.java | 10 ++++-- .../float16/TestAllFloat16ToFloat.java | 32 +++++++++++++------ .../float16/TestConstFloat16ToFloat.java | 18 ++++++++--- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/test/hotspot/jtreg/compiler/intrinsics/float16/Binary16Conversion.java b/test/hotspot/jtreg/compiler/intrinsics/float16/Binary16Conversion.java index eeba614de4f..0541121c127 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/float16/Binary16Conversion.java +++ b/test/hotspot/jtreg/compiler/intrinsics/float16/Binary16Conversion.java @@ -309,7 +309,8 @@ private static int testRoundFloatToBinary16FullBinade() { f_prime_diff > f_prime_up_diff) { errors++; System.out.println("Round-to-nearest violation on converting " + - Float.toHexString(f) + "/" + Integer.toHexString(i) + " to binary16 and back: " + Integer.toHexString(0xffff & f_as_bin16) + " f_prime: " + Float.toHexString(f_prime)); + Float.toHexString(f) + "/" + Integer.toHexString(i) + " to binary16 and back: " + + Integer.toHexString(0xffff & f_as_bin16) + " f_prime: " + Float.toHexString(f_prime)); } } return errors; @@ -326,11 +327,14 @@ private static int testAlternativeImplementation() { ell++) { float f = Float.intBitsToFloat((int)ell); short s1 = Float.floatToFloat16(f); - short s2 = testAltFloatToFloat16(f); + short s2 = testAltFloatToFloat16(f); if (s1 != s2) { errors++; - System.out.println("Different conversion of float value " + Float.toHexString(f)); + System.out.println("Different conversion of float value (" + f + "/" + + Integer.toHexString(Float.floatToRawIntBits(f)) + "): " + + Integer.toHexString(s1 & 0xffff) + "(" + s1 + ")" + " != " + + Integer.toHexString(s2 & 0xffff) + "(" + s2 + ")"); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/float16/TestAllFloat16ToFloat.java b/test/hotspot/jtreg/compiler/intrinsics/float16/TestAllFloat16ToFloat.java index 4afda120709..492901f0046 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/float16/TestAllFloat16ToFloat.java +++ b/test/hotspot/jtreg/compiler/intrinsics/float16/TestAllFloat16ToFloat.java @@ -53,45 +53,59 @@ public static short testRoundTrip(short s) { return Float.floatToFloat16(Float.float16ToFloat(s)); } - public static void verify(short sVal, float fVal, short sRes) { + public static int verify(short sVal, float fVal, short sRes, String prefix) { + int errors = 0; if (sRes != sVal) { if (!Float.isNaN(fVal) || ((sRes & ~0x0200) != (sVal & ~0x0200)) ) { + errors++; String fVal_hex = Integer.toHexString(Float.floatToRawIntBits(fVal)); String sRes_hex = Integer.toHexString(sRes & 0xffff); String sVal_hex = Integer.toHexString(sVal & 0xffff); - throw new RuntimeException("Inconsistent result for Float.floatToFloat16(" + fVal + "/" + fVal_hex + "): " + sRes_hex + " != " + sVal_hex); + System.out.println(prefix + "Inconsistent result for Float.floatToFloat16(" + fVal + "/" + fVal_hex + "): " + + sRes_hex + "(" + sRes + ")" + " != " + sVal_hex + "(" + sVal + ")"); } } + return errors; } - public static void run() { + public static int run() { + int errors = 0; // Testing all float16 values. for (short sVal = Short.MIN_VALUE; sVal < Short.MAX_VALUE; ++sVal) { float fVal = Float.float16ToFloat(sVal); short sRes = testFloatToFloat16(fVal); - verify(sVal, fVal, sRes); + errors += verify(sVal, fVal, sRes, "testFloatToFloat16: "); float fRes = testFloat16ToFloat(sVal); if (!Float.isNaN(fRes) && fRes != fVal) { + errors++; String sVal_hex = Integer.toHexString(sVal & 0xffff); String fRes_hex = Integer.toHexString(Float.floatToRawIntBits(fRes)); String fVal_hex = Integer.toHexString(Float.floatToRawIntBits(fVal)); - throw new RuntimeException("Inconsistent result for Float.float16ToFloat(" + sVal_hex + "): " + fRes + "/" + fRes_hex + " != " + fVal + "/" + fVal_hex); + System.out.println("Non-NaN res: " + "Inconsistent result for Float.float16ToFloat(" + sVal_hex + "): " + + fRes + "/" + fRes_hex + " != " + fVal + "/" + fVal_hex); } sRes = testRoundTrip(sVal); - verify(sVal, fVal, sRes); + errors += verify(sVal, fVal, sRes, "testRoundTrip: "); if (Float.floatToFloat16(fRes) != Float.floatToFloat16(fVal)) { + errors++; String sVal_hex = Integer.toHexString(sVal & 0xffff); String sfRes_hex = Integer.toHexString(Float.floatToFloat16(fRes) & 0xffff); - String sfVal_hex = Integer.toHexString(Float.floatToFloat16(fVal)& 0xffff); - throw new RuntimeException("Inconsistent result for Float.float16ToFloat(" + sVal_hex + "): " + sfRes_hex + " != " + sfVal_hex); + String sfVal_hex = Integer.toHexString(Float.floatToFloat16(fVal) & 0xffff); + System.out.println("Float16 not equal: " + "Inconsistent result for Float.float16ToFloat(" + sVal_hex + "): " + + sfRes_hex + " != " + sfVal_hex); } } + return errors; } public static void main(String[] args) { + int errors = 0; // Run twice to trigger compilation for (int i = 0; i < 2; i++) { - run(); + errors += run(); + } + if (errors > 0) { + throw new RuntimeException(errors + " errors"); } } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/float16/TestConstFloat16ToFloat.java b/test/hotspot/jtreg/compiler/intrinsics/float16/TestConstFloat16ToFloat.java index 062e6804897..b4ba578c9f2 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/float16/TestConstFloat16ToFloat.java +++ b/test/hotspot/jtreg/compiler/intrinsics/float16/TestConstFloat16ToFloat.java @@ -127,7 +127,8 @@ public static void testFloatConst(short[] sRes) { sRes[13] = Float.floatToFloat16(BinaryF16.POSITIVE_INFINITY); } - public static void run() { + public static int run() { + int errors = 0; short s = Float.floatToFloat16(0.0f); // Load Float class // Testing constant float16 values. float[] fRes = new float[sCon.length]; @@ -135,10 +136,12 @@ public static void run() { for (int i = 0; i < sCon.length; i++) { float fVal = Float.float16ToFloat(sCon[i]); if (Float.floatToRawIntBits(fRes[i]) != Float.floatToRawIntBits(fVal)) { + errors++; String cVal_hex = Integer.toHexString(sCon[i] & 0xffff); String fRes_hex = Integer.toHexString(Float.floatToRawIntBits(fRes[i])); String fVal_hex = Integer.toHexString(Float.floatToRawIntBits(fVal)); - throw new RuntimeException("Inconsistent result for Float.float16ToFloat(" + cVal_hex + "): " + fRes[i] + "/" + fRes_hex + " != " + fVal + "/" + fVal_hex); + System.out.println("Inconsistent result for Float.float16ToFloat(" + cVal_hex + "): " + + fRes[i] + "/" + fRes_hex + " != " + fVal + "/" + fVal_hex); } } @@ -148,19 +151,26 @@ public static void run() { for (int i = 0; i < fCon.length; i++) { short sVal = Float.floatToFloat16(fCon[i]); if (sRes[i] != sVal) { + errors++; String cVal_hex = Integer.toHexString(Float.floatToRawIntBits(fCon[i])); String sRes_hex = Integer.toHexString(sRes[i] & 0xffff); String sVal_hex = Integer.toHexString(sVal & 0xffff); - throw new RuntimeException("Inconsistent result for Float.floatToFloat16(" + fCon[i] + "/" + cVal_hex + "): " + sRes_hex + " != " + sVal_hex); + System.out.println("Inconsistent result for Float.floatToFloat16(" + fCon[i] + "/" + cVal_hex + "): " + + sRes_hex + "(" + sRes + ")" + " != " + sVal_hex + "(" + sVal + ")"); } } + return errors; } public static void main(String[] args) { + int errors = 0; // Run twice to trigger compilation for (int i = 0; i < 2; i++) { - run(); + errors += run(); + } + if (errors > 0) { + throw new RuntimeException(errors + " errors"); } } } From ff295b7fc417d4ce690d70015a1633ded67eceaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Arias=20de=20Reyna?= Date: Fri, 17 May 2024 14:07:38 +0000 Subject: [PATCH 280/298] 8316138: Add GlobalSign 2 TLS root certificates Backport-of: 4083255440cfbf39b9683ea88a433d71ec6111e7 --- .../share/data/cacerts/globalsigne46 | 20 ++++++++++ .../share/data/cacerts/globalsignr46 | 38 +++++++++++++++++++ .../certification/CAInterop.java | 29 ++++++++++++++ .../security/lib/cacerts/VerifyCACerts.java | 10 +++-- 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/java.base/share/data/cacerts/globalsigne46 create mode 100644 src/java.base/share/data/cacerts/globalsignr46 diff --git a/src/java.base/share/data/cacerts/globalsigne46 b/src/java.base/share/data/cacerts/globalsigne46 new file mode 100644 index 00000000000..50c7dadefdd --- /dev/null +++ b/src/java.base/share/data/cacerts/globalsigne46 @@ -0,0 +1,20 @@ +Owner: CN=GlobalSign Root E46, O=GlobalSign nv-sa, C=BE +Issuer: CN=GlobalSign Root E46, O=GlobalSign nv-sa, C=BE +Serial number: 11d2bbba336ed4bce62468c50d841d98e843 +Valid from: Wed Mar 20 00:00:00 GMT 2019 until: Tue Mar 20 00:00:00 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- diff --git a/src/java.base/share/data/cacerts/globalsignr46 b/src/java.base/share/data/cacerts/globalsignr46 new file mode 100644 index 00000000000..80d7d92d4fb --- /dev/null +++ b/src/java.base/share/data/cacerts/globalsignr46 @@ -0,0 +1,38 @@ +Owner: CN=GlobalSign Root R46, O=GlobalSign nv-sa, C=BE +Issuer: CN=GlobalSign Root R46, O=GlobalSign nv-sa, C=BE +Serial number: 11d2bbb9d723189e405f0a9d2dd0df2567d1 +Valid from: Wed Mar 20 00:00:00 GMT 2019 until: Tue Mar 20 00:00:00 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 0b832366286..9f071bc1450 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -511,6 +511,28 @@ * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyroote1 DEFAULT */ +/* + * @test id=globalsignr46 + * @bug 8316138 + * @summary Interoperability tests with GlobalSign Root R46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignr46 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignr46 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignr46 CRL + */ + +/* + * @test id=globalsigne46 + * @bug 8316138 + * @summary Interoperability tests with GlobalSign Root E46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigne46 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigne46 OCSP + * @run main/othervm -Djava.security.debug=certpath CAInterop globalsigne46 CRL + */ + /** * Collection of certificate validation tests for interoperability with external CAs */ @@ -680,6 +702,13 @@ private CATestURLs getTestURLs(String alias) { new CATestURLs("https://valid.root-e1.certainly.com", "https://revoked.root-e1.certainly.com"); + case "globalsignr46" -> + new CATestURLs("https://valid.r46.roots.globalsign.com", + "https://revoked.r46.roots.globalsign.com"); + case "globalsigne46" -> + new CATestURLs("https://valid.e46.roots.globalsign.com", + "https://revoked.e46.roots.globalsign.com"); + default -> throw new RuntimeException("No test setup found for: " + alias); }; } diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 548024efc6c..83427f1a33a 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -29,7 +29,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 - * 8321408 + * 8321408 8316138 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -48,12 +48,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 108; + private static final int COUNT = 110; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "C4:A2:41:9E:B6:4D:77:26:AA:21:02:83:51:C7:88:21:66:1E:D8:88:4A:AC:84:D5:B0:15:0C:7C:C6:45:85:AF"; + = "BD:80:65:81:68:E5:6C:51:64:ED:B9:08:53:9F:BB:2F:D9:6C:5D:D4:06:D4:16:59:39:10:8E:F8:24:81:8B:78"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -278,6 +278,10 @@ public class VerifyCACerts { "77:B8:2C:D8:64:4C:43:05:F7:AC:C5:CB:15:6B:45:67:50:04:03:3D:51:C6:0C:62:02:A8:E0:C3:34:67:D3:A0"); put("certainlyroote1 [jdk]", "B4:58:5F:22:E4:AC:75:6A:4E:86:12:A1:36:1C:5D:9D:03:1A:93:FD:84:FE:BB:77:8F:A3:06:8B:0F:C4:2D:C2"); + put("globalsignr46 [jdk]", + "4F:A3:12:6D:8D:3A:11:D1:C4:85:5A:4F:80:7C:BA:D6:CF:91:9D:3A:5A:88:B0:3B:EA:2C:63:72:D9:3C:40:C9"); + put("globalsigne46 [jdk]", + "CB:B9:C4:4D:84:B8:04:3E:10:50:EA:31:A6:9F:51:49:55:D7:BF:D2:E2:C6:B4:93:01:01:9A:D6:1D:9F:50:58"); } }; From c44d4e936f82c502af5745cf1a6495045731b369 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Tue, 21 May 2024 09:56:22 +0000 Subject: [PATCH 281/298] 8321107: Add more test cases for JDK-8319372 Backport-of: ecd335d8f42757d332f217e220e1a9db8c48c8d6 --- .../TestTopCastIIOnUndetectedDeadPath4.java | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath4.java diff --git a/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath4.java b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath4.java new file mode 100644 index 00000000000..566295b844b --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath4.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id=JDK-8293941 + * @bug 8319372 8293941 + * @summary Tests that CastII are not dying anymore and breaking the graph due to control that is not removed + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:-RangeCheckElimination + * -Xcomp -XX:CompileOnly=compiler.c2.TestTopCastIIOnUndetectedDeadPath4::* + * compiler.c2.TestTopCastIIOnUndetectedDeadPath4 + */ + +/* + * @test id=JDK-8314111 + * @bug 8319372 8314111 + * @summary Tests that CastII are not dying anymore and breaking the graph due to control that is not removed + * @run main/othervm -Xcomp -XX:CompileOnly=compiler.c2.TestTopCastIIOnUndetectedDeadPath4::test* + * compiler.c2.TestTopCastIIOnUndetectedDeadPath4 + */ + +/* + * @test id=NoFlags + * @summary Tests that CastII are not dying anymore and breaking the graph due to control that is not removed + * @run main/othervm compiler.c2.TestTopCastIIOnUndetectedDeadPath4 + */ + +package compiler.c2; + +public class TestTopCastIIOnUndetectedDeadPath4 { + + static boolean bFld; + static int iArrFld[]; + static long lArrFld[]; + static double dArrFld[][]; + + public static void main(String[] strArr) { + for (int i = 0; i < 5000; i++) { + test8293941(); + test8314111_1(); + test8314111_2(); + } + } + + static void test8293941() { + int i16; + boolean b = false; + for (double d1 = 31.2; d1 < 72; d1++) { + for (i16 = (int) d1; i16 < 2; ++i16) { + iArrFld[i16] >>= 5; + dArrFld[i16 - 1][i16] = 3; + if (b) { + break; + } + lArrFld[i16] = 4; + } + switch (0) { + case 5: + b = b; + } + } + } + + static void test8314111_1() { + int i, i1 = 0, i28, i30 = 0, iArr[] = new int[10]; + boolean bArr[] = new boolean[10]; + i = 1; + while (++i < 5) { + try { + i1 = iArr[i - 1]; + i1 = 2 / i; + } catch (ArithmeticException a_e) { + } + if (bFld) { + switch (i) { + case 4: + for (i28 = 3; 100 > i28; i28++) { + i1 -= i28; + } + if ((i30 -= 3) > 0) { + switch (i30) { + case 4: + bArr[i - 1] = bFld; + iArr[i] = 6; + } + } + } + } + } + } + + static void test8314111_2() { + int iArr[] = new int[1000]; + boolean bArr[] = new boolean[1000]; + int x = 0; + int i = 1; + while (++i < 5) { + try { + x = iArr[i - 1]; + x = 2 / i; + } catch (ArithmeticException a_e) { + } + if (bFld) { + x++; + bArr[i - 1] = false; + iArr[i] = 0; + } + } + } +} + +class Foo { + public static void empty() { + } +} From 8ff816356a313e1e0fefd3b3737c73b29b56e70f Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Tue, 21 May 2024 20:19:51 +0000 Subject: [PATCH 282/298] 8331466: Problemlist serviceability/dcmd/gc/RunFinalizationTest.java on generic-all Backport-of: 440782e0160f867f08afbec0abf48d557a522c72 --- test/hotspot/jtreg/ProblemList.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 3264c682882..e43d968fcfa 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -124,7 +124,7 @@ serviceability/sa/TestRevPtrsForInvokeDynamic.java 8241235 generic-all serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java 8286836 generic-all -serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64,aix-ppc64 +serviceability/dcmd/gc/RunFinalizationTest.java 8227120 generic-all serviceability/sa/ClhsdbCDSCore.java 8294316,8267433 macosx-x64 serviceability/sa/ClhsdbFindPC.java#xcomp-core 8294316,8267433 macosx-x64 From a1e0c5db7407bc7d58aa55f64e3f813f2eccc6ea Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 21 May 2024 20:38:56 +0000 Subject: [PATCH 283/298] 8332253: Linux arm32 build fails after 8292591 Backport-of: 95f79c678737fb8de9ed45c516761d4d818869ef --- src/hotspot/os/linux/systemMemoryBarrier_linux.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp index 5135ffefc45..51397b139d8 100644 --- a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp +++ b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp @@ -41,6 +41,8 @@ #define SYS_membarrier 365 #elif defined(AARCH64) #define SYS_membarrier 283 + #elif defined(ARM32) + #define SYS_membarrier 389 #elif defined(ALPHA) #define SYS_membarrier 517 #else From acff39d922f588dc56ade4369ad11cf717911dec Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 23 May 2024 02:00:35 +0000 Subject: [PATCH 284/298] 8319338: tools/jpackage/share/RuntimeImageTest.java fails with -XX:+UseZGC Backport-of: e9eb8b98f4dd949c8a0f501189471e11b837d936 --- test/jdk/tools/jpackage/share/RuntimeImageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/tools/jpackage/share/RuntimeImageTest.java b/test/jdk/tools/jpackage/share/RuntimeImageTest.java index 3d66a163c07..3b57536213b 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageTest.java @@ -47,7 +47,7 @@ * @build jdk.jpackage.test.* * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal * @compile RuntimeImageTest.java - * @run main/othervm/timeout=1400 -Xmx512m jdk.jpackage.test.Main + * @run main/othervm/timeout=1400 jdk.jpackage.test.Main * --jpt-run=RuntimeImageTest */ From cdfe2f44f672d7d2b2bef96552336cc30932197d Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Thu, 23 May 2024 08:47:16 +0000 Subject: [PATCH 285/298] 8329840: Fix ZPhysicalMemorySegment::_end type Backport-of: b4ddddeff1ce4293c88a9ab8ad3ca9d3b0e2352e --- src/hotspot/share/gc/z/zAddress.inline.hpp | 4 ++ src/hotspot/share/gc/z/zPhysicalMemory.hpp | 8 ++-- .../share/gc/z/zPhysicalMemory.inline.hpp | 6 +-- .../gtest/gc/z/test_zPhysicalMemory.cpp | 45 +++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/z/zAddress.inline.hpp b/src/hotspot/share/gc/z/zAddress.inline.hpp index 7088a71ef7b..39fa7b6e0b3 100644 --- a/src/hotspot/share/gc/z/zAddress.inline.hpp +++ b/src/hotspot/share/gc/z/zAddress.inline.hpp @@ -133,6 +133,10 @@ inline bool operator<(zoffset first, zoffset_end second) { return untype(first) < untype(second); } +inline bool operator<=(zoffset_end first, zoffset second) { + return untype(first) <= untype(second); +} + inline bool operator>(zoffset first, zoffset_end second) { return untype(first) > untype(second); } diff --git a/src/hotspot/share/gc/z/zPhysicalMemory.hpp b/src/hotspot/share/gc/z/zPhysicalMemory.hpp index 2244732a146..e5e0a19d1c5 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemory.hpp +++ b/src/hotspot/share/gc/z/zPhysicalMemory.hpp @@ -32,16 +32,16 @@ class ZPhysicalMemorySegment : public CHeapObj { private: - zoffset _start; - zoffset _end; - bool _committed; + zoffset _start; + zoffset_end _end; + bool _committed; public: ZPhysicalMemorySegment(); ZPhysicalMemorySegment(zoffset start, size_t size, bool committed); zoffset start() const; - zoffset end() const; + zoffset_end end() const; size_t size() const; bool is_committed() const; diff --git a/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp b/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp index cbfd3842b35..744c68daa7e 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp +++ b/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp @@ -31,19 +31,19 @@ inline ZPhysicalMemorySegment::ZPhysicalMemorySegment() : _start(zoffset(UINTPTR_MAX)), - _end(zoffset(UINTPTR_MAX)), + _end(zoffset_end(UINTPTR_MAX)), _committed(false) {} inline ZPhysicalMemorySegment::ZPhysicalMemorySegment(zoffset start, size_t size, bool committed) : _start(start), - _end(start + size), + _end(to_zoffset_end(start, size)), _committed(committed) {} inline zoffset ZPhysicalMemorySegment::start() const { return _start; } -inline zoffset ZPhysicalMemorySegment::end() const { +inline zoffset_end ZPhysicalMemorySegment::end() const { return _end; } diff --git a/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp b/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp index 69861416928..6e44993986b 100644 --- a/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp +++ b/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp @@ -25,7 +25,27 @@ #include "gc/z/zPhysicalMemory.inline.hpp" #include "unittest.hpp" +class ZAddressOffsetMaxSetter { +private: + const size_t _old_max; + const size_t _old_mask; + +public: + ZAddressOffsetMaxSetter() + : _old_max(ZAddressOffsetMax), + _old_mask(ZAddressOffsetMask) { + ZAddressOffsetMax = size_t(16) * G * 1024; + ZAddressOffsetMask = ZAddressOffsetMax - 1; + } + ~ZAddressOffsetMaxSetter() { + ZAddressOffsetMax = _old_max; + ZAddressOffsetMask = _old_mask; + } +}; + TEST(ZPhysicalMemoryTest, copy) { + ZAddressOffsetMaxSetter setter; + const ZPhysicalMemorySegment seg0(zoffset(0), 100, true); const ZPhysicalMemorySegment seg1(zoffset(200), 100, true); @@ -52,6 +72,8 @@ TEST(ZPhysicalMemoryTest, copy) { } TEST(ZPhysicalMemoryTest, add) { + ZAddressOffsetMaxSetter setter; + const ZPhysicalMemorySegment seg0(zoffset(0), 1, true); const ZPhysicalMemorySegment seg1(zoffset(1), 1, true); const ZPhysicalMemorySegment seg2(zoffset(2), 1, true); @@ -114,6 +136,8 @@ TEST(ZPhysicalMemoryTest, add) { } TEST(ZPhysicalMemoryTest, remove) { + ZAddressOffsetMaxSetter setter; + ZPhysicalMemory pmem; pmem.add_segment(ZPhysicalMemorySegment(zoffset(10), 10, true)); @@ -130,6 +154,8 @@ TEST(ZPhysicalMemoryTest, remove) { } TEST(ZPhysicalMemoryTest, split) { + ZAddressOffsetMaxSetter setter; + ZPhysicalMemory pmem; pmem.add_segment(ZPhysicalMemorySegment(zoffset(0), 10, true)); @@ -158,6 +184,8 @@ TEST(ZPhysicalMemoryTest, split) { } TEST(ZPhysicalMemoryTest, split_committed) { + ZAddressOffsetMaxSetter setter; + ZPhysicalMemory pmem0; pmem0.add_segment(ZPhysicalMemorySegment(zoffset(0), 10, true)); pmem0.add_segment(ZPhysicalMemorySegment(zoffset(10), 10, false)); @@ -172,3 +200,20 @@ TEST(ZPhysicalMemoryTest, split_committed) { EXPECT_EQ(pmem1.nsegments(), 2); EXPECT_EQ(pmem1.size(), 20u); } + +TEST(ZPhysicalMemoryTest, limits) { + ZAddressOffsetMaxSetter setter; + + const size_t HalfZAddressOffsetMax = ZAddressOffsetMax >> 1; + ZPhysicalMemory pmem0; + pmem0.add_segment(ZPhysicalMemorySegment(zoffset(0), HalfZAddressOffsetMax, true)); + pmem0.add_segment(ZPhysicalMemorySegment(zoffset(HalfZAddressOffsetMax), HalfZAddressOffsetMax, false)); + EXPECT_EQ(pmem0.nsegments(), 2); + EXPECT_EQ(pmem0.size(), ZAddressOffsetMax); + + ZPhysicalMemory pmem1 = pmem0.split_committed(); + EXPECT_EQ(pmem0.nsegments(), 1); + EXPECT_EQ(pmem0.size(), HalfZAddressOffsetMax); + EXPECT_EQ(pmem1.nsegments(), 1); + EXPECT_EQ(pmem1.size(), HalfZAddressOffsetMax); +} From fe4a2ae57072126f674b32c8e7cd719faf317c60 Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Thu, 23 May 2024 08:47:30 +0000 Subject: [PATCH 286/298] 8329109: Threads::print_on() tries to print CPU time for terminated GC threads Backport-of: c1cfb43d8de8d0eed01b9bb6aa1202dc7cbff007 --- src/hotspot/share/runtime/threads.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index ef5ccec9ec8..373d4afd4dd 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -1317,10 +1317,7 @@ void Threads::print_on(outputStream* st, bool print_stacks, } PrintOnClosure cl(st); - cl.do_thread(VMThread::vm_thread()); - Universe::heap()->gc_threads_do(&cl); - cl.do_thread(WatcherThread::watcher_thread()); - cl.do_thread(AsyncLogWriter::instance()); + non_java_threads_do(&cl); st->flush(); } From 201e663ee2714ae848c8abbbe51684f50dc2defc Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 23 May 2024 09:21:16 +0000 Subject: [PATCH 287/298] 8320681: [macos] Test tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java timed out on macOS Backport-of: a657aa38a56056211a9d2773b30e8fe1a89c128e --- .../tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java b/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java index b3cefa7d38f..8b1cec04ab9 100644 --- a/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java +++ b/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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,7 +39,7 @@ * @build MacAppStoreJLinkOptionsTest * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "mac") - * @run main/othervm -Xmx512m jdk.jpackage.test.Main + * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MacAppStoreJLinkOptionsTest */ public class MacAppStoreJLinkOptionsTest { From a4d2a5aaca511e66e41524d4037f930e36e323e1 Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Thu, 23 May 2024 09:21:34 +0000 Subject: [PATCH 288/298] 8312194: test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java cannot handle empty modules Backport-of: e7c83ea948f8b2cd7caf7e59d3cf6b087807dba7 --- .../ctw/modules/jdk_crypto_ec.java | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java diff --git a/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java b/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java deleted file mode 100644 index 09e173b4801..00000000000 --- a/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary run CTW for all classes from jdk.crypto.ec module - * - * @library /test/lib / /testlibrary/ctw/src - * @modules java.base/jdk.internal.access - * java.base/jdk.internal.jimage - * java.base/jdk.internal.misc - * java.base/jdk.internal.reflect - * @modules jdk.crypto.ec - * - * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run driver/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.crypto.ec - */ From 9035981eca6df3a102c76453019d82a145756933 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Thu, 23 May 2024 09:24:54 +0000 Subject: [PATCH 289/298] 8321812: Update GC tests to use execute[Limited]TestJava Reviewed-by: mbaesken Backport-of: 1d1cd32bc355a33448d8f15555e142570bb49c21 --- test/hotspot/jtreg/gc/TestAgeOutput.java | 3 +- test/hotspot/jtreg/gc/TestAllocateHeapAt.java | 3 +- .../jtreg/gc/TestAllocateHeapAtError.java | 3 +- .../jtreg/gc/TestAllocateHeapAtMultiple.java | 3 +- .../jtreg/gc/TestCardTablePageCommits.java | 3 +- .../hotspot/jtreg/gc/TestNumWorkerOutput.java | 3 +- .../jtreg/gc/TestPLABAdaptToMinTLABSize.java | 4 +- test/hotspot/jtreg/gc/TestSmallHeap.java | 3 +- .../jtreg/gc/TestVerifyDuringStartup.java | 3 +- test/hotspot/jtreg/gc/TestVerifySilently.java | 3 +- test/hotspot/jtreg/gc/TestVerifySubSet.java | 3 +- .../jtreg/gc/arguments/GCArguments.java | 17 +++ .../gc/arguments/TestAggressiveHeap.java | 4 +- .../arguments/TestCompressedClassFlags.java | 12 +- .../gc/arguments/TestDisableDefaultGC.java | 15 ++- .../TestG1ConcMarkStepDurationMillis.java | 3 +- .../TestG1ConcRefinementThreads.java | 3 +- .../gc/arguments/TestG1HeapRegionSize.java | 3 +- .../gc/arguments/TestG1PercentageOptions.java | 3 +- .../jtreg/gc/arguments/TestG1RemSetFlags.java | 3 +- .../jtreg/gc/arguments/TestHeapFreeRatio.java | 3 +- .../TestInitialTenuringThreshold.java | 6 +- .../gc/arguments/TestMaxHeapSizeTools.java | 9 +- .../TestMaxMinHeapFreeRatioFlags.java | 6 +- .../jtreg/gc/arguments/TestMaxNewSize.java | 3 +- .../jtreg/gc/arguments/TestMaxRAMFlags.java | 6 +- .../TestMinAndInitialSurvivorRatioFlags.java | 3 +- .../jtreg/gc/arguments/TestNewRatioFlag.java | 3 +- .../jtreg/gc/arguments/TestNewSizeFlags.java | 8 +- .../arguments/TestNewSizeThreadIncrease.java | 15 ++- .../gc/arguments/TestObjectTenuringFlags.java | 3 +- .../gc/arguments/TestParallelGCThreads.java | 9 +- .../gc/arguments/TestParallelRefProc.java | 4 +- .../gc/arguments/TestSelectDefaultGC.java | 3 +- ...tSmallInitialHeapWithLargePageAndNUMA.java | 3 +- .../gc/arguments/TestSurvivorRatioFlag.java | 3 +- .../TestTargetSurvivorRatioFlag.java | 6 +- .../TestUnrecognizedVMOptionsHandling.java | 9 +- .../TestUseCompressedOopsErgoTools.java | 6 +- .../TestUseCompressedOopsFlagsWithUlimit.java | 5 +- .../gc/arguments/TestUseNUMAInterleaving.java | 3 +- .../TestVerifyBeforeAndAfterGCFlags.java | 3 +- .../TestG1ClassUnloadingHWM.java | 3 +- .../jtreg/gc/epsilon/TestDieDefault.java | 6 +- .../jtreg/gc/epsilon/TestDieWithHeapDump.java | 3 +- .../jtreg/gc/epsilon/TestDieWithOnError.java | 6 +- .../TestDynamicNumberOfGCThreads.java | 8 +- .../TestInitialGCThreadLogging.java | 4 +- test/hotspot/jtreg/gc/g1/Test2GbHeap.java | 3 +- .../g1/TestEagerReclaimHumongousRegions.java | 4 +- ...rReclaimHumongousRegionsClearMarkBits.java | 3 +- .../TestEagerReclaimHumongousRegionsLog.java | 3 +- ...tEagerReclaimHumongousRegionsWithRefs.java | 4 +- .../jtreg/gc/g1/TestEvacuationFailure.java | 19 ++-- .../jtreg/gc/g1/TestG1SkipCompaction.java | 3 +- ...stG1TraceEagerReclaimHumongousObjects.java | 18 ++- .../jtreg/gc/g1/TestGCLogMessages.java | 104 ++++++++---------- .../g1/TestHumongousAllocConcurrentStart.java | 3 +- .../TestHumongousAllocNearlyFullRegion.java | 3 +- .../gc/g1/TestHumongousCodeCacheRoots.java | 3 +- .../g1/TestHumongousConcurrentStartUndo.java | 3 +- .../gc/g1/TestLargePageUseForAuxMemory.java | 9 +- .../jtreg/gc/g1/TestLargePageUseForHeap.java | 31 +++--- .../jtreg/gc/g1/TestMarkStackSizes.java | 4 +- .../jtreg/gc/g1/TestMixedGCLiveThreshold.java | 4 +- .../jtreg/gc/g1/TestOneEdenRegionAfterGC.java | 3 +- test/hotspot/jtreg/gc/g1/TestPLABOutput.java | 3 +- .../jtreg/gc/g1/TestPLABSizeBounds.java | 3 +- .../jtreg/gc/g1/TestPeriodicLogMessages.java | 22 ++-- .../g1/TestPrintRegionRememberedSetInfo.java | 3 +- .../jtreg/gc/g1/TestRemsetLoggingThreads.java | 14 +-- .../jtreg/gc/g1/TestRemsetLoggingTools.java | 3 +- .../gc/g1/TestSharedArchiveWithPreTouch.java | 9 +- .../jtreg/gc/g1/TestShrinkAuxiliaryData.java | 3 +- .../gc/g1/TestShrinkDefragmentedHeap.java | 3 +- .../gc/g1/TestSkipRebuildRemsetPhase.java | 21 ++-- .../hotspot/jtreg/gc/g1/TestVerifyGCType.java | 5 +- .../ClassLoaderGenerator.java | 4 +- .../gc/g1/humongousObjects/G1SampleClass.java | 5 +- .../TestHumongousClassLoader.java | 4 +- .../TestHumongousNonArrayAllocation.java | 3 +- .../jtreg/gc/g1/mixedgc/TestLogging.java | 3 +- .../gc/g1/numa/TestG1NUMATouchRegions.java | 3 +- .../gc/logging/TestDeprecatedPrintFlags.java | 12 +- test/hotspot/jtreg/gc/logging/TestGCId.java | 6 +- .../jtreg/gc/logging/TestMetaSpaceLog.java | 24 ++-- .../jtreg/gc/logging/TestPrintReferences.java | 24 ++-- .../CompressedClassSpaceSizeInJmapHeap.java | 5 +- .../gc/metaspace/TestMetaspaceSizeFlags.java | 3 +- .../gc/metaspace/TestSizeTransitions.java | 3 +- .../jtreg/gc/serial/HeapChangeLogging.java | 3 +- .../jtreg/gc/shenandoah/TestEvilSyncBug.java | 3 +- .../jtreg/gc/shenandoah/TestJcmdHeapDump.java | 7 +- .../gc/shenandoah/TestObjItrWithHeapDump.java | 3 +- .../jtreg/gc/shenandoah/TestPeriodicGC.java | 3 +- .../gc/shenandoah/oom/TestAllocLargeObj.java | 6 +- .../oom/TestAllocLargerThanHeap.java | 6 +- .../gc/shenandoah/oom/TestAllocSmallObj.java | 6 +- .../shenandoah/oom/TestClassLoaderLeak.java | 4 +- .../gc/shenandoah/oom/TestThreadFailure.java | 3 +- .../options/TestArgumentRanges.java | 21 ++-- .../options/TestClassUnloadingArguments.java | 3 +- .../gc/shenandoah/options/TestExplicitGC.java | 15 +-- .../options/TestExplicitGCNoConcurrent.java | 3 +- .../options/TestHeuristicsUnlock.java | 9 +- .../options/TestHumongousThresholdArgs.java | 9 +- .../options/TestLoopMiningArguments.java | 3 +- .../gc/shenandoah/options/TestModeUnlock.java | 9 +- .../options/TestRegionSizeArgs.java | 48 +++----- .../options/TestSelectiveBarrierFlags.java | 3 +- .../options/TestSoftMaxHeapSize.java | 9 +- .../shenandoah/options/TestThreadCounts.java | 3 +- .../options/TestThreadCountsOverride.java | 6 +- .../options/TestWrongBarrierDisable.java | 6 +- .../options/TestWrongBarrierEnable.java | 6 +- .../stress/TestReclaimStringsLeaksMemory.java | 4 +- .../gc/stress/TestStressG1Humongous.java | 3 +- .../jtreg/gc/stress/TestStressG1Uncommit.java | 3 +- .../TestStringDeduplicationTools.java | 3 +- .../hotspot/jtreg/gc/testlibrary/Helpers.java | 15 ++- test/hotspot/jtreg/gc/whitebox/TestWBGC.java | 3 +- .../jtreg/gc/x/TestAllocateHeapAt.java | 22 ++-- .../jtreg/gc/x/TestPageCacheFlush.java | 22 ++-- test/hotspot/jtreg/gc/x/TestSmallHeap.java | 20 ++-- .../jtreg/gc/z/TestAllocateHeapAt.java | 22 ++-- .../jtreg/gc/z/TestPageCacheFlush.java | 22 ++-- test/hotspot/jtreg/gc/z/TestSmallHeap.java | 20 ++-- ...stZForceDiscontiguousHeapReservations.java | 22 ++-- test/hotspot/jtreg/gc/z/TestZNMT.java | 30 ++--- 129 files changed, 439 insertions(+), 627 deletions(-) diff --git a/test/hotspot/jtreg/gc/TestAgeOutput.java b/test/hotspot/jtreg/gc/TestAgeOutput.java index 084279bcda9..c83f2ba511f 100644 --- a/test/hotspot/jtreg/gc/TestAgeOutput.java +++ b/test/hotspot/jtreg/gc/TestAgeOutput.java @@ -66,7 +66,7 @@ public static void checkPattern(String pattern, String what) throws Exception { } public static void runTest(String gcArg) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-XX:+UnlockExperimentalVMOptions", "-XX:+UnlockDiagnosticVMOptions", @@ -75,7 +75,6 @@ public static void runTest(String gcArg) throws Exception { "-Xmx10M", "-Xlog:gc+age=trace", GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java index 8daf0bbcdc7..d1e96751ab8 100644 --- a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java +++ b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java @@ -36,13 +36,12 @@ public class TestAllocateHeapAt { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeTestJava( "-XX:AllocateHeapAt=" + System.getProperty("test.dir", "."), "-Xlog:gc+heap=info", "-Xmx32m", "-Xms32m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println("Output:\n" + output.getOutput()); diff --git a/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java b/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java index 372437b8898..28e2f71d09d 100644 --- a/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java +++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java @@ -45,13 +45,12 @@ public static void main(String args[]) throws Exception { f = new File(test_dir, UUID.randomUUID().toString()); } while(f.exists()); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeTestJava( "-XX:AllocateHeapAt=" + f.getName(), "-Xlog:gc+heap=info", "-Xmx32m", "-Xms32m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println("Output:\n" + output.getOutput()); diff --git a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java index b2d2f1e429d..d8d1b4bd88d 100644 --- a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java +++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java @@ -60,8 +60,7 @@ public static void main(String args[]) throws Exception { "-Xlog:gc+heap=info", "-version"}); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(flags); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeTestJava(flags); System.out.println("Output:\n" + output.getOutput()); diff --git a/test/hotspot/jtreg/gc/TestCardTablePageCommits.java b/test/hotspot/jtreg/gc/TestCardTablePageCommits.java index c468a771076..6c10dd0100e 100644 --- a/test/hotspot/jtreg/gc/TestCardTablePageCommits.java +++ b/test/hotspot/jtreg/gc/TestCardTablePageCommits.java @@ -42,12 +42,11 @@ public static void main(String args[]) throws Exception { // because of 8kB pages, assume 4 KB pages for all other CPUs. String Xmx = "-Xmx4m"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( Xmx, "-XX:NativeMemoryTracking=detail", "-XX:+UseParallelGC", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/TestNumWorkerOutput.java b/test/hotspot/jtreg/gc/TestNumWorkerOutput.java index 81209f73929..8b224d22010 100644 --- a/test/hotspot/jtreg/gc/TestNumWorkerOutput.java +++ b/test/hotspot/jtreg/gc/TestNumWorkerOutput.java @@ -58,7 +58,7 @@ public static void checkPatternOnce(String pattern, String what) throws Exceptio } public static void runTest(String gcArg) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-XX:+UnlockExperimentalVMOptions", "-XX:+UnlockDiagnosticVMOptions", @@ -67,7 +67,6 @@ public static void runTest(String gcArg) throws Exception { "-Xmx10M", "-XX:+PrintGCDetails", GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java b/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java index c5c4854946d..8dfefcb7d95 100644 --- a/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java +++ b/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java @@ -48,9 +48,7 @@ private static void runTest(boolean shouldSucceed, String... extraArgs) throws E Collections.addAll(testArguments, extraArgs); testArguments.add("-version"); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(testArguments); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeTestJava(testArguments); System.out.println(output.getStderr()); diff --git a/test/hotspot/jtreg/gc/TestSmallHeap.java b/test/hotspot/jtreg/gc/TestSmallHeap.java index a9b32eb81c8..fd6c5860f01 100644 --- a/test/hotspot/jtreg/gc/TestSmallHeap.java +++ b/test/hotspot/jtreg/gc/TestSmallHeap.java @@ -96,12 +96,11 @@ public static void main(String[] args) throws Exception { private static void verifySmallHeapSize(String gc, long expectedMaxHeap) throws Exception { long minMaxHeap = 4 * 1024 * 1024; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( gc, "-Xmx" + minMaxHeap, "-XX:+PrintFlagsFinal", VerifyHeapSize.class.getName()); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(0); expectedMaxHeap = Math.max(expectedMaxHeap, minMaxHeap); diff --git a/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java b/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java index 4ad9f9675d9..e651295d5b5 100644 --- a/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java +++ b/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java @@ -37,13 +37,12 @@ public class TestVerifyDuringStartup { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeTestJava( "-XX:-UseTLAB", "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyDuringStartup", "-Xlog:gc+verify=debug", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println("Output:\n" + output.getOutput()); diff --git a/test/hotspot/jtreg/gc/TestVerifySilently.java b/test/hotspot/jtreg/gc/TestVerifySilently.java index b7b07a1eb8e..2f245f5eed2 100644 --- a/test/hotspot/jtreg/gc/TestVerifySilently.java +++ b/test/hotspot/jtreg/gc/TestVerifySilently.java @@ -57,8 +57,7 @@ private static OutputAnalyzer runTest(boolean verifySilently) throws Exception { "-XX:+VerifyAfterGC", (verifySilently ? "-Xlog:gc":"-Xlog:gc+verify=debug"), TestVerifySilentlyRunSystemGC.class.getName()}); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(vmOpts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(vmOpts); System.out.println("Output:\n" + output.getOutput()); return output; diff --git a/test/hotspot/jtreg/gc/TestVerifySubSet.java b/test/hotspot/jtreg/gc/TestVerifySubSet.java index 5aa8cc3eb13..08cddc74a00 100644 --- a/test/hotspot/jtreg/gc/TestVerifySubSet.java +++ b/test/hotspot/jtreg/gc/TestVerifySubSet.java @@ -59,8 +59,7 @@ private static OutputAnalyzer runTest(String subset) throws Exception { "-Xlog:gc+verify=debug", "-XX:VerifySubSet="+subset, TestVerifySubSetRunSystemGC.class.getName()}); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(vmOpts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(vmOpts); System.out.println("Output:\n" + output.getOutput()); return output; diff --git a/test/hotspot/jtreg/gc/arguments/GCArguments.java b/test/hotspot/jtreg/gc/arguments/GCArguments.java index c59a14954bf..3908ce17966 100644 --- a/test/hotspot/jtreg/gc/arguments/GCArguments.java +++ b/test/hotspot/jtreg/gc/arguments/GCArguments.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.List; import jdk.test.lib.Platform; +import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; /** @@ -81,4 +82,20 @@ static public ProcessBuilder createTestJavaProcessBuilder(List arguments static public ProcessBuilder createTestJavaProcessBuilder(String... arguments) { return ProcessTools.createTestJavaProcessBuilder(withDefaults(arguments)); } + + static public OutputAnalyzer executeLimitedTestJava(List arguments) throws Exception { + return executeLimitedTestJava(arguments.toArray(String[]::new)); + } + + static public OutputAnalyzer executeLimitedTestJava(String... arguments) throws Exception { + return ProcessTools.executeLimitedTestJava(withDefaults(arguments)); + } + + static public OutputAnalyzer executeTestJava(List arguments) throws Exception { + return executeTestJava(arguments.toArray(String[]::new)); + } + + static public OutputAnalyzer executeTestJava(String... arguments) throws Exception { + return ProcessTools.executeTestJava(withDefaults(arguments)); + } } diff --git a/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java b/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java index 2ce13fbbfd4..2a246bcf3a7 100644 --- a/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java +++ b/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java @@ -65,11 +65,9 @@ public static void main(String args[]) throws Exception { " *bool +UseParallelGC *= *true +\\{product\\} *\\{command line\\}"; private static void testFlag() throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeTestJava( option, heapSizeOption, "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); String value = output.firstMatch(parallelGCPattern); diff --git a/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java b/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java index 0b6dce0fc0e..c1975d6b692 100644 --- a/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java @@ -41,17 +41,13 @@ public class TestCompressedClassFlags { public static void main(String[] args) throws Exception { if (Platform.is64bit()) { - OutputAnalyzer output = runJava("-XX:CompressedClassSpaceSize=1g", - "-XX:-UseCompressedClassPointers", - "-version"); + OutputAnalyzer output = GCArguments.executeTestJava( + "-XX:CompressedClassSpaceSize=1g", + "-XX:-UseCompressedClassPointers", + "-version"); output.shouldContain("warning"); output.shouldNotContain("error"); output.shouldHaveExitValue(0); } } - - private static OutputAnalyzer runJava(String ... args) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(args); - return new OutputAnalyzer(pb.start()); - } } diff --git a/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java b/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java index e8e4552da01..0828622fa7a 100644 --- a/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java +++ b/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java @@ -40,14 +40,13 @@ public class TestDisableDefaultGC { public static void main(String[] args) throws Exception { // Start VM, disabling all possible default GCs - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder("-XX:-UseSerialGC", - "-XX:-UseParallelGC", - "-XX:-UseG1GC", - "-XX:-UseZGC", - "-XX:+UnlockExperimentalVMOptions", - "-XX:-UseShenandoahGC", - "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava("-XX:-UseSerialGC", + "-XX:-UseParallelGC", + "-XX:-UseG1GC", + "-XX:-UseZGC", + "-XX:+UnlockExperimentalVMOptions", + "-XX:-UseShenandoahGC", + "-version"); output.shouldMatch("Garbage collector not selected"); output.shouldHaveExitValue(1); } diff --git a/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java b/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java index 21a4eddb410..c5f595e7a1a 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java @@ -78,8 +78,7 @@ private static void runG1ConcMarkStepDurationMillisTest(String expectedValue, in Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:G1ConcMarkStepDurationMillis="+expectedValue, "-XX:+PrintFlagsFinal", "-version"); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(vmOpts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(vmOpts); output.shouldHaveExitValue(expectedResult == PASS ? 0 : 1); String stdout = output.getStdout(); diff --git a/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java b/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java index 91be97782f5..f82d2b31711 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java @@ -69,8 +69,7 @@ private static void runG1ConcRefinementThreadsTest(String[] passedOpts, } Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:+PrintFlagsFinal", "-version"); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(vmOpts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(vmOpts); output.shouldHaveExitValue(0); String stdout = output.getStdout(); diff --git a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java index 0d63dec0c26..5ecd27e24e8 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java @@ -53,8 +53,7 @@ private static void checkG1HeapRegionSize(String[] flags, int expectedValue, int flagList.add("-XX:+PrintFlagsFinal"); flagList.add("-version"); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(flagList); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(flagList); output.shouldHaveExitValue(exitValue); if (exitValue == 0) { diff --git a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java index 875e995374a..e8ee2598c9a 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java @@ -63,8 +63,7 @@ private static final class OptionDescription { }; private static void check(String flag, boolean is_valid) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder("-XX:+UseG1GC", flag, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava("-XX:+UseG1GC", flag, "-version"); if (is_valid) { output.shouldHaveExitValue(0); } else { diff --git a/test/hotspot/jtreg/gc/arguments/TestG1RemSetFlags.java b/test/hotspot/jtreg/gc/arguments/TestG1RemSetFlags.java index 84483f39272..63b9d782c06 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1RemSetFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1RemSetFlags.java @@ -48,8 +48,7 @@ private static void checkG1RemSetFlags(String[] flags, int exitValue) throws Exc flagList.add("-XX:+PrintFlagsFinal"); flagList.add("-version"); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(flagList); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(flagList); output.shouldHaveExitValue(exitValue); } diff --git a/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java b/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java index 19ecb181418..c8eaa0f46e3 100644 --- a/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java +++ b/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java @@ -48,11 +48,10 @@ enum Validation { } private static void testMinMaxFreeRatio(String min, String max, Validation type) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeTestJava( "-Xminf" + min, "-Xmaxf" + max, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (type) { case VALID: diff --git a/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java b/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java index 7bf78a001bf..07a9065cee1 100644 --- a/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java +++ b/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java @@ -41,14 +41,13 @@ public class TestInitialTenuringThreshold { public static void runWithThresholds(int initial, int max, boolean shouldfail) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeTestJava( "-XX:+UseParallelGC", "-XX:InitialTenuringThreshold=" + String.valueOf(initial), "-XX:MaxTenuringThreshold=" + String.valueOf(max), "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); if (shouldfail) { output.shouldHaveExitValue(1); } else { @@ -58,14 +57,13 @@ public static void runWithThresholds(int initial, int max, boolean shouldfail) t public static void main(String args[]) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeTestJava( // some value below the default value of InitialTenuringThreshold of 7 "-XX:+UseParallelGC", "-XX:MaxTenuringThreshold=1", "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); // successful tests runWithThresholds(0, 10, false); diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java b/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java index 3a5d472f9f8..5af005063c1 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java +++ b/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java @@ -115,9 +115,8 @@ private static long align_up(long value, long alignment) { } private static void getNewOldSize(String gcflag, long[] values) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(gcflag, + OutputAnalyzer output = GCArguments.executeTestJava(gcflag, "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); String stdout = output.getStdout(); @@ -208,8 +207,7 @@ public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, finalargs.add(classname); finalargs.addAll(Arrays.asList(arguments)); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(finalargs.toArray(String[]::new)); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(finalargs.toArray(String[]::new)); output.shouldHaveExitValue(0); return output; @@ -308,8 +306,7 @@ private static void shouldContainOrNot(OutputAnalyzer output, boolean contains, } private static void expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(flags); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(flags); shouldContainOrNot(output, hasWarning, "Warning"); shouldContainOrNot(output, hasError, "Error"); output.shouldHaveExitValue(errorcode); diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java index 7e91fe60cfb..11729aa5827 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java @@ -98,8 +98,7 @@ public static void positiveTest(int minRatio, boolean useXminf, Boolean.toString(shrinkHeapInSteps) ); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(0); } @@ -123,8 +122,7 @@ public static void negativeTest(int minRatio, boolean useXminf, "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", "-version" ); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(1); analyzer.shouldContain("Error: Could not create the Java Virtual Machine."); } diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java b/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java index f2214b8b0cf..ff6c3127640 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java +++ b/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java @@ -95,8 +95,7 @@ private static String getMaxNewSize(String[] flags) throws Exception { finalargs.add("-XX:+PrintFlagsFinal"); finalargs.add("-version"); - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder(finalargs); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeTestJava(finalargs); output.shouldHaveExitValue(0); String stdout = output.getStdout(); return getFlagValue("MaxNewSize", stdout); diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java index 4c66afd5cf5..13bb36ecc43 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java @@ -61,8 +61,7 @@ private static void checkMaxRAMSize(long maxram, int maxrampercent, boolean forc args.add("-XX:+PrintFlagsFinal"); args.add("-version"); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(args); output.shouldHaveExitValue(0); String stdout = output.getStdout(); @@ -84,8 +83,7 @@ private static long getHeapBaseMinAddress() throws Exception { args.add("-XX:+PrintFlagsFinal"); args.add("-version"); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(args); output.shouldHaveExitValue(0); String stdout = output.getStdout(); return (new Long(getFlagValue("HeapBaseMinAddress", stdout)).longValue()); diff --git a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java index 83f564b98a5..d3a51c40b61 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java @@ -102,8 +102,7 @@ public static void testSurvivorRatio(int survivorRatio, Boolean.toString(useAdaptiveSizePolicy) ); vmOptions.removeIf((String p) -> p.isEmpty()); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java index 9076005fa86..6eff65f3fa8 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java @@ -82,8 +82,7 @@ public static void testNewRatio(int ratio, LinkedList options) throws Ex Integer.toString(ratio) ); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(0); System.out.println(analyzer.getOutput()); } diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java index 3c3aff980dd..8fc522f8be8 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java @@ -133,7 +133,7 @@ public static void testVMOptions(long newSize, long maxNewSize, long heapSize, long maxHeapSize, long expectedNewSize, long expectedMaxNewSize, LinkedList options, boolean failureExpected) throws Exception { - OutputAnalyzer analyzer = startVM(options, newSize, maxNewSize, heapSize, maxHeapSize, expectedNewSize, expectedMaxNewSize); + OutputAnalyzer analyzer = executeLimitedTestJava(options, newSize, maxNewSize, heapSize, maxHeapSize, expectedNewSize, expectedMaxNewSize); if (failureExpected) { analyzer.shouldHaveExitValue(1); @@ -144,7 +144,7 @@ public static void testVMOptions(long newSize, long maxNewSize, } } - private static OutputAnalyzer startVM(LinkedList options, + private static OutputAnalyzer executeLimitedTestJava(LinkedList options, long newSize, long maxNewSize, long heapSize, long maxHeapSize, long expectedNewSize, long expectedMaxNewSize) throws Exception, IOException { @@ -166,9 +166,7 @@ private static OutputAnalyzer startVM(LinkedList options, Long.toString(maxHeapSize) ); vmOptions.removeIf(String::isEmpty); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); - return analyzer; + return GCArguments.executeLimitedTestJava(vmOptions); } /** diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java index 82e98429100..583176dfc69 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java @@ -65,14 +65,13 @@ public static void main(String[] args) throws Exception { } static void runNewSizeThreadIncreaseTest(String expectedValue, boolean isNewsizeChanged) throws Exception { - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder("-XX:+UseSerialGC", - "-Xms96M", - "-Xmx128M", - "-XX:NewRatio=2", - "-Xlog:gc+heap+ergo=debug", - "-XX:NewSizeThreadIncrease="+expectedValue, - GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava("-XX:+UseSerialGC", + "-Xms96M", + "-Xmx128M", + "-XX:NewRatio=2", + "-Xlog:gc+heap+ergo=debug", + "-XX:NewSizeThreadIncrease="+expectedValue, + GCTest.class.getName()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java b/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java index ca45def0b2b..ee1e73f9550 100644 --- a/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java @@ -161,8 +161,7 @@ private static void runTenuringFlagsConsistencyTest(String[] tenuringFlags, } Collections.addAll(vmOpts, "-XX:+UseParallelGC", "-XX:+PrintFlagsFinal", "-version"); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(vmOpts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(vmOpts); if (shouldFail) { output.shouldHaveExitValue(1); diff --git a/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java b/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java index 82ee38685ec..0a73a9d8759 100644 --- a/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java +++ b/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java @@ -56,10 +56,9 @@ public static void main(String args[]) throws Exception { private static final String printFlagsFinalPattern = " *uint *" + flagName + " *:?= *(\\d+) *\\{product\\} *"; public static void testDefaultValue() throws Exception { - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeLimitedTestJava( "-XX:+UnlockExperimentalVMOptions", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); String value = output.firstMatch(printFlagsFinalPattern, 1); try { @@ -94,12 +93,11 @@ public static void testFlags() throws Exception { for (String gc : supportedGC) { // Make sure the VM does not allow ParallelGCThreads set to 0 - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeLimitedTestJava( "-XX:+Use" + gc + "GC", "-XX:ParallelGCThreads=0", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); // Do some basic testing to ensure the flag updates the count @@ -124,8 +122,7 @@ public static void testFlags() throws Exception { } public static long getParallelGCThreadCount(String... flags) throws Exception { - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(flags); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(flags); output.shouldHaveExitValue(0); String stdout = output.getStdout(); return FlagsValue.getFlagLongValue("ParallelGCThreads", stdout); diff --git a/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java b/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java index d47d277e30b..40dfc4dc7fb 100644 --- a/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java +++ b/test/hotspot/jtreg/gc/arguments/TestParallelRefProc.java @@ -77,9 +77,7 @@ private static void testFlag(String[] args, boolean expectedTrue) throws Excepti result.addAll(Arrays.asList(args)); result.add("-XX:+PrintFlagsFinal"); result.add("-version"); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(result); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(result); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java b/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java index a48f21c957b..fb4787f452f 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java +++ b/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java @@ -44,12 +44,11 @@ public static void assertVMOption(OutputAnalyzer output, String option, boolean public static void testDefaultGC(boolean actAsServer) throws Exception { // Start VM without specifying GC - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeLimitedTestJava( "-XX:" + (actAsServer ? "+" : "-") + "AlwaysActAsServerClassMachine", "-XX:" + (actAsServer ? "-" : "+") + "NeverActAsServerClassMachine", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); final boolean isServer = actAsServer; diff --git a/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java b/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java index c1c2164a4da..7dcf006d172 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java +++ b/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception { long initHeap = heapAlignment; long maxHeap = heapAlignment * 2; - ProcessBuilder pb_enabled = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava( "-XX:+UseParallelGC", "-Xms" + String.valueOf(initHeap), "-Xmx" + String.valueOf(maxHeap), @@ -68,7 +68,6 @@ public static void main(String[] args) throws Exception { "-XX:+UseHugeTLBFS", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb_enabled.start()); if (largePageOrNumaEnabled(analyzer)) { // We reach here, if both NUMA and HugeTLB are supported. diff --git a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java index 8567615220a..a593970e6f7 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java @@ -87,8 +87,7 @@ public static void testSurvivorRatio(int ratio, LinkedList options) thro Integer.toString(ratio) ); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java index 8f8b4aa1087..afe424896b5 100644 --- a/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java @@ -116,8 +116,7 @@ public static void negativeTest(int ratio, LinkedList options) throws Ex vmOptions.add("-XX:TargetSurvivorRatio=" + ratio); vmOptions.add("-version"); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(1); analyzer.shouldContain("Error: Could not create the Java Virtual Machine."); @@ -151,8 +150,7 @@ public static void positiveTest(int ratio, LinkedList options) throws Ex Integer.toString(ratio) ); - ProcessBuilder procBuilder = GCArguments.createLimitedTestJavaProcessBuilder(vmOptions); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOptions); analyzer.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java b/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java index 8d51a6df173..c8ecac0bb99 100644 --- a/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java +++ b/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java @@ -40,32 +40,29 @@ public class TestUnrecognizedVMOptionsHandling { public static void main(String args[]) throws Exception { // The first two JAVA processes are expected to fail, but with a correct VM option suggestion - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer outputWithError = GCArguments.executeLimitedTestJava( "-XX:+UseDynamicNumberOfGcThreads", "-version" ); - OutputAnalyzer outputWithError = new OutputAnalyzer(pb.start()); outputWithError.shouldContain("Did you mean '(+/-)UseDynamicNumberOfGCThreads'?"); if (outputWithError.getExitValue() == 0) { throw new RuntimeException("Not expected to get exit value 0"); } - pb = GCArguments.createLimitedTestJavaProcessBuilder( + outputWithError = GCArguments.executeLimitedTestJava( "-XX:MaxiumHeapSize=500m", "-version" ); - outputWithError = new OutputAnalyzer(pb.start()); outputWithError.shouldContain("Did you mean 'MaxHeapSize='?"); if (outputWithError.getExitValue() == 0) { throw new RuntimeException("Not expected to get exit value 0"); } // The last JAVA process should run successfully for the purpose of sanity check - pb = GCArguments.createLimitedTestJavaProcessBuilder( + OutputAnalyzer outputWithNoError = GCArguments.executeLimitedTestJava( "-XX:+UseDynamicNumberOfGCThreads", "-version" ); - OutputAnalyzer outputWithNoError = new OutputAnalyzer(pb.start()); outputWithNoError.shouldNotContain("Did you mean '(+/-)UseDynamicNumberOfGCThreads'?"); outputWithNoError.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java index 19ebdea3c0e..2a1d2fef879 100644 --- a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java +++ b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java @@ -93,8 +93,7 @@ public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, finalargs.add(classname); finalargs.addAll(Arrays.asList(arguments)); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(finalargs); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(finalargs); output.shouldHaveExitValue(0); return output; } @@ -157,8 +156,7 @@ private static boolean getFlagBoolValue(String flag, String where) { } private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(flags); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = GCArguments.executeLimitedTestJava(flags); output.shouldHaveExitValue(errorcode); return output.getStdout(); } diff --git a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsFlagsWithUlimit.java b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsFlagsWithUlimit.java index 07cf4126970..495b36407b1 100644 --- a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsFlagsWithUlimit.java +++ b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsFlagsWithUlimit.java @@ -59,9 +59,8 @@ private static void checkFlag(long ulimit, long maxram, int maxrampercent, boole // Convert bytes to kbytes for ulimit -v var ulimit_prefix = "ulimit -v " + (ulimit / 1024); - String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJavaProcessBuilder(args.toArray(String[]::new))); - ProcessBuilder pb = new ProcessBuilder("sh", "-c", ulimit_prefix + ";" + cmd); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJavaProcessBuilder(args)); + OutputAnalyzer output = ProcessTools.executeProcess("sh", "-c", ulimit_prefix + ";" + cmd); output.shouldHaveExitValue(0); String stdout = output.getStdout(); diff --git a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java index 4a7fb7108c3..29c13f1fd90 100644 --- a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java +++ b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java @@ -39,11 +39,10 @@ public class TestUseNUMAInterleaving { public static void main(String[] args) throws Exception { - ProcessBuilder pb = GCArguments.createTestJavaProcessBuilder( + OutputAnalyzer output = GCArguments.executeTestJava( "-XX:+UseNUMA", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); boolean isNUMAEnabled = Boolean.parseBoolean(output.firstMatch(NUMA_FLAG_PATTERN, 1)); diff --git a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java index a3d6d5a7440..cc1f9be6fb7 100644 --- a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java @@ -99,8 +99,7 @@ public static void testVerifyFlags(boolean verifyBeforeGC, : "-XX:-VerifyAfterGC"), GarbageProducer.class.getName(), doFullGC ? "t" : "f" }); - ProcessBuilder pb = GCArguments.createLimitedTestJavaProcessBuilder(vmOpts); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + OutputAnalyzer analyzer = GCArguments.executeLimitedTestJava(vmOpts); analyzer.shouldHaveExitValue(0); analyzer.shouldNotMatch(VERIFY_BEFORE_GC_CORRUPTED_PATTERN); diff --git a/test/hotspot/jtreg/gc/class_unloading/TestG1ClassUnloadingHWM.java b/test/hotspot/jtreg/gc/class_unloading/TestG1ClassUnloadingHWM.java index 875da61a05f..758d6d1bf01 100644 --- a/test/hotspot/jtreg/gc/class_unloading/TestG1ClassUnloadingHWM.java +++ b/test/hotspot/jtreg/gc/class_unloading/TestG1ClassUnloadingHWM.java @@ -45,7 +45,7 @@ public class TestG1ClassUnloadingHWM { private static long YoungGenSize = 32 * 1024 * 1024; private static OutputAnalyzer run(boolean enableUnloading) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + return ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", @@ -57,7 +57,6 @@ private static OutputAnalyzer run(boolean enableUnloading) throws Exception { TestG1ClassUnloadingHWM.AllocateBeyondMetaspaceSize.class.getName(), "" + MetaspaceSize, "" + YoungGenSize); - return new OutputAnalyzer(pb.start()); } public static OutputAnalyzer runWithG1ClassUnloading() throws Exception { diff --git a/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java b/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java index c978f149fca..016bb517c3c 100644 --- a/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java +++ b/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java @@ -37,15 +37,13 @@ public class TestDieDefault { public static void passWith(String... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + OutputAnalyzer out = ProcessTools.executeLimitedTestJava(args); out.shouldNotContain("OutOfMemoryError"); out.shouldHaveExitValue(0); } public static void failWith(String... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + OutputAnalyzer out = ProcessTools.executeLimitedTestJava(args); out.shouldContain("OutOfMemoryError"); if (out.getExitValue() == 0) { throw new IllegalStateException("Should have failed with non-zero exit code"); diff --git a/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java b/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java index 2e19141d286..8f6e9a36d77 100644 --- a/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java +++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java @@ -38,8 +38,7 @@ public class TestDieWithHeapDump { public static void passWith(String... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + OutputAnalyzer out = ProcessTools.executeLimitedTestJava(args); out.shouldNotContain("OutOfMemoryError"); out.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java b/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java index a6593fecdff..7be60c59595 100644 --- a/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java +++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java @@ -39,16 +39,14 @@ public class TestDieWithOnError { static String ON_ERR_MSG = "Epsilon error handler message"; public static void passWith(String... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + OutputAnalyzer out = ProcessTools.executeLimitedTestJava(args); out.shouldNotContain("OutOfMemoryError"); out.stdoutShouldNotMatch("^" + ON_ERR_MSG); out.shouldHaveExitValue(0); } public static void failWith(String... args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + OutputAnalyzer out = ProcessTools.executeLimitedTestJava(args); out.shouldContain("OutOfMemoryError"); if (out.getExitValue() == 0) { throw new IllegalStateException("Should have failed with non-zero exit code"); diff --git a/test/hotspot/jtreg/gc/ergonomics/TestDynamicNumberOfGCThreads.java b/test/hotspot/jtreg/gc/ergonomics/TestDynamicNumberOfGCThreads.java index 3e7293a5a92..b87609ef922 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestDynamicNumberOfGCThreads.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestDynamicNumberOfGCThreads.java @@ -73,16 +73,16 @@ private static void testDynamicNumberOfGCThreads(String gcFlag) throws Exception String[] baseArgs = {"-XX:+UnlockExperimentalVMOptions", "-XX:+" + gcFlag, "-Xmx10M", "-XX:+UseDynamicNumberOfGCThreads", "-Xlog:gc+task=trace", GCTest.class.getName()}; // Base test with gc and +UseDynamicNumberOfGCThreads: - ProcessBuilder pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder(baseArgs); - verifyDynamicNumberOfGCThreads(new OutputAnalyzer(pb_enabled.start())); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseArgs); + verifyDynamicNumberOfGCThreads(output); // Turn on parallel reference processing String[] parRefProcArg = {"-XX:+ParallelRefProcEnabled", "-XX:-ShowMessageBoxOnError"}; String[] parRefArgs = new String[baseArgs.length + parRefProcArg.length]; System.arraycopy(parRefProcArg, 0, parRefArgs, 0, parRefProcArg.length); System.arraycopy(baseArgs, 0, parRefArgs, parRefProcArg.length, baseArgs.length); - pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder(parRefArgs); - verifyDynamicNumberOfGCThreads(new OutputAnalyzer(pb_enabled.start())); + output = ProcessTools.executeLimitedTestJava(parRefArgs); + verifyDynamicNumberOfGCThreads(output); } static class GCTest { diff --git a/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java b/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java index dc1b83cd2c1..e58b930b519 100644 --- a/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java +++ b/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java @@ -70,13 +70,13 @@ private static void verifyDynamicNumberOfGCThreads(OutputAnalyzer output, String private static void testInitialGCThreadLogging(String gcFlag, String threadName) throws Exception { // Base test with gc and +UseDynamicNumberOfGCThreads: - ProcessBuilder pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UnlockExperimentalVMOptions", "-XX:+" + gcFlag, "-Xmx10M", "-XX:+UseDynamicNumberOfGCThreads", "-Xlog:gc+task=trace", "-version"); - verifyDynamicNumberOfGCThreads(new OutputAnalyzer(pb_enabled.start()), threadName); + verifyDynamicNumberOfGCThreads(output, threadName); } } diff --git a/test/hotspot/jtreg/gc/g1/Test2GbHeap.java b/test/hotspot/jtreg/gc/g1/Test2GbHeap.java index 8e06ac3ee2c..9b981883714 100644 --- a/test/hotspot/jtreg/gc/g1/Test2GbHeap.java +++ b/test/hotspot/jtreg/gc/g1/Test2GbHeap.java @@ -49,9 +49,8 @@ public static void main(String[] args) throws Exception { testArguments.add("-Xmx2g"); testArguments.add("-version"); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(testArguments); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(testArguments); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegions.java b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegions.java index a334783eca6..d1ae8ab734c 100644 --- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegions.java +++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegions.java @@ -80,7 +80,7 @@ public static void main(String[] args) { public class TestEagerReclaimHumongousRegions { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UseG1GC", "-Xms128M", "-Xmx128M", @@ -90,8 +90,6 @@ public static void main(String[] args) throws Exception { Pattern p = Pattern.compile("Full GC"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - int found = 0; Matcher m = p.matcher(output.getStdout()); while (m.find()) { found++; } diff --git a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java index bcb156d9074..282c4fcfc14 100644 --- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java +++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java @@ -119,7 +119,7 @@ public static void main(String[] args) { public class TestEagerReclaimHumongousRegionsClearMarkBits { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UseG1GC", "-Xms128M", "-Xmx128M", @@ -132,7 +132,6 @@ public static void main(String[] args) throws Exception { "-XX:ConcGCThreads=1", // Want to make marking as slow as possible. "-XX:+G1VerifyBitmaps", TestEagerReclaimHumongousRegionsClearMarkBitsReclaimRegionFast.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java index 30aee3ced47..812257f8d39 100644 --- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java +++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java @@ -54,7 +54,7 @@ private static String getSumValue(String s) { } public static void runTest() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-XX:+UnlockExperimentalVMOptions", "-XX:+UnlockDiagnosticVMOptions", @@ -65,7 +65,6 @@ public static void runTest() throws Exception { "-Xmx128M", "-Xlog:gc+phases=trace,gc+heap=info", GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java index 585f4e867ab..0ff16a49f0e 100644 --- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java +++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java @@ -92,7 +92,7 @@ public static void main(String[] args) { public class TestEagerReclaimHumongousRegionsWithRefs { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UseG1GC", "-Xms128M", "-Xmx128M", @@ -102,8 +102,6 @@ public static void main(String[] args) throws Exception { Pattern p = Pattern.compile("Full GC"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - int found = 0; Matcher m = p.matcher(output.getStdout()); while (m.find()) { diff --git a/test/hotspot/jtreg/gc/g1/TestEvacuationFailure.java b/test/hotspot/jtreg/gc/g1/TestEvacuationFailure.java index 6bbcddae55f..7bf8cd09137 100644 --- a/test/hotspot/jtreg/gc/g1/TestEvacuationFailure.java +++ b/test/hotspot/jtreg/gc/g1/TestEvacuationFailure.java @@ -43,17 +43,16 @@ public class TestEvacuationFailure { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx32M", - "-Xmn16M", - "-XX:+G1EvacuationFailureALot", - "-XX:G1EvacuationFailureALotCount=100", - "-XX:G1EvacuationFailureALotInterval=1", - "-XX:+UnlockDiagnosticVMOptions", - "-Xlog:gc", - GCTestWithEvacuationFailure.class.getName()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx32M", + "-Xmn16M", + "-XX:+G1EvacuationFailureALot", + "-XX:G1EvacuationFailureALotCount=100", + "-XX:G1EvacuationFailureALotInterval=1", + "-XX:+UnlockDiagnosticVMOptions", + "-Xlog:gc", + GCTestWithEvacuationFailure.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println(output.getStdout()); output.shouldContain("(Evacuation Failure)"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java b/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java index 17957cfa5fc..1d2cf8e7880 100644 --- a/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java +++ b/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java @@ -54,8 +54,7 @@ public static void runTest() throws Exception { "-XX:G1HeapRegionSize=1m", GCTest.class.getName() }; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(arguments); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(arguments); System.out.println(output.getStdout()); String pattern = ".*skip compaction region.*"; diff --git a/test/hotspot/jtreg/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java b/test/hotspot/jtreg/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java index 4dedac0a61b..d1cb29b314e 100644 --- a/test/hotspot/jtreg/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java +++ b/test/hotspot/jtreg/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java @@ -41,16 +41,14 @@ public class TestG1TraceEagerReclaimHumongousObjects { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xms128M", - "-Xmx128M", - "-Xmn16M", - "-XX:G1HeapRegionSize=1M", - "-Xlog:gc+phases=trace,gc+humongous=trace", - "-XX:+UnlockExperimentalVMOptions", - GCWithHumongousObjectTest.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn16M", + "-XX:G1HeapRegionSize=1M", + "-Xlog:gc+phases=trace,gc+humongous=trace", + "-XX:+UnlockExperimentalVMOptions", + GCWithHumongousObjectTest.class.getName()); System.out.println(output.getStdout()); // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed. diff --git a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java index f256cbc61c6..3b0630b3e60 100644 --- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java +++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java @@ -217,28 +217,25 @@ public static void main(String[] args) throws Exception { private void testNormalLogs() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - GCTest.class.getName()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); checkMessagesAtLevel(output, allLogMessages, Level.OFF); output.shouldHaveExitValue(0); - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - "-Xlog:gc+phases=debug", - GCTest.class.getName()); + output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + "-Xlog:gc+phases=debug", + GCTest.class.getName()); - output = new OutputAnalyzer(pb.start()); checkMessagesAtLevel(output, allLogMessages, Level.DEBUG); - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - "-Xlog:gc+phases=trace", - GCTest.class.getName()); + output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + "-Xlog:gc+phases=trace", + GCTest.class.getName()); - output = new OutputAnalyzer(pb.start()); checkMessagesAtLevel(output, allLogMessages, Level.TRACE); output.shouldHaveExitValue(0); } @@ -252,11 +249,10 @@ private void testNormalLogs() throws Exception { }; private void testConcurrentRefinementLogs() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - "-Xlog:gc+refine+stats=debug", - GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + "-Xlog:gc+refine+stats=debug", + GCTest.class.getName()); checkMessagesAtLevel(output, concRefineMessages, Level.DEBUG); } @@ -268,29 +264,27 @@ private void testConcurrentRefinementLogs() throws Exception { }; private void testWithEvacuationFailureLogs() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx32M", - "-Xmn16M", - "-XX:+G1EvacuationFailureALot", - "-XX:G1EvacuationFailureALotCount=100", - "-XX:G1EvacuationFailureALotInterval=1", - "-XX:+UnlockDiagnosticVMOptions", - "-Xlog:gc+phases=debug", - GCTestWithEvacuationFailure.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx32M", + "-Xmn16M", + "-XX:+G1EvacuationFailureALot", + "-XX:G1EvacuationFailureALotCount=100", + "-XX:G1EvacuationFailureALotInterval=1", + "-XX:+UnlockDiagnosticVMOptions", + "-Xlog:gc+phases=debug", + GCTestWithEvacuationFailure.class.getName()); + checkMessagesAtLevel(output, exhFailureMessages, Level.DEBUG); output.shouldHaveExitValue(0); - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx32M", - "-Xmn16M", - "-Xms32M", - "-XX:+UnlockDiagnosticVMOptions", - "-Xlog:gc+phases=trace", - GCTestWithEvacuationFailure.class.getName()); + output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx32M", + "-Xmn16M", + "-Xms32M", + "-XX:+UnlockDiagnosticVMOptions", + "-Xlog:gc+phases=trace", + GCTestWithEvacuationFailure.class.getName()); - output = new OutputAnalyzer(pb.start()); checkMessagesAtLevel(output, exhFailureMessages, Level.TRACE); output.shouldHaveExitValue(0); } @@ -301,29 +295,27 @@ private void testWithEvacuationFailureLogs() throws Exception { }; private void testWithConcurrentStart() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - "-Xbootclasspath/a:.", - "-Xlog:gc*=debug", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - GCTestWithConcurrentStart.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + "-Xbootclasspath/a:.", + "-Xlog:gc*=debug", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + GCTestWithConcurrentStart.class.getName()); + checkMessagesAtLevel(output, concurrentStartMessages, Level.TRACE); output.shouldHaveExitValue(0); } private void testExpandHeap() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-Xmx10M", - "-Xbootclasspath/a:.", - "-Xlog:gc+ergo+heap=debug", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - GCTest.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx10M", + "-Xbootclasspath/a:.", + "-Xlog:gc+ergo+heap=debug", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + GCTest.class.getName()); + output.shouldContain("Expand the heap. requested expansion amount: "); output.shouldContain("B expansion amount: "); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java b/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java index dc8c28a6008..52cb2db0ffa 100644 --- a/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java +++ b/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java @@ -45,7 +45,7 @@ public class TestHumongousAllocConcurrentStart { private static final int initiatingHeapOccupancyPercent = 50; // % public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeTestJava( "-XX:+UseG1GC", "-Xms" + heapSize + "m", "-Xmx" + heapSize + "m", @@ -54,7 +54,6 @@ public static void main(String[] args) throws Exception { "-Xlog:gc", HumongousObjectAllocator.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Pause Young (Concurrent Start) (G1 Humongous Allocation)"); output.shouldNotContain("Full GC"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestHumongousAllocNearlyFullRegion.java b/test/hotspot/jtreg/gc/g1/TestHumongousAllocNearlyFullRegion.java index 6d141870ae3..d6e9aac722f 100644 --- a/test/hotspot/jtreg/gc/g1/TestHumongousAllocNearlyFullRegion.java +++ b/test/hotspot/jtreg/gc/g1/TestHumongousAllocNearlyFullRegion.java @@ -47,7 +47,7 @@ public class TestHumongousAllocNearlyFullRegion { private static final int heapRegionSize = 1; // MB public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UseG1GC", "-Xms" + heapSize + "m", "-Xmx" + heapSize + "m", @@ -55,7 +55,6 @@ public static void main(String[] args) throws Exception { "-Xlog:gc", HumongousObjectAllocator.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Pause Young (Concurrent Start) (G1 Humongous Allocation)"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/g1/TestHumongousCodeCacheRoots.java b/test/hotspot/jtreg/gc/g1/TestHumongousCodeCacheRoots.java index 057b8310de6..c5f2a86b42c 100644 --- a/test/hotspot/jtreg/gc/g1/TestHumongousCodeCacheRoots.java +++ b/test/hotspot/jtreg/gc/g1/TestHumongousCodeCacheRoots.java @@ -106,8 +106,7 @@ public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, finalargs.add(classname); finalargs.addAll(Arrays.asList(arguments)); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(finalargs); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(finalargs); output.shouldHaveExitValue(0); return output; } diff --git a/test/hotspot/jtreg/gc/g1/TestHumongousConcurrentStartUndo.java b/test/hotspot/jtreg/gc/g1/TestHumongousConcurrentStartUndo.java index 6376149fbf9..bd8e6a39df8 100644 --- a/test/hotspot/jtreg/gc/g1/TestHumongousConcurrentStartUndo.java +++ b/test/hotspot/jtreg/gc/g1/TestHumongousConcurrentStartUndo.java @@ -56,7 +56,7 @@ public class TestHumongousConcurrentStartUndo { private static final int YoungSize = HeapSize / 8; public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-XX:+UseG1GC", "-Xms" + HeapSize + "m", @@ -70,7 +70,6 @@ public static void main(String[] args) throws Exception { "-Xlog:gc*", EdenObjectAllocatorWithHumongousAllocation.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Pause Young (Concurrent Start) (G1 Humongous Allocation)"); output.shouldContain("Concurrent Undo Cycle"); output.shouldContain("Concurrent Mark Cycle"); diff --git a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java index 588411fb2e6..3718583e09e 100644 --- a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java +++ b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java @@ -120,12 +120,8 @@ static List getOpts(long heapsize, boolean largePageEnabled) { static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception { System.out.println(what + " heapsize " + heapsize + " card table should use large pages " + cardsShouldUseLargePages + " " + "bitmaps should use large pages " + bitmapShouldUseLargePages); - ProcessBuilder pb; + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(getOpts(heapsize, true)); - // Test with large page enabled. - pb = ProcessTools.createLimitedTestJavaProcessBuilder(getOpts(heapsize, true)); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); // Only expect large page size if large pages are enabled. if (largePagesEnabled(output)) { checkSmallTables(output, (cardsShouldUseLargePages ? largePageSize : smallPageSize)); @@ -137,9 +133,8 @@ static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, output.shouldHaveExitValue(0); // Test with large page disabled. - pb = ProcessTools.createLimitedTestJavaProcessBuilder(getOpts(heapsize, false)); + output = ProcessTools.executeLimitedTestJava(getOpts(heapsize, false)); - output = new OutputAnalyzer(pb.start()); checkSmallTables(output, smallPageSize); checkBitmap(output, smallPageSize); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestLargePageUseForHeap.java b/test/hotspot/jtreg/gc/g1/TestLargePageUseForHeap.java index 90f8747f3b3..a779d9ba096 100644 --- a/test/hotspot/jtreg/gc/g1/TestLargePageUseForHeap.java +++ b/test/hotspot/jtreg/gc/g1/TestLargePageUseForHeap.java @@ -85,29 +85,26 @@ static void checkHeap(OutputAnalyzer output, long expectedPageSize) throws Excep } static void testVM(long regionSize) throws Exception { - ProcessBuilder pb; // Test with large page enabled. - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-XX:G1HeapRegionSize=" + regionSize, - "-Xmx128m", - "-Xlog:gc+init,pagesize,gc+heap+coops=debug", - "-XX:+UseLargePages", - "-version"); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-XX:G1HeapRegionSize=" + regionSize, + "-Xmx128m", + "-Xlog:gc+init,pagesize,gc+heap+coops=debug", + "-XX:+UseLargePages", + "-version"); + boolean largePageEnabled = checkLargePageEnabled(output); checkHeap(output, largePageEnabled ? largePageSize : smallPageSize); output.shouldHaveExitValue(0); // Test with large page disabled. - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-XX:G1HeapRegionSize=" + regionSize, - "-Xmx128m", - "-Xlog:gc+init,pagesize,gc+heap+coops=debug", - "-XX:-UseLargePages", - "-version"); - - output = new OutputAnalyzer(pb.start()); + output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-XX:G1HeapRegionSize=" + regionSize, + "-Xmx128m", + "-Xlog:gc+init,pagesize,gc+heap+coops=debug", + "-XX:-UseLargePages", + "-version"); + checkHeap(output, smallPageSize); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/g1/TestMarkStackSizes.java b/test/hotspot/jtreg/gc/g1/TestMarkStackSizes.java index d056a5ef747..0a1c373199c 100644 --- a/test/hotspot/jtreg/gc/g1/TestMarkStackSizes.java +++ b/test/hotspot/jtreg/gc/g1/TestMarkStackSizes.java @@ -50,9 +50,7 @@ private static void runTest(boolean shouldSucceed, String... extraArgs) throws E Collections.addAll(testArguments, extraArgs); testArguments.add("-version"); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(testArguments); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(testArguments); System.out.println(output.getStderr()); diff --git a/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java b/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java index 035a6b89679..e0aa0827749 100644 --- a/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java +++ b/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java @@ -109,9 +109,7 @@ private static OutputAnalyzer testWithMixedGCLiveThresholdPercent(int percent) t basicOpts.add(GCTest.class.getName()); - ProcessBuilder procBuilder = ProcessTools.createLimitedTestJavaProcessBuilder(basicOpts); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); - return analyzer; + return ProcessTools.executeLimitedTestJava(basicOpts); } private static boolean regionsSelectedForRebuild(String output) throws Exception { diff --git a/test/hotspot/jtreg/gc/g1/TestOneEdenRegionAfterGC.java b/test/hotspot/jtreg/gc/g1/TestOneEdenRegionAfterGC.java index f6a22c4b841..a541fd327f9 100644 --- a/test/hotspot/jtreg/gc/g1/TestOneEdenRegionAfterGC.java +++ b/test/hotspot/jtreg/gc/g1/TestOneEdenRegionAfterGC.java @@ -40,7 +40,7 @@ public class TestOneEdenRegionAfterGC { private static long YoungGenSize = 32 * 1024 * 1024; private static OutputAnalyzer run() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + return ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-Xmn" + YoungGenSize, "-Xmx512M", @@ -50,7 +50,6 @@ private static OutputAnalyzer run() throws Exception { "-Xlog:gc,gc+ergo*=trace", TestOneEdenRegionAfterGC.Allocate.class.getName(), "" + YoungGenSize); - return new OutputAnalyzer(pb.start()); } public static void main(String args[]) throws Exception { diff --git a/test/hotspot/jtreg/gc/g1/TestPLABOutput.java b/test/hotspot/jtreg/gc/g1/TestPLABOutput.java index 13a496ca47e..ed6570633a6 100644 --- a/test/hotspot/jtreg/gc/g1/TestPLABOutput.java +++ b/test/hotspot/jtreg/gc/g1/TestPLABOutput.java @@ -59,8 +59,7 @@ public static void runTest() throws Exception { GCTest.class.getName() }; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(arguments); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(arguments); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestPLABSizeBounds.java b/test/hotspot/jtreg/gc/g1/TestPLABSizeBounds.java index 6c1e7f16dd3..87185388287 100644 --- a/test/hotspot/jtreg/gc/g1/TestPLABSizeBounds.java +++ b/test/hotspot/jtreg/gc/g1/TestPLABSizeBounds.java @@ -62,8 +62,7 @@ public static void runTest(int regionSize, int plabSize, boolean shouldSucceed) testArguments.add("-XX:OldPLABSize=" + plabSize); testArguments.add(GCTest.class.getName()); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(testArguments); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(testArguments); if (shouldSucceed) { output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java b/test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java index c80ab7a50e8..35641affff7 100644 --- a/test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java +++ b/test/hotspot/jtreg/gc/g1/TestPeriodicLogMessages.java @@ -40,24 +40,22 @@ public class TestPeriodicLogMessages { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-XX:G1PeriodicGCInterval=0", - "-Xlog:gc+init,gc+periodic=debug", - "-Xmx10M", - GCTest.class.getName()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-XX:G1PeriodicGCInterval=0", + "-Xlog:gc+init,gc+periodic=debug", + "-Xmx10M", + GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Periodic GC: Disabled"); output.shouldNotContain("Checking for periodic GC"); output.shouldHaveExitValue(0); - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-XX:G1PeriodicGCInterval=100", - "-Xlog:gc+init,gc+periodic=debug", - "-Xmx10M", - GCTest.class.getName()); + output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-XX:G1PeriodicGCInterval=100", + "-Xlog:gc+init,gc+periodic=debug", + "-Xmx10M", + GCTest.class.getName()); - output = new OutputAnalyzer(pb.start()); output.shouldContain("Periodic GC: Enabled"); output.shouldContain("Periodic GC Interval: 100ms"); output.shouldContain("Checking for periodic GC"); diff --git a/test/hotspot/jtreg/gc/g1/TestPrintRegionRememberedSetInfo.java b/test/hotspot/jtreg/gc/g1/TestPrintRegionRememberedSetInfo.java index bc4d59d9a3c..374daef92b5 100644 --- a/test/hotspot/jtreg/gc/g1/TestPrintRegionRememberedSetInfo.java +++ b/test/hotspot/jtreg/gc/g1/TestPrintRegionRememberedSetInfo.java @@ -69,8 +69,7 @@ public static String runTest(String arg) throws Exception { finalargs.add(RunAndWaitForMarking.class.getName()); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(finalargs); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(finalargs); output.shouldHaveExitValue(0); String result = output.getStdout(); diff --git a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java index 5d4b4d958f8..c2b1be60322 100644 --- a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java +++ b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java @@ -44,14 +44,12 @@ public class TestRemsetLoggingThreads { private static void runTest(int refinementThreads, int workerThreads) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UseG1GC", - "-XX:+UnlockDiagnosticVMOptions", - "-Xlog:gc+remset+exit=trace", - "-XX:G1ConcRefinementThreads=" + refinementThreads, - "-XX:ParallelGCThreads=" + workerThreads, - "-version"); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-XX:+UnlockDiagnosticVMOptions", + "-Xlog:gc+remset+exit=trace", + "-XX:G1ConcRefinementThreads=" + refinementThreads, + "-XX:ParallelGCThreads=" + workerThreads, + "-version"); String pattern = "Concurrent refinement threads times \\(s\\)$"; Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout()); diff --git a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java index 69f34e07146..7e44c41e1a4 100644 --- a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java +++ b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java @@ -77,8 +77,7 @@ public static String runTest(String[] additionalArgs, int numGCs) throws Excepti finalargs.add(VerifySummaryOutput.class.getName()); finalargs.add(String.valueOf(numGCs)); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(finalargs); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(finalargs); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestSharedArchiveWithPreTouch.java b/test/hotspot/jtreg/gc/g1/TestSharedArchiveWithPreTouch.java index d894c58d737..aef9a98530c 100644 --- a/test/hotspot/jtreg/gc/g1/TestSharedArchiveWithPreTouch.java +++ b/test/hotspot/jtreg/gc/g1/TestSharedArchiveWithPreTouch.java @@ -50,8 +50,6 @@ public static void main(String[] args) throws Exception { final List BaseOptions = Arrays.asList(new String[] {"-XX:+UseG1GC", "-XX:+AlwaysPreTouch", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + ArchiveFileName }); - ProcessBuilder pb; - List dump_args = new ArrayList(BaseOptions); if (Platform.is64bit()) { @@ -59,8 +57,8 @@ public static void main(String[] args) throws Exception { } dump_args.addAll(Arrays.asList(new String[] { "-Xshare:dump", "-Xlog:cds" })); - pb = ProcessTools.createLimitedTestJavaProcessBuilder(dump_args); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(dump_args); + try { output.shouldContain("Loading classes to share"); output.shouldHaveExitValue(0); @@ -72,8 +70,7 @@ public static void main(String[] args) throws Exception { } load_args.addAll(Arrays.asList(new String[] { "-Xshare:on", "-version" })); - pb = ProcessTools.createLimitedTestJavaProcessBuilder(load_args.toArray(new String[0])); - output = new OutputAnalyzer(pb.start()); + output = ProcessTools.executeLimitedTestJava(load_args.toArray(new String[0])); output.shouldContain("sharing"); output.shouldHaveExitValue(0); } catch (RuntimeException e) { diff --git a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java index 645e545443d..8f68ccba9ad 100644 --- a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java +++ b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java @@ -88,9 +88,8 @@ protected void test() throws Exception { } private void performTest(List opts) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(opts); + OutputAnalyzer output = ProcessTools.executeTestJava(opts); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println(output.getStdout()); System.err.println(output.getStderr()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestShrinkDefragmentedHeap.java b/test/hotspot/jtreg/gc/g1/TestShrinkDefragmentedHeap.java index acdce6b6417..7934660a323 100644 --- a/test/hotspot/jtreg/gc/g1/TestShrinkDefragmentedHeap.java +++ b/test/hotspot/jtreg/gc/g1/TestShrinkDefragmentedHeap.java @@ -61,7 +61,7 @@ public class TestShrinkDefragmentedHeap { private static final int REGION_SIZE = 1 * 1024 * 1024; public static void main(String[] args) throws Exception, Throwable { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:InitialHeapSize=" + INITIAL_HEAP_SIZE, "-Xmn" + MINIMAL_YOUNG_SIZE, "-Xmx" + MAXIMUM_HEAP_SIZE, @@ -74,7 +74,6 @@ public static void main(String[] args) throws Exception, Throwable { GCTest.class.getName() ); - OutputAnalyzer output = ProcessTools.executeProcess(pb); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java index 4c7190ada02..f7f768c9d7d 100644 --- a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java +++ b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java @@ -40,17 +40,16 @@ public class TestSkipRebuildRemsetPhase { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xbootclasspath/a:.", - "-XX:+UseG1GC", - "-XX:+UnlockExperimentalVMOptions", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-XX:G1MixedGCLiveThresholdPercent=20", - "-Xlog:gc+marking=debug,gc+phases=debug,gc+remset+tracking=trace", - "-Xms10M", - "-Xmx10M", - GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xbootclasspath/a:.", + "-XX:+UseG1GC", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:G1MixedGCLiveThresholdPercent=20", + "-Xlog:gc+marking=debug,gc+phases=debug,gc+remset+tracking=trace", + "-Xms10M", + "-Xmx10M", + GCTest.class.getName()); output.shouldContain("Skipping Remembered Set Rebuild."); output.shouldContain("No Remembered Sets to update after rebuild"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/g1/TestVerifyGCType.java b/test/hotspot/jtreg/gc/g1/TestVerifyGCType.java index 02ee74bed8b..646132e6b2c 100644 --- a/test/hotspot/jtreg/gc/g1/TestVerifyGCType.java +++ b/test/hotspot/jtreg/gc/g1/TestVerifyGCType.java @@ -178,10 +178,7 @@ private static OutputAnalyzer testWithVerificationType(String[] types, String... basicOpts.add(TriggerGCs.class.getName()); - ProcessBuilder procBuilder = ProcessTools.createLimitedTestJavaProcessBuilder(basicOpts); - OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start()); - - return analyzer; + return ProcessTools.executeLimitedTestJava(basicOpts); } private static void verifyCollection(String name, boolean expectBefore, boolean expectDuring, boolean expectAfter, String data) { diff --git a/test/hotspot/jtreg/gc/g1/humongousObjects/ClassLoaderGenerator.java b/test/hotspot/jtreg/gc/g1/humongousObjects/ClassLoaderGenerator.java index 25510063b55..01ad5e1c0b3 100644 --- a/test/hotspot/jtreg/gc/g1/humongousObjects/ClassLoaderGenerator.java +++ b/test/hotspot/jtreg/gc/g1/humongousObjects/ClassLoaderGenerator.java @@ -34,7 +34,7 @@ * Since the generation depends on current host architecture it cannot be done as part of pre-compilation step */ public class ClassLoaderGenerator { - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { if (args.length != 1) { throw new Error("Test Bug: Expected region size wasn't provided as command line argument"); @@ -47,7 +47,7 @@ public static void main(String[] args) throws IOException { } - public static void generateClassLoader(long regionSize, Path wrkDir) throws IOException { + public static void generateClassLoader(long regionSize, Path wrkDir) throws Exception { // Generating simple classloader String finalSimpleClassLoaderPrototype = TestHumongousClassLoader.GENERIC_PROTOTYPE .replace("${Methods}", diff --git a/test/hotspot/jtreg/gc/g1/humongousObjects/G1SampleClass.java b/test/hotspot/jtreg/gc/g1/humongousObjects/G1SampleClass.java index 1a321c9b115..8e11eff2749 100644 --- a/test/hotspot/jtreg/gc/g1/humongousObjects/G1SampleClass.java +++ b/test/hotspot/jtreg/gc/g1/humongousObjects/G1SampleClass.java @@ -75,12 +75,11 @@ public long expectedInstanceSize() { * @param wrkDir working dir where generated classes are put and compiled * @param classNamePrefix prefix for service classes (ones we use to create chain of inheritance) * @return a class with instances of the specified size loaded in specified class loader - * @throws IOException - * @throws ClassNotFoundException + * @throws Exception */ public Class getCls(ClassLoader classLoader, Path wrkDir, String classNamePrefix) - throws IOException, ClassNotFoundException { + throws Exception { return Helpers.generateCompileAndLoad(classLoader, Helpers.enumNameToClassName(name()) + "Class", expectedInstanceSize(), wrkDir, classNamePrefix); } diff --git a/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousClassLoader.java b/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousClassLoader.java index c2be830f57c..34333e90ef2 100644 --- a/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousClassLoader.java +++ b/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousClassLoader.java @@ -140,9 +140,7 @@ public void provoke() { public abstract void provoke(); } - public static void main(String[] args) throws ClassNotFoundException, InstantiationException, - IllegalAccessException, IOException, NoSuchMethodException, InvocationTargetException { - + public static void main(String[] args) throws Exception { if (args.length != 1) { throw new Error("Test Bug: Expected GC type wasn't provided as command line argument"); } diff --git a/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousNonArrayAllocation.java b/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousNonArrayAllocation.java index 32a4251a6a8..0e432177208 100644 --- a/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousNonArrayAllocation.java +++ b/test/hotspot/jtreg/gc/g1/humongousObjects/TestHumongousNonArrayAllocation.java @@ -82,8 +82,7 @@ public class TestHumongousNonArrayAllocation { private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final String CLASS_NAME_PREFIX = TestHumongousNonArrayAllocation.class.getSimpleName() + "_"; - public static void main(String[] args) throws ClassNotFoundException, InstantiationException, - IllegalAccessException, IOException { + public static void main(String[] args) throws Exception { if (args.length != 1) { throw new Error("Test Bug: Expected class name wasn't provided as command line argument"); diff --git a/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java b/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java index e4b4074264d..e3b0ba0185b 100644 --- a/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java +++ b/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java @@ -90,8 +90,7 @@ private static OutputAnalyzer spawnMixedGCProvoker(String... extraFlags) Collections.addAll(testOpts, extraFlags); testOpts.add(RunMixedGC.class.getName()); System.out.println(testOpts); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(testOpts); - return new OutputAnalyzer(pb.start()); + return ProcessTools.executeLimitedTestJava(testOpts); } } diff --git a/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java b/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java index 4d231080a24..e467b89d31d 100644 --- a/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java +++ b/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java @@ -181,7 +181,7 @@ static void testMemoryTouch(String largePagesSetting, int regionSizeInMB) throws return; } - ProcessBuilder pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xbootclasspath/a:.", "-Xlog:pagesize,gc+heap+region=trace", "-XX:+UseG1GC", @@ -195,7 +195,6 @@ static void testMemoryTouch(String largePagesSetting, int regionSizeInMB) throws largePagesSetting, "-XX:G1HeapRegionSize=" + regionSizeInMB + "m", GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb_enabled.start()); // Check NUMA availability. if (status == NUMASupportStatus.NOT_CHECKED) { diff --git a/test/hotspot/jtreg/gc/logging/TestDeprecatedPrintFlags.java b/test/hotspot/jtreg/gc/logging/TestDeprecatedPrintFlags.java index 04607502a22..78089ea6452 100644 --- a/test/hotspot/jtreg/gc/logging/TestDeprecatedPrintFlags.java +++ b/test/hotspot/jtreg/gc/logging/TestDeprecatedPrintFlags.java @@ -42,8 +42,7 @@ public class TestDeprecatedPrintFlags { public static void testPrintGC() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+PrintGC", DoGC.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintGC", DoGC.class.getName()); output.shouldContain("-XX:+PrintGC is deprecated. Will use -Xlog:gc instead."); output.shouldNotContain("PrintGCDetails"); output.stdoutShouldMatch("\\[info.*\\]\\[gc *\\]"); @@ -52,8 +51,7 @@ public static void testPrintGC() throws Exception { } public static void testPrintGCDetails() throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+PrintGCDetails", DoGC.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintGCDetails", DoGC.class.getName()); output.shouldContain("-XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead."); output.shouldNotContain("PrintGC is deprecated"); output.stdoutShouldMatch("\\[info.*\\]\\[gc *\\]"); @@ -63,8 +61,7 @@ public static void testPrintGCDetails() throws Exception { public static void testXloggc() throws Exception { String fileName = "gc-test.log"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xloggc:" + fileName, DoGC.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xloggc:" + fileName, DoGC.class.getName()); output.shouldContain("-Xloggc is deprecated. Will use -Xlog:gc:gc-test.log instead."); output.shouldNotContain("PrintGCDetails"); output.shouldNotContain("PrintGC"); @@ -80,8 +77,7 @@ public static void testXloggc() throws Exception { public static void testXloggcWithPrintGCDetails() throws Exception { String fileName = "gc-test.log"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+PrintGCDetails", "-Xloggc:" + fileName, DoGC.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintGCDetails", "-Xloggc:" + fileName, DoGC.class.getName()); output.shouldContain("-XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead."); output.shouldContain("-Xloggc is deprecated. Will use -Xlog:gc:gc-test.log instead."); output.shouldNotContain("PrintGC is deprecated"); diff --git a/test/hotspot/jtreg/gc/logging/TestGCId.java b/test/hotspot/jtreg/gc/logging/TestGCId.java index dca1681e0e8..b1015f46435 100644 --- a/test/hotspot/jtreg/gc/logging/TestGCId.java +++ b/test/hotspot/jtreg/gc/logging/TestGCId.java @@ -73,9 +73,9 @@ private static void verifyContainsGCIDs(OutputAnalyzer output) { } private static void testGCId(String gcFlag) throws Exception { - ProcessBuilder pb_default = - ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", "-XX:+" + gcFlag, "-Xlog:gc", "-Xmx10M", GCTest.class.getName()); - verifyContainsGCIDs(new OutputAnalyzer(pb_default.start())); + OutputAnalyzer output = + ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+" + gcFlag, "-Xlog:gc", "-Xmx10M", GCTest.class.getName()); + verifyContainsGCIDs(output); } static class GCTest { diff --git a/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java b/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java index 260a62eb5bd..48e5a9021ee 100644 --- a/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java +++ b/test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java @@ -94,24 +94,24 @@ private static void testMetaSpaceUpdate() throws Exception { // Propagate test.src for the jar file. String testSrc= "-Dtest.src=" + System.getProperty("test.src", "."); - ProcessBuilder pb = - ProcessTools.createTestJavaProcessBuilder( - "-Xlog:gc*", - "-Xbootclasspath/a:.", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-Xmx1000M", - "-Xms1000M", - testSrc, StressMetaSpace.class.getName()); - OutputAnalyzer output = null; try { - output = new OutputAnalyzer(pb.start()); + output = ProcessTools.executeTestJava( + "-Xlog:gc*", + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-Xmx1000M", + "-Xms1000M", + testSrc, StressMetaSpace.class.getName()); + verifyContainsMetaSpaceUpdate(output); } catch (Exception e) { // For error diagnosis: print and throw. e.printStackTrace(); - output.reportDiagnosticSummary(); + if (output != null) { + output.reportDiagnosticSummary(); + } throw e; } } diff --git a/test/hotspot/jtreg/gc/logging/TestPrintReferences.java b/test/hotspot/jtreg/gc/logging/TestPrintReferences.java index 99932bc68a6..96e0e7f14d4 100644 --- a/test/hotspot/jtreg/gc/logging/TestPrintReferences.java +++ b/test/hotspot/jtreg/gc/logging/TestPrintReferences.java @@ -67,11 +67,10 @@ static String indent(int count) { } public static void testRefs() throws Exception { - ProcessBuilder pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:gc+ref+phases=debug", - "-XX:+UseG1GC", - "-Xmx32M", - GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb_enabled.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xlog:gc+ref+phases=debug", + "-XX:+UseG1GC", + "-Xmx32M", + GCTest.class.getName()); checkRefsLogFormat(output); @@ -95,14 +94,13 @@ private static void checkRefsLogFormat(OutputAnalyzer output) { } public static void testPhases(boolean parallelRefProcEnabled) throws Exception { - ProcessBuilder pb_enabled = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:gc+phases+ref=debug", - "-XX:+UseG1GC", - "-Xmx32M", - "-XX:" + (parallelRefProcEnabled ? "+" : "-") + "ParallelRefProcEnabled", - "-XX:-UseDynamicNumberOfGCThreads", - "-XX:ParallelGCThreads=2", - GCTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb_enabled.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xlog:gc+phases+ref=debug", + "-XX:+UseG1GC", + "-Xmx32M", + "-XX:" + (parallelRefProcEnabled ? "+" : "-") + "ParallelRefProcEnabled", + "-XX:-UseDynamicNumberOfGCThreads", + "-XX:ParallelGCThreads=2", + GCTest.class.getName()); checkLogFormat(output, parallelRefProcEnabled); checkLogValue(output); diff --git a/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java b/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java index 30553a7b8c6..5955006ec0f 100644 --- a/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java +++ b/test/hotspot/jtreg/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java @@ -77,9 +77,8 @@ public static void main(String[] args) throws Exception { } private static void run(ProcessBuilder pb) throws Exception { - Process p = pb.start(); - p.waitFor(); - int exitValue = p.exitValue(); + OutputAnalyzer output = ProcessTools.executeProcess(pb); + int exitValue = output.getExitValue(); if (exitValue != 0) { throw new Exception("jmap -heap exited with error code: " + exitValue); } diff --git a/test/hotspot/jtreg/gc/metaspace/TestMetaspaceSizeFlags.java b/test/hotspot/jtreg/gc/metaspace/TestMetaspaceSizeFlags.java index eda71fa9c4b..7e6066557dd 100644 --- a/test/hotspot/jtreg/gc/metaspace/TestMetaspaceSizeFlags.java +++ b/test/hotspot/jtreg/gc/metaspace/TestMetaspaceSizeFlags.java @@ -84,13 +84,12 @@ private static MetaspaceFlags runAndGetValue(long maxMetaspaceSize, long metaspa } private static OutputAnalyzer run(long maxMetaspaceSize, long metaspaceSize) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + return ProcessTools.executeLimitedTestJava( "-XX:MaxMetaspaceSize=" + maxMetaspaceSize, "-XX:MetaspaceSize=" + metaspaceSize, "-XX:-UseLargePages", // Prevent us from using 2GB large pages on solaris + sparc. "-XX:+PrintFlagsFinal", "-version"); - return new OutputAnalyzer(pb.start()); } private static class MetaspaceFlags { diff --git a/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java b/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java index a87ed22e15b..458a90b08a4 100644 --- a/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java +++ b/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java @@ -119,8 +119,7 @@ public static void main(String... args) throws Exception { System.out.println(" " + a); } - final ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(jvmArgs); - final OutputAnalyzer output = new OutputAnalyzer(pb.start()); + final OutputAnalyzer output = ProcessTools.executeLimitedTestJava(jvmArgs); System.out.println(output.getStdout()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/serial/HeapChangeLogging.java b/test/hotspot/jtreg/gc/serial/HeapChangeLogging.java index 8480d046dfb..486fdbe0ed1 100644 --- a/test/hotspot/jtreg/gc/serial/HeapChangeLogging.java +++ b/test/hotspot/jtreg/gc/serial/HeapChangeLogging.java @@ -41,8 +41,7 @@ public class HeapChangeLogging { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xmx128m", "-Xmn100m", "-XX:+UseSerialGC", "-Xlog:gc", HeapFiller.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xmx128m", "-Xmn100m", "-XX:+UseSerialGC", "-Xlog:gc", HeapFiller.class.getName()); String stdout = output.getStdout(); System.out.println(stdout); Matcher stdoutMatcher = Pattern.compile(".*\\(Allocation Failure\\) [0-9]+[KMG]->[0-9]+[KMG]\\([0-9]+[KMG]\\)", Pattern.MULTILINE).matcher(stdout); diff --git a/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java b/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java index 67690d8cad5..8765105b5c0 100644 --- a/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java +++ b/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java @@ -56,14 +56,13 @@ public static void main(String[] args) throws Exception { for (int c = 0; c < NUM_RUNS; c++) { Callable task = () -> { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xms128m", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-Xms128m", "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahGCHeuristics=aggressive", "TestEvilSyncBug", "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); return null; }; diff --git a/test/hotspot/jtreg/gc/shenandoah/TestJcmdHeapDump.java b/test/hotspot/jtreg/gc/shenandoah/TestJcmdHeapDump.java index cc5bc5d425e..40a36d0a5ef 100644 --- a/test/hotspot/jtreg/gc/shenandoah/TestJcmdHeapDump.java +++ b/test/hotspot/jtreg/gc/shenandoah/TestJcmdHeapDump.java @@ -127,6 +127,7 @@ */ import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import java.io.File; @@ -141,11 +142,7 @@ public static void main(String[] args) { jcmd.addToolArg(dumpFileName); try { - ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand()); - Process jcmdProc = pb.start(); - - OutputAnalyzer output = new OutputAnalyzer(jcmdProc); - jcmdProc.waitFor(); + OutputAnalyzer output = ProcessTools.executeProcess(jcmd.getCommand()); output.shouldHaveExitValue(0); } catch (Exception e) { throw new RuntimeException("Test failed: " + e); diff --git a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java index c0161b7a238..a0612a60a9f 100644 --- a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java +++ b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java @@ -41,9 +41,8 @@ public static void testWith(String... args) throws Exception { String[] cmds = Arrays.copyOf(args, args.length + 2); cmds[args.length] = TestObjItrWithHeapDump.class.getName(); cmds[args.length + 1] = "test"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(cmds); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); output.shouldContain("Class Histogram (before full gc)"); output.shouldContain("Class Histogram (after full gc)"); diff --git a/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java b/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java index b65aa0cd0b4..3a5780069ef 100644 --- a/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java +++ b/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java @@ -42,9 +42,8 @@ public static void testWith(String msg, boolean periodic, String... args) throws String[] cmds = Arrays.copyOf(args, args.length + 2); cmds[args.length] = TestPeriodicGC.class.getName(); cmds[args.length + 1] = "test"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(cmds); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); if (periodic && !output.getOutput().contains("Trigger: Time since last GC")) { throw new AssertionError(msg + ": Should have periodic GC in logs"); diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargeObj.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargeObj.java index 1057eb4a977..f9e660cb200 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargeObj.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargeObj.java @@ -55,27 +55,25 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx16m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocLargeObj.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(1); analyzer.shouldContain("java.lang.OutOfMemoryError: Java heap space"); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx1g", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocLargeObj.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(0); analyzer.shouldNotContain("java.lang.OutOfMemoryError: Java heap space"); } diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargerThanHeap.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargerThanHeap.java index 1567e3d05da..a87fda5c98d 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargerThanHeap.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocLargerThanHeap.java @@ -50,27 +50,25 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx16m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocLargerThanHeap.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(1); analyzer.shouldContain("java.lang.OutOfMemoryError: Java heap space"); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx1g", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocLargerThanHeap.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(0); analyzer.shouldNotContain("java.lang.OutOfMemoryError: Java heap space"); } diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocSmallObj.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocSmallObj.java index bc32c1f0aa0..572351b498f 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocSmallObj.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestAllocSmallObj.java @@ -54,27 +54,25 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx16m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocSmallObj.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(1); analyzer.shouldContain("java.lang.OutOfMemoryError: Java heap space"); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx1g", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestAllocSmallObj.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(0); analyzer.shouldNotContain("java.lang.OutOfMemoryError: Java heap space"); } diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java index beb57b0b401..9d17e916089 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java @@ -99,9 +99,7 @@ public static void testWith(boolean shouldPass, String... args) throws Exception pbArgs.add(TestClassLoaderLeak.class.getName()); pbArgs.add("test"); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(pbArgs.toArray(new String[0])); - - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava(pbArgs.toArray(new String[0])); if (shouldPass) { analyzer.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java index 75cb2d5c31a..fea5761df2f 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestThreadFailure.java @@ -62,14 +62,13 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer analyzer = ProcessTools.executeLimitedTestJava( "-Xmx32m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", TestThreadFailure.class.getName(), "test"); - OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); analyzer.shouldHaveExitValue(0); analyzer.shouldContain("java.lang.OutOfMemoryError"); analyzer.shouldContain("All good"); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestArgumentRanges.java b/test/hotspot/jtreg/gc/shenandoah/options/TestArgumentRanges.java index 2cc2c2c2197..597d9a74c1d 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestArgumentRanges.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestArgumentRanges.java @@ -46,36 +46,33 @@ public static void main(String[] args) throws Exception { private static void testHeuristics() throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahGCHeuristics=aggressive", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahGCHeuristics=static", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahGCHeuristics=fluff", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Unknown -XX:ShenandoahGCHeuristics option"); output.shouldHaveExitValue(1); } @@ -83,47 +80,43 @@ private static void testHeuristics() throws Exception { private static void testRange(String option, int min, int max) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:" + option + "=" + (max + 1), "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:" + option + "=" + max, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:" + option + "=" + (min - 1), "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:" + option + "=" + min, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestClassUnloadingArguments.java b/test/hotspot/jtreg/gc/shenandoah/options/TestClassUnloadingArguments.java index c575b51084c..bf49ad3ec9c 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestClassUnloadingArguments.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestClassUnloadingArguments.java @@ -43,8 +43,7 @@ public static void testWith(String msg, boolean cu, boolean cuConc, String... ar cmds[args.length] = "-Xmx128m"; cmds[args.length + 1] = "-XX:+PrintFlagsFinal"; cmds[args.length + 2] = "-version"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(cmds); output.shouldHaveExitValue(0); output.shouldContain("ClassUnloading"); output.shouldContain("ClassUnloadingWithConcurrentMark"); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java index 49e7c417130..7fe5d56f7de 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java @@ -60,14 +60,13 @@ public static void main(String[] args) throws Exception { }; { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xlog:gc", TestExplicitGC.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : full) { output.shouldNotContain(p); } @@ -77,7 +76,7 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", @@ -85,7 +84,6 @@ public static void main(String[] args) throws Exception { "-XX:+DisableExplicitGC", TestExplicitGC.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : full) { output.shouldNotContain(p); } @@ -95,7 +93,7 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", @@ -103,7 +101,6 @@ public static void main(String[] args) throws Exception { "-XX:+ExplicitGCInvokesConcurrent", TestExplicitGC.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : full) { output.shouldNotContain(p); } @@ -113,7 +110,7 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", @@ -121,7 +118,6 @@ public static void main(String[] args) throws Exception { "-XX:-ExplicitGCInvokesConcurrent", TestExplicitGC.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : full) { output.shouldContain(p); } @@ -131,7 +127,7 @@ public static void main(String[] args) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", @@ -140,7 +136,6 @@ public static void main(String[] args) throws Exception { "-XX:ShenandoahGCMode=iu", TestExplicitGC.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : full) { output.shouldNotContain(p); } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGCNoConcurrent.java b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGCNoConcurrent.java index 6499457b667..176e4a2ca7a 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGCNoConcurrent.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGCNoConcurrent.java @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception { }; for (String opt : opts) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", @@ -70,7 +70,6 @@ public static void main(String[] args) throws Exception { "-XX:ShenandoahGCHeuristics=passive", TestExplicitGCNoConcurrent.class.getName(), "test"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (String p : concurrent) { output.shouldNotContain(p); } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java index c9f1c75b4e1..9d0065fe803 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java @@ -52,7 +52,7 @@ public static void main(String[] args) throws Exception { private static void testWith(String h, Mode mode) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:-UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", @@ -60,7 +60,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: output.shouldHaveExitValue(0); @@ -73,7 +72,7 @@ private static void testWith(String h, Mode mode) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", @@ -81,7 +80,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: case DIAGNOSTIC: @@ -94,7 +92,7 @@ private static void testWith(String h, Mode mode) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:-UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -102,7 +100,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: case EXPERIMENTAL: diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestHumongousThresholdArgs.java b/test/hotspot/jtreg/gc/shenandoah/options/TestHumongousThresholdArgs.java index 523f434dbbd..47d4115ce74 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestHumongousThresholdArgs.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHumongousThresholdArgs.java @@ -38,12 +38,11 @@ public class TestHumongousThresholdArgs { public static void main(String[] args) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } @@ -51,24 +50,22 @@ public static void main(String[] args) throws Exception { int[] invalid = new int[] {-100, -1, 0, 101, 1000}; for (int v : valid) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahHumongousThreshold=" + v, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } for (int v : invalid) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-XX:ShenandoahHumongousThreshold=" + v, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); } } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestLoopMiningArguments.java b/test/hotspot/jtreg/gc/shenandoah/options/TestLoopMiningArguments.java index 79452b6cbc5..6d37b2877da 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestLoopMiningArguments.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestLoopMiningArguments.java @@ -44,8 +44,7 @@ public static void testWith(String msg, boolean cls, int iters, String... args) cmds[args.length] = "-Xmx128m"; cmds[args.length + 1] = "-XX:+PrintFlagsFinal"; cmds[args.length + 2] = "-version"; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(cmds); output.shouldHaveExitValue(0); output.shouldContain("UseCountedLoopSafepoints"); output.shouldContain("LoopStripMiningIter"); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java b/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java index 0c8fea7f993..802038363b5 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java @@ -51,7 +51,7 @@ public static void main(String[] args) throws Exception { private static void testWith(String h, Mode mode) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:-UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", @@ -59,7 +59,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: output.shouldHaveExitValue(0); @@ -72,7 +71,7 @@ private static void testWith(String h, Mode mode) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:-UnlockExperimentalVMOptions", @@ -80,7 +79,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: case DIAGNOSTIC: @@ -93,7 +91,7 @@ private static void testWith(String h, Mode mode) throws Exception { } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:-UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -101,7 +99,6 @@ private static void testWith(String h, Mode mode) throws Exception { h, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); switch (mode) { case PRODUCT: case EXPERIMENTAL: diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java b/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java index 79d0b517e89..a8d5155584b 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java @@ -45,113 +45,103 @@ public static void main(String[] args) throws Exception { private static void testInvalidRegionSizes() throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms4m", "-Xmx1g", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms8m", "-Xmx1g", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahRegionSize=200m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahRegionSize=9m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahRegionSize=255K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahRegionSize=260K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms1g", "-Xmx1g", "-XX:ShenandoahRegionSize=32M", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms1g", "-Xmx1g", "-XX:ShenandoahRegionSize=64M", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms1g", "-Xmx1g", "-XX:ShenandoahRegionSize=256K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms1g", "-Xmx1g", "-XX:ShenandoahRegionSize=128K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahRegionSize option"); output.shouldHaveExitValue(1); } @@ -160,49 +150,45 @@ private static void testInvalidRegionSizes() throws Exception { private static void testMinRegionSize() throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMinRegionSize=255K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahMinRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMinRegionSize=1M", "-XX:ShenandoahMaxRegionSize=260K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahMinRegionSize or -XX:ShenandoahMaxRegionSize"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMinRegionSize=200m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahMinRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMinRegionSize=9m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } @@ -211,26 +197,24 @@ private static void testMinRegionSize() throws Exception { private static void testMaxRegionSize() throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMaxRegionSize=255K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahMaxRegionSize option"); output.shouldHaveExitValue(1); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms100m", "-Xmx1g", "-XX:ShenandoahMinRegionSize=1M", "-XX:ShenandoahMaxRegionSize=260K", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("Invalid -XX:ShenandoahMinRegionSize or -XX:ShenandoahMaxRegionSize"); output.shouldHaveExitValue(1); } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java b/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java index 5b34bfab3a0..094e62f53f3 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java @@ -89,8 +89,7 @@ public static void main(String[] args) throws Exception { pool.submit(() -> { try { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(conf.toArray(new String[0])); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(conf.toArray(new String[0])); output.shouldHaveExitValue(0); } catch (Exception e) { e.printStackTrace(); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestSoftMaxHeapSize.java b/test/hotspot/jtreg/gc/shenandoah/options/TestSoftMaxHeapSize.java index 78bbf75189c..212ffb41037 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestSoftMaxHeapSize.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestSoftMaxHeapSize.java @@ -38,35 +38,32 @@ public class TestSoftMaxHeapSize { public static void main(String[] args) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms4m", "-Xmx128m", "-XX:SoftMaxHeapSize=4m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms4m", "-Xmx128m", "-XX:SoftMaxHeapSize=128m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions", + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UnlockExperimentalVMOptions", "-XX:+UseShenandoahGC", "-Xms4m", "-Xmx128m", "-XX:SoftMaxHeapSize=129m", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); output.shouldContain("SoftMaxHeapSize must be less than or equal to the maximum heap size"); } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java index f7f9ee56b59..90985eb4c4d 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java @@ -45,7 +45,7 @@ public static void main(String[] args) throws Exception { } private static void testWith(int conc, int par) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -53,7 +53,6 @@ private static void testWith(int conc, int par) throws Exception { "-XX:ConcGCThreads=" + conc, "-XX:ParallelGCThreads=" + par, "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); if (conc == 0) { output.shouldContain("Shenandoah expects ConcGCThreads > 0"); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java index 5e63595e726..b3d8ba34567 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java @@ -38,7 +38,7 @@ public class TestThreadCountsOverride { public static void main(String[] args) throws Exception { { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -46,14 +46,13 @@ public static void main(String[] args) throws Exception { "-XX:ParallelGCThreads=1", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("ParallelGCThreads(.*)= 1 "); output.shouldHaveExitValue(0); } { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -61,7 +60,6 @@ public static void main(String[] args) throws Exception { "-XX:ConcGCThreads=1", "-XX:+PrintFlagsFinal", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldMatch("ConcGCThreads(.*)= 1 "); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java index 0e913375534..aa6b7935649 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java @@ -63,7 +63,7 @@ public static void main(String[] args) throws Exception { private static void shouldFailAll(String h, String[] barriers) throws Exception { for (String b : barriers) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -72,7 +72,6 @@ private static void shouldFailAll(String h, String[] barriers) throws Exception "-XX:-" + b, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); output.shouldContain("GC mode needs "); output.shouldContain("to work correctly"); @@ -81,7 +80,7 @@ private static void shouldFailAll(String h, String[] barriers) throws Exception private static void shouldPassAll(String h, String[] barriers) throws Exception { for (String b : barriers) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -90,7 +89,6 @@ private static void shouldPassAll(String h, String[] barriers) throws Exception "-XX:-" + b, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierEnable.java b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierEnable.java index 84645621eb4..486860728ab 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierEnable.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierEnable.java @@ -55,7 +55,7 @@ public static void main(String[] args) throws Exception { private static void shouldFailAll(String h, String[] barriers) throws Exception { for (String b : barriers) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -64,7 +64,6 @@ private static void shouldFailAll(String h, String[] barriers) throws Exception "-XX:+" + b, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); output.shouldContain("GC mode needs "); output.shouldContain("to work correctly"); @@ -73,7 +72,7 @@ private static void shouldFailAll(String h, String[] barriers) throws Exception private static void shouldPassAll(String h, String[] barriers) throws Exception { for (String b : barriers) { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-Xmx128m", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockExperimentalVMOptions", @@ -82,7 +81,6 @@ private static void shouldPassAll(String h, String[] barriers) throws Exception "-XX:+" + b, "-version" ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java b/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java index 3114117a1ef..0d7e26c91d8 100644 --- a/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java +++ b/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java @@ -61,8 +61,8 @@ public static void main(String[] args) throws Exception { "-XX:+PrintNMTStatistics" )); baseargs.addAll(Arrays.asList(args)); baseargs.add(GCTest.class.getName()); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(baseargs); - verifySymbolMemoryUsageNotTooHigh(new OutputAnalyzer(pb.start())); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(baseargs); + verifySymbolMemoryUsageNotTooHigh(output); } private static void verifySymbolMemoryUsageNotTooHigh(OutputAnalyzer output) throws Exception { diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java b/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java index 2a02039c60e..70544e8af31 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Humongous.java @@ -101,8 +101,7 @@ public static void main(String[] args) throws Exception { "-Dregionsize=" + regionSize, TestStressG1HumongousImpl.class.getName() ); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(options); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(options); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java index 2f61c166cb8..d3575e8cd4b 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java @@ -59,8 +59,7 @@ public static void main(String[] args) throws Exception { "-XX:+UseG1GC", StressUncommit.class.getName() ); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(options); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeLimitedTestJava(options); output.shouldHaveExitValue(0); output.shouldMatch("Uncommit regions"); output.outputTo(System.out); diff --git a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java index 31c11b66dfc..8b8fea1f2e3 100644 --- a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java +++ b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java @@ -299,8 +299,7 @@ private static OutputAnalyzer runTest(String... extraArgs) throws Exception { args.addAll(Arrays.asList(defaultArgs)); args.addAll(Arrays.asList(extraArgs)); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(args); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeTestJava(args); System.err.println(output.getStderr()); System.out.println(output.getStdout()); return output; diff --git a/test/hotspot/jtreg/gc/testlibrary/Helpers.java b/test/hotspot/jtreg/gc/testlibrary/Helpers.java index 225a5bda0e6..03d67e44455 100644 --- a/test/hotspot/jtreg/gc/testlibrary/Helpers.java +++ b/test/hotspot/jtreg/gc/testlibrary/Helpers.java @@ -25,6 +25,7 @@ import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; import jdk.test.whitebox.WhiteBox; import java.io.File; @@ -89,7 +90,7 @@ public static int detectByteArrayAllocationOverhead() { * @param source class source * @throws IOException if cannot write file to specified directory */ - public static void compileClass(String className, Path root, String source) throws IOException { + public static void compileClass(String className, Path root, String source) throws Exception { Path sourceFile = root.resolve(className + ".java"); Files.write(sourceFile, source.getBytes()); @@ -100,8 +101,7 @@ public static void compileClass(String className, Path root, String source) thro .addToolArg(System.getProperty("java.class.path") + File.pathSeparator + root.toAbsolutePath()) .addToolArg(sourceFile.toAbsolutePath().toString()); - ProcessBuilder pb = new ProcessBuilder(jar.getCommand()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = ProcessTools.executeProcess(jar.getCommand()); output.shouldHaveExitValue(0); } @@ -199,12 +199,11 @@ public static String enumNameToClassName(String enumName) { * @param prefix prefix for service classes (ones we use to create chain of inheritance). * The names will be prefix_1, prefix_2,.., prefix_n * @return Class object of generated and compiled class loaded in specified class loader - * @throws IOException - * @throws ClassNotFoundException + * @throws Exception */ public static Class generateCompileAndLoad(ClassLoader classLoader, String className, long instanceSize, Path workDir, String prefix) - throws IOException, ClassNotFoundException { + throws Exception { generateByTemplateAndCompile(className, null, "public class ${ClassName} extends ${BaseClass} {\n${Fields}}\n", "", instanceSize, workDir, prefix); @@ -243,11 +242,11 @@ public static Class generateCompileAndLoad(ClassLoader classLoader, String cl * @param prefix prefix for service classes (ones we use to create chain of inheritance). * The names will be prefix_1, prefix_2,.., prefix_n * @return Class object of generated and compiled class loaded in specified class loader - * @throws IOException if cannot write or read to workDir + * @throws Exception if cannot write or read to workDir */ public static void generateByTemplateAndCompile(String className, String baseClass, String classTemplate, String constructorTemplate, long instanceSize, Path workDir, - String prefix) throws IOException { + String prefix) throws Exception { if (instanceSize % SIZE_OF_LONG != 0L) { throw new Error(String.format("Test bug: only sizes aligned by %d bytes are supported and %d was specified", diff --git a/test/hotspot/jtreg/gc/whitebox/TestWBGC.java b/test/hotspot/jtreg/gc/whitebox/TestWBGC.java index c2fe2633e4e..38f3593b638 100644 --- a/test/hotspot/jtreg/gc/whitebox/TestWBGC.java +++ b/test/hotspot/jtreg/gc/whitebox/TestWBGC.java @@ -43,7 +43,7 @@ public class TestWBGC { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + OutputAnalyzer output = ProcessTools.executeTestJava( "-Xbootclasspath/a:.", "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", @@ -51,7 +51,6 @@ public static void main(String args[]) throws Exception { "-Xlog:gc", GCYoungTest.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println(output.getStdout()); output.shouldHaveExitValue(0); output.shouldContain("WhiteBox Initiated Young GC"); diff --git a/test/hotspot/jtreg/gc/x/TestAllocateHeapAt.java b/test/hotspot/jtreg/gc/x/TestAllocateHeapAt.java index de3d1f585a7..3bf83d90768 100644 --- a/test/hotspot/jtreg/gc/x/TestAllocateHeapAt.java +++ b/test/hotspot/jtreg/gc/x/TestAllocateHeapAt.java @@ -41,16 +41,16 @@ public static void main(String[] args) throws Exception { final String heapBackingFile = "Heap Backing File: " + directory; final String failedToCreateFile = "Failed to create file " + directory; - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:-ZGenerational", - "-Xlog:gc*", - "-Xms32M", - "-Xmx32M", - "-XX:AllocateHeapAt=" + directory, - "-version")) - .shouldContain(exists ? heapBackingFile : failedToCreateFile) - .shouldNotContain(exists ? failedToCreateFile : heapBackingFile) - .shouldHaveExitValue(exists ? 0 : 1); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:-ZGenerational", + "-Xlog:gc*", + "-Xms32M", + "-Xmx32M", + "-XX:AllocateHeapAt=" + directory, + "-version") + .shouldContain(exists ? heapBackingFile : failedToCreateFile) + .shouldNotContain(exists ? failedToCreateFile : heapBackingFile) + .shouldHaveExitValue(exists ? 0 : 1); } } diff --git a/test/hotspot/jtreg/gc/x/TestPageCacheFlush.java b/test/hotspot/jtreg/gc/x/TestPageCacheFlush.java index 5a20ee8322a..cb8685d0d09 100644 --- a/test/hotspot/jtreg/gc/x/TestPageCacheFlush.java +++ b/test/hotspot/jtreg/gc/x/TestPageCacheFlush.java @@ -68,16 +68,16 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:-ZGenerational", - "-Xms128M", - "-Xmx128M", - "-Xlog:gc,gc+init,gc+heap=debug", - Test.class.getName())) - .outputTo(System.out) - .errorTo(System.out) - .shouldContain("Page Cache Flushed:") - .shouldHaveExitValue(0); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:-ZGenerational", + "-Xms128M", + "-Xmx128M", + "-Xlog:gc,gc+init,gc+heap=debug", + Test.class.getName()) + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("Page Cache Flushed:") + .shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/x/TestSmallHeap.java b/test/hotspot/jtreg/gc/x/TestSmallHeap.java index 0fc6477b59b..8fc6f07be39 100644 --- a/test/hotspot/jtreg/gc/x/TestSmallHeap.java +++ b/test/hotspot/jtreg/gc/x/TestSmallHeap.java @@ -53,16 +53,16 @@ public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception { for (var maxCapacity: args) { - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:-ZGenerational", - "-Xlog:gc,gc+init,gc+reloc,gc+heap", - "-Xmx" + maxCapacity, - Test.class.getName())) - .outputTo(System.out) - .errorTo(System.out) - .shouldContain("Success") - .shouldHaveExitValue(0); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:-ZGenerational", + "-Xlog:gc,gc+init,gc+reloc,gc+heap", + "-Xmx" + maxCapacity, + Test.class.getName()) + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("Success") + .shouldHaveExitValue(0); } } } diff --git a/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java b/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java index f5a6113f6ff..9f47c4b60d3 100644 --- a/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java +++ b/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java @@ -41,16 +41,16 @@ public static void main(String[] args) throws Exception { final String heapBackingFile = "Heap Backing File: " + directory; final String failedToCreateFile = "Failed to create file " + directory; - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:+ZGenerational", - "-Xlog:gc*", - "-Xms32M", - "-Xmx32M", - "-XX:AllocateHeapAt=" + directory, - "-version")) - .shouldContain(exists ? heapBackingFile : failedToCreateFile) - .shouldNotContain(exists ? failedToCreateFile : heapBackingFile) - .shouldHaveExitValue(exists ? 0 : 1); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:+ZGenerational", + "-Xlog:gc*", + "-Xms32M", + "-Xmx32M", + "-XX:AllocateHeapAt=" + directory, + "-version") + .shouldContain(exists ? heapBackingFile : failedToCreateFile) + .shouldNotContain(exists ? failedToCreateFile : heapBackingFile) + .shouldHaveExitValue(exists ? 0 : 1); } } diff --git a/test/hotspot/jtreg/gc/z/TestPageCacheFlush.java b/test/hotspot/jtreg/gc/z/TestPageCacheFlush.java index 629edccd496..387053b580a 100644 --- a/test/hotspot/jtreg/gc/z/TestPageCacheFlush.java +++ b/test/hotspot/jtreg/gc/z/TestPageCacheFlush.java @@ -68,16 +68,16 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:+ZGenerational", - "-Xms128M", - "-Xmx128M", - "-Xlog:gc,gc+init,gc+heap=debug", - Test.class.getName())) - .outputTo(System.out) - .errorTo(System.out) - .shouldContain("Page Cache Flushed:") - .shouldHaveExitValue(0); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:+ZGenerational", + "-Xms128M", + "-Xmx128M", + "-Xlog:gc,gc+init,gc+heap=debug", + Test.class.getName()) + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("Page Cache Flushed:") + .shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/gc/z/TestSmallHeap.java b/test/hotspot/jtreg/gc/z/TestSmallHeap.java index bfe1c0310ca..354cd4164f1 100644 --- a/test/hotspot/jtreg/gc/z/TestSmallHeap.java +++ b/test/hotspot/jtreg/gc/z/TestSmallHeap.java @@ -53,16 +53,16 @@ public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception { for (var maxCapacity: args) { - ProcessTools.executeProcess(ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:+ZGenerational", - "-Xlog:gc,gc+init,gc+reloc,gc+heap", - "-Xmx" + maxCapacity, - Test.class.getName())) - .outputTo(System.out) - .errorTo(System.out) - .shouldContain("Success") - .shouldHaveExitValue(0); + ProcessTools.executeLimitedTestJava( + "-XX:+UseZGC", + "-XX:+ZGenerational", + "-Xlog:gc,gc+init,gc+reloc,gc+heap", + "-Xmx" + maxCapacity, + Test.class.getName()) + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("Success") + .shouldHaveExitValue(0); } } } diff --git a/test/hotspot/jtreg/gc/z/TestZForceDiscontiguousHeapReservations.java b/test/hotspot/jtreg/gc/z/TestZForceDiscontiguousHeapReservations.java index 2993038faa5..f1a14f0cf90 100644 --- a/test/hotspot/jtreg/gc/z/TestZForceDiscontiguousHeapReservations.java +++ b/test/hotspot/jtreg/gc/z/TestZForceDiscontiguousHeapReservations.java @@ -45,17 +45,17 @@ private static void testValue(int n) throws Exception { */ final int XmxInM = 2000; final int XmsInM = Math.min(16 * XmxInM / (n + 1), XmxInM); - OutputAnalyzer oa = ProcessTools.executeProcess(ProcessTools.createTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:+ZGenerational", - "-Xms" + XmsInM + "M", - "-Xmx" + XmxInM + "M", - "-Xlog:gc,gc+init", - "-XX:ZForceDiscontiguousHeapReservations=" + n, - "-version")) - .outputTo(System.out) - .errorTo(System.out) - .shouldHaveExitValue(0); + OutputAnalyzer oa = ProcessTools.executeTestJava( + "-XX:+UseZGC", + "-XX:+ZGenerational", + "-Xms" + XmsInM + "M", + "-Xmx" + XmxInM + "M", + "-Xlog:gc,gc+init", + "-XX:ZForceDiscontiguousHeapReservations=" + n, + "-version") + .outputTo(System.out) + .errorTo(System.out) + .shouldHaveExitValue(0); if (n > 1) { oa.shouldContain("Address Space Type: Discontiguous"); } diff --git a/test/hotspot/jtreg/gc/z/TestZNMT.java b/test/hotspot/jtreg/gc/z/TestZNMT.java index 066ebd063f6..db37a0e1e14 100644 --- a/test/hotspot/jtreg/gc/z/TestZNMT.java +++ b/test/hotspot/jtreg/gc/z/TestZNMT.java @@ -68,21 +68,21 @@ private static void testValue(int zForceDiscontiguousHeapReservations) throws Ex * reservations. */ final int XmsInM = Math.min(16 * XmxInM / (zForceDiscontiguousHeapReservations + 1), XmxInM); - OutputAnalyzer oa = ProcessTools.executeProcess(ProcessTools.createTestJavaProcessBuilder( - "-XX:+UseZGC", - "-XX:+ZGenerational", - "-Xms" + XmsInM + "M", - "-Xmx" + XmxInM + "M", - "-Xlog:gc,gc+init", - "-XX:ZForceDiscontiguousHeapReservations=" + zForceDiscontiguousHeapReservations, - "-XX:NativeMemoryTracking=detail", - "-XX:+PrintNMTStatistics", - Test.class.getName(), - Integer.toString(zForceDiscontiguousHeapReservations), - Integer.toString(XmxInM))) - .outputTo(System.out) - .errorTo(System.out) - .shouldHaveExitValue(0); + OutputAnalyzer oa = ProcessTools.executeTestJava( + "-XX:+UseZGC", + "-XX:+ZGenerational", + "-Xms" + XmsInM + "M", + "-Xmx" + XmxInM + "M", + "-Xlog:gc,gc+init", + "-XX:ZForceDiscontiguousHeapReservations=" + zForceDiscontiguousHeapReservations, + "-XX:NativeMemoryTracking=detail", + "-XX:+PrintNMTStatistics", + Test.class.getName(), + Integer.toString(zForceDiscontiguousHeapReservations), + Integer.toString(XmxInM)) + .outputTo(System.out) + .errorTo(System.out) + .shouldHaveExitValue(0); if (zForceDiscontiguousHeapReservations > 1) { oa.shouldContain("Address Space Type: Discontiguous"); } From 20da646c37a2170eebffb9fd2eb36814d805f63c Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 23 May 2024 12:25:50 +0000 Subject: [PATCH 290/298] 8329605: hs errfile generic events - move memory protections and nmethod flushes to separate sections Backport-of: 397d94831033e91c7a849774bf4e80d8f1c8ec66 --- src/hotspot/os/aix/os_aix.cpp | 2 +- src/hotspot/os/bsd/os_bsd.cpp | 6 +++--- src/hotspot/os/linux/os_linux.cpp | 2 +- src/hotspot/share/code/nmethod.cpp | 2 +- src/hotspot/share/utilities/events.cpp | 6 +++++- src/hotspot/share/utilities/events.hpp | 30 +++++++++++++++++++++++++- 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index d73a847b2b6..57092b0b065 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1997,7 +1997,7 @@ static bool checked_mprotect(char* addr, size_t size, int prot) { // // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm - Events::log(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); + Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); bool rc = ::mprotect(addr, size, prot) == 0 ? true : false; if (!rc) { diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index e2c5c5b9819..f1f1274a354 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1511,7 +1511,7 @@ bool os::pd_commit_memory(char* addr, size_t size, bool exec) { int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; #if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD - Events::log(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); + Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); if (::mprotect(addr, size, prot) == 0) { return true; } @@ -1613,7 +1613,7 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) { #if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD - Events::log(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size)); + Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size)); return ::mprotect(addr, size, PROT_NONE) == 0; #elif defined(__APPLE__) if (exec) { @@ -1683,7 +1683,7 @@ static bool bsd_mprotect(char* addr, size_t size, int prot) { assert(addr == bottom, "sanity check"); size = align_up(pointer_delta(addr, bottom, 1) + size, os::vm_page_size()); - Events::log(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); + Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); return ::mprotect(bottom, size, prot) == 0; } diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index b3aee9b24bc..3a47e43a6fe 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -3551,7 +3551,7 @@ static bool linux_mprotect(char* addr, size_t size, int prot) { #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if (addr != g_assert_poison) #endif - Events::log(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); + Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot); return ::mprotect(bottom, size, prot) == 0; } diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 0a82827bd33..c07b5e28c17 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1450,7 +1450,7 @@ void nmethod::purge(bool free_code_cache_data, bool unregister_nmethod) { MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); // completely deallocate this method - Events::log(Thread::current(), "flushing nmethod " INTPTR_FORMAT, p2i(this)); + Events::log_nmethod_flush(Thread::current(), "flushing %s nmethod " INTPTR_FORMAT, is_osr_method() ? "osr" : "", p2i(this)); log_debug(codecache)("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", is_osr_method() ? "osr" : "",_compile_id, p2i(this), CodeCache::blob_count(), diff --git a/src/hotspot/share/utilities/events.cpp b/src/hotspot/share/utilities/events.cpp index c47c466372e..f11b7c5bfc3 100644 --- a/src/hotspot/share/utilities/events.cpp +++ b/src/hotspot/share/utilities/events.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -35,6 +35,8 @@ EventLog* Events::_logs = nullptr; StringEventLog* Events::_messages = nullptr; +StringEventLog* Events::_memprotect_messages = nullptr; +StringEventLog* Events::_nmethod_flush_messages = nullptr; StringEventLog* Events::_vm_operations = nullptr; StringEventLog* Events::_zgc_phase_switch = nullptr; ExceptionsEventLog* Events::_exceptions = nullptr; @@ -95,6 +97,8 @@ void Events::print() { void Events::init() { if (LogEvents) { _messages = new StringEventLog("Events", "events"); + _nmethod_flush_messages = new StringEventLog("Nmethod flushes", "nmethodflushes"); + _memprotect_messages = new StringEventLog("Memory protections", "memprotects"); _vm_operations = new StringEventLog("VM Operations", "vmops"); _zgc_phase_switch = new StringEventLog("ZGC Phase Switch", "zgcps"); _exceptions = new ExceptionsEventLog("Internal exceptions", "exc"); diff --git a/src/hotspot/share/utilities/events.hpp b/src/hotspot/share/utilities/events.hpp index f7d2d193a86..4470002a1e3 100644 --- a/src/hotspot/share/utilities/events.hpp +++ b/src/hotspot/share/utilities/events.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, 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 @@ -220,6 +220,12 @@ class Events : AllStatic { // A log for generic messages that aren't well categorized. static StringEventLog* _messages; + // A log for memory protection related messages + static StringEventLog* _memprotect_messages; + + // A log for nmethod flush operations + static StringEventLog* _nmethod_flush_messages; + // A log for VM Operations static StringEventLog* _vm_operations; @@ -259,6 +265,10 @@ class Events : AllStatic { // Logs a generic message with timestamp and format as printf. static void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + static void log_memprotect(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + + static void log_nmethod_flush(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + static void log_vm_operation(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); static void log_zgc_phase_switch(const char* format, ...) ATTRIBUTE_PRINTF(1, 2); @@ -290,6 +300,24 @@ inline void Events::log(Thread* thread, const char* format, ...) { } } +inline void Events::log_memprotect(Thread* thread, const char* format, ...) { + if (LogEvents && _memprotect_messages != nullptr) { + va_list ap; + va_start(ap, format); + _memprotect_messages->logv(thread, format, ap); + va_end(ap); + } +} + +inline void Events::log_nmethod_flush(Thread* thread, const char* format, ...) { + if (LogEvents && _nmethod_flush_messages != nullptr) { + va_list ap; + va_start(ap, format); + _nmethod_flush_messages->logv(thread, format, ap); + va_end(ap); + } +} + inline void Events::log_vm_operation(Thread* thread, const char* format, ...) { if (LogEvents && _vm_operations != nullptr) { va_list ap; From d9860963022402b11110adb62801a2d69432d30e Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 23 May 2024 12:27:11 +0000 Subject: [PATCH 291/298] 8330464: hserr generic events - add entry for the before_exit calls Backport-of: 45ed97f15b96071e5d6b6d21e8f0129eda5aa447 --- src/hotspot/share/runtime/java.cpp | 3 +++ src/hotspot/share/runtime/threads.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index 48709aa5c43..a92a1c5d285 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -77,6 +77,7 @@ #include "sanitizers/leak.hpp" #include "services/memTracker.hpp" #include "utilities/dtrace.hpp" +#include "utilities/events.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/vmError.hpp" @@ -395,6 +396,8 @@ void before_exit(JavaThread* thread, bool halt) { #define BEFORE_EXIT_DONE 2 static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN; + Events::log(thread, "Before exit entered"); + // Note: don't use a Mutex to guard the entire before_exit(), as // JVMTI post_thread_end_event and post_vm_death_event will run native code. // A CAS or OSMutex would work just fine but then we need to manipulate diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 373d4afd4dd..ac435317d05 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -823,10 +823,10 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Threads::destroy_vm() is normally called from jni_DestroyJavaVM() when // the program falls off the end of main(). Another VM exit path is through -// vm_exit() when the program calls System.exit() to return a value or when -// there is a serious error in VM. The two shutdown paths are not exactly -// the same, but they share Shutdown.shutdown() at Java level and before_exit() -// and VM_Exit op at VM level. +// vm_exit(), when the program calls System.exit() to return a value, or when +// there is a serious error in VM. +// These two separate shutdown paths are not exactly the same, but they share +// Shutdown.shutdown() at Java level and before_exit() and VM_Exit op at VM level. // // Shutdown sequence: // + Shutdown native memory tracking if it is on From 4b1d95c73ca503e18636129a77c0d6c49aae4821 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 23 May 2024 20:29:02 +0000 Subject: [PATCH 292/298] 8329223: Parallel: Parallel GC resizes heap even if -Xms = -Xmx Backport-of: aca1e8365bf0f64bf18caf798bbca1d25b3c4117 --- src/hotspot/share/gc/shared/genArguments.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/gc/shared/genArguments.cpp b/src/hotspot/share/gc/shared/genArguments.cpp index c53fb72c459..6d569d6f717 100644 --- a/src/hotspot/share/gc/shared/genArguments.cpp +++ b/src/hotspot/share/gc/shared/genArguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -276,6 +276,9 @@ void GenArguments::initialize_size_info() { // and maximum heap size since no explicit flags exist // for setting the old generation maximum. MaxOldSize = MAX2(MaxHeapSize - max_young_size, GenAlignment); + MinOldSize = MIN3(MaxOldSize, + InitialHeapSize - initial_young_size, + MinHeapSize - MinNewSize); size_t initial_old_size = OldSize; @@ -287,9 +290,8 @@ void GenArguments::initialize_size_info() { // with the overall heap size). In either case make // the minimum, maximum and initial sizes consistent // with the young sizes and the overall heap sizes. - MinOldSize = GenAlignment; initial_old_size = clamp(InitialHeapSize - initial_young_size, MinOldSize, MaxOldSize); - // MaxOldSize has already been made consistent above. + // MaxOldSize and MinOldSize have already been made consistent above. } else { // OldSize has been explicitly set on the command line. Use it // for the initial size but make sure the minimum allow a young @@ -304,9 +306,10 @@ void GenArguments::initialize_size_info() { ", -XX:OldSize flag is being ignored", MaxHeapSize); initial_old_size = MaxOldSize; + } else if (initial_old_size < MinOldSize) { + log_warning(gc, ergo)("Inconsistency between initial old size and minimum old size"); + MinOldSize = initial_old_size; } - - MinOldSize = MIN2(initial_old_size, MinHeapSize - MinNewSize); } // The initial generation sizes should match the initial heap size, From 00d3ca21cc5d5b9c4a3a17cab8f0b44e08b46c9f Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 27 May 2024 10:17:18 +0000 Subject: [PATCH 293/298] 8331031: unify os::dont_yield and os::naked_yield across Posix platforms Backport-of: c9442014e561f8e1cb43a0e9f18a9a5ae2a7a2da --- src/hotspot/os/aix/os_aix.cpp | 9 --------- src/hotspot/os/bsd/os_bsd.cpp | 9 --------- src/hotspot/os/linux/os_linux.cpp | 19 ------------------- src/hotspot/os/posix/os_posix.cpp | 8 ++++++++ 4 files changed, 8 insertions(+), 37 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 57092b0b065..ac9b4541db3 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -2147,15 +2147,6 @@ char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool return addr; } -// Used to convert frequent JVM_Yield() to nops -bool os::dont_yield() { - return DontYieldALot; -} - -void os::naked_yield() { - sched_yield(); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index f1f1274a354..0a786ddf35c 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1784,15 +1784,6 @@ char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool return nullptr; } -// Used to convert frequent JVM_Yield() to nops -bool os::dont_yield() { - return DontYieldALot; -} - -void os::naked_yield() { - sched_yield(); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 3a47e43a6fe..492300a37d4 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -4242,25 +4242,6 @@ char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool return nullptr; } -// Used to convert frequent JVM_Yield() to nops -bool os::dont_yield() { - return DontYieldALot; -} - -// Linux CFS scheduler (since 2.6.23) does not guarantee sched_yield(2) will -// actually give up the CPU. Since skip buddy (v2.6.28): -// -// * Sets the yielding task as skip buddy for current CPU's run queue. -// * Picks next from run queue, if empty, picks a skip buddy (can be the yielding task). -// * Clears skip buddies for this run queue (yielding task no longer a skip buddy). -// -// An alternative is calling os::naked_short_nanosleep with a small number to avoid -// getting re-scheduled immediately. -// -void os::naked_yield() { - sched_yield(); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index f21c72453a9..7f95560a19e 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -840,6 +840,14 @@ void os::_exit(int num) { ALLOW_C_FUNCTION(::_exit, ::_exit(num);) } +bool os::dont_yield() { + return DontYieldALot; +} + +void os::naked_yield() { + sched_yield(); +} + // Builds a platform dependent Agent_OnLoad_ function name // which is used to find statically linked in agents. // Parameters: From 58c19a60512086a23975a4d7e595905fdbde540a Mon Sep 17 00:00:00 2001 From: Vladimir Petko Date: Mon, 27 May 2024 22:15:42 +0000 Subject: [PATCH 294/298] 8295111: dpkg appears to have problems resolving symbolically linked native libraries Backport-of: 32946e1882e9b22c983cbba3c6bda3cc7295946a --- .../jpackage/internal/LinuxDebBundler.java | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java index e97cfc90a80..478ec078797 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -201,6 +201,24 @@ protected void initLibProvidersLookup( Map params, LibProvidersLookup libProvidersLookup) { + libProvidersLookup.setPackageLookup(file -> { + Path realPath = file.toRealPath(); + + try { + // Try the real path first as it works better on newer Ubuntu versions + return findProvidingPackages(realPath); + } catch (IOException ex) { + // Try the default path if differ + if (!realPath.toString().equals(file.toString())) { + return findProvidingPackages(file); + } else { + throw ex; + } + } + }); + } + + private static Stream findProvidingPackages(Path file) throws IOException { // // `dpkg -S` command does glob pattern lookup. If not the absolute path // to the file is specified it might return mltiple package names. @@ -243,32 +261,30 @@ protected void initLibProvidersLookup( // 4. Arch suffix should be stripped from accepted package names. // - libProvidersLookup.setPackageLookup(file -> { - Set archPackages = new HashSet<>(); - Set otherPackages = new HashSet<>(); - - Executor.of(TOOL_DPKG, "-S", file.toString()) - .saveOutput(true).executeExpectSuccess() - .getOutput().forEach(line -> { - Matcher matcher = PACKAGE_NAME_REGEX.matcher(line); - if (matcher.find()) { - String name = matcher.group(1); - if (name.endsWith(":" + DEB_ARCH)) { - // Strip arch suffix - name = name.substring(0, - name.length() - (DEB_ARCH.length() + 1)); - archPackages.add(name); - } else { - otherPackages.add(name); - } + Set archPackages = new HashSet<>(); + Set otherPackages = new HashSet<>(); + + Executor.of(TOOL_DPKG, "-S", file.toString()) + .saveOutput(true).executeExpectSuccess() + .getOutput().forEach(line -> { + Matcher matcher = PACKAGE_NAME_REGEX.matcher(line); + if (matcher.find()) { + String name = matcher.group(1); + if (name.endsWith(":" + DEB_ARCH)) { + // Strip arch suffix + name = name.substring(0, + name.length() - (DEB_ARCH.length() + 1)); + archPackages.add(name); + } else { + otherPackages.add(name); } - }); + } + }); - if (!archPackages.isEmpty()) { - return archPackages.stream(); - } - return otherPackages.stream(); - }); + if (!archPackages.isEmpty()) { + return archPackages.stream(); + } + return otherPackages.stream(); } @Override From a0376cd8f86731f7b8aa455eb36a2e4465fe0a6b Mon Sep 17 00:00:00 2001 From: Andrew Lu Date: Tue, 28 May 2024 02:00:44 +0000 Subject: [PATCH 295/298] 8323635: Test gc/g1/TestHumongousAllocConcurrentStart.java fails with -XX:TieredStopAtLevel=3 Backport-of: 5045839cb2095105a5c6c9eebc633a78b1e3213e --- .../jtreg/gc/g1/TestHumongousAllocConcurrentStart.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java b/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java index 52cb2db0ffa..b981f839c7c 100644 --- a/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java +++ b/test/hotspot/jtreg/gc/g1/TestHumongousAllocConcurrentStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -28,6 +28,7 @@ * @bug 7168848 * @summary G1: humongous object allocations should initiate marking cycles when necessary * @requires vm.gc.G1 + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management @@ -45,7 +46,7 @@ public class TestHumongousAllocConcurrentStart { private static final int initiatingHeapOccupancyPercent = 50; // % public static void main(String[] args) throws Exception { - OutputAnalyzer output = ProcessTools.executeTestJava( + OutputAnalyzer output = ProcessTools.executeLimitedTestJava( "-XX:+UseG1GC", "-Xms" + heapSize + "m", "-Xmx" + heapSize + "m", From 2e327a9a98ecef6c55120cc9fdee7b5aca7aa7cd Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 28 May 2024 07:14:05 +0000 Subject: [PATCH 296/298] 8329862: libjli GetApplicationHome cleanups and enhance jli tracing Backport-of: 377f2e538ae0fc94fc5483700a3ae70175017741 --- src/java.base/unix/native/libjli/java_md.c | 18 ++++------- src/java.base/windows/native/libjli/java_md.c | 30 ++++--------------- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/src/java.base/unix/native/libjli/java_md.c b/src/java.base/unix/native/libjli/java_md.c index 024cec571b7..d2c04d8c25d 100644 --- a/src/java.base/unix/native/libjli/java_md.c +++ b/src/java.base/unix/native/libjli/java_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, 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 @@ -495,6 +495,8 @@ GetJREPath(char *path, jint pathsize, jboolean speculative) char libjava[MAXPATHLEN]; struct stat s; + JLI_TraceLauncher("Attempt to get JRE path from launcher executable path\n"); + if (GetApplicationHome(path, pathsize)) { /* Is JRE co-located with the application? */ JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path); @@ -502,20 +504,10 @@ GetJREPath(char *path, jint pathsize, jboolean speculative) JLI_TraceLauncher("JRE path is %s\n", path); return JNI_TRUE; } - /* ensure storage for path + /jre + NULL */ - if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) { - JLI_TraceLauncher("Insufficient space to store JRE path\n"); - return JNI_FALSE; - } - /* Does the app ship a private JRE in /jre directory? */ - JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/" JAVA_DLL, path); - if (access(libjava, F_OK) == 0) { - JLI_StrCat(path, "/jre"); - JLI_TraceLauncher("JRE path is %s\n", path); - return JNI_TRUE; - } } + JLI_TraceLauncher("Attempt to get JRE path from shared lib of the image\n"); + if (GetApplicationHomeFromDll(path, pathsize)) { JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path); if (stat(libjava, &s) == 0) { diff --git a/src/java.base/windows/native/libjli/java_md.c b/src/java.base/windows/native/libjli/java_md.c index 39930a38535..6ff155bcb9b 100644 --- a/src/java.base/windows/native/libjli/java_md.c +++ b/src/java.base/windows/native/libjli/java_md.c @@ -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 @@ -49,10 +49,6 @@ static jboolean GetJVMPath(const char *jrepath, const char *jvmtype, char *jvmpath, jint jvmpathsize); static jboolean GetJREPath(char *path, jint pathsize); -#ifdef USE_REGISTRY_LOOKUP -jboolean GetPublicJREHome(char *buf, jint bufsize); -#endif - /* We supports warmup for UI stack that is performed in parallel * to VM initialization. * This helps to improve startup of UI application as warmup phase @@ -300,6 +296,8 @@ GetJREPath(char *path, jint pathsize) char javadll[MAXPATHLEN]; struct stat s; + JLI_TraceLauncher("Attempt to get JRE path from launcher executable path\n"); + if (GetApplicationHome(path, pathsize)) { /* Is JRE co-located with the application? */ JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path); @@ -307,20 +305,10 @@ GetJREPath(char *path, jint pathsize) JLI_TraceLauncher("JRE path is %s\n", path); return JNI_TRUE; } - /* ensure storage for path + \jre + NULL */ - if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) { - JLI_TraceLauncher("Insufficient space to store JRE path\n"); - return JNI_FALSE; - } - /* Does this app ship a private JRE in \jre directory? */ - JLI_Snprintf(javadll, sizeof (javadll), "%s\\jre\\bin\\" JAVA_DLL, path); - if (stat(javadll, &s) == 0) { - JLI_StrCat(path, "\\jre"); - JLI_TraceLauncher("JRE path is %s\n", path); - return JNI_TRUE; - } } + JLI_TraceLauncher("Attempt to get JRE path from shared lib of the image\n"); + /* Try getting path to JRE from path to JLI.DLL */ if (GetApplicationHomeFromDll(path, pathsize)) { JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path); @@ -330,14 +318,6 @@ GetJREPath(char *path, jint pathsize) } } -#ifdef USE_REGISTRY_LOOKUP - /* Lookup public JRE using Windows registry. */ - if (GetPublicJREHome(path, pathsize)) { - JLI_TraceLauncher("JRE path is %s\n", path); - return JNI_TRUE; - } -#endif - JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL); return JNI_FALSE; } From 60402f88b569064cd140d782e1846988cff6e8cb Mon Sep 17 00:00:00 2001 From: Ashutosh Mehra Date: Tue, 28 May 2024 18:36:04 +0000 Subject: [PATCH 297/298] 8330275: Crash in XMark::follow_array Reviewed-by: stuefe Backport-of: 42b1d858d15fd06de9ce41b08b430b12724652e9 --- src/hotspot/cpu/aarch64/gc/x/xGlobals_aarch64.cpp | 8 +++++--- src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/aarch64/gc/x/xGlobals_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/x/xGlobals_aarch64.cpp index 6204f212703..a9c53da3d01 100644 --- a/src/hotspot/cpu/aarch64/gc/x/xGlobals_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/x/xGlobals_aarch64.cpp @@ -142,9 +142,11 @@ // * 63-48 Fixed (16-bits, always zero) // -// Default value if probing is not implemented for a certain platform: 128TB -static const size_t DEFAULT_MAX_ADDRESS_BIT = 47; -// Minimum value returned, if probing fails: 64GB +// Default value if probing is not implemented for a certain platform +// Max address bit is restricted by implicit assumptions in the code, for instance +// the bit layout of XForwardingEntry or Partial array entry (see XMarkStackEntry) in mark stack +static const size_t DEFAULT_MAX_ADDRESS_BIT = 46; +// Minimum value returned, if probing fails static const size_t MINIMUM_MAX_ADDRESS_BIT = 36; static size_t probe_valid_max_address_bit() { diff --git a/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp index 6c3cea73d1a..e140525bcbc 100644 --- a/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp @@ -36,9 +36,11 @@ #include #endif // LINUX -// Default value if probing is not implemented for a certain platform: 128TB -static const size_t DEFAULT_MAX_ADDRESS_BIT = 47; -// Minimum value returned, if probing fails: 64GB +// Default value if probing is not implemented for a certain platform +// Max address bit is restricted by implicit assumptions in the code, for instance +// the bit layout of XForwardingEntry or Partial array entry (see XMarkStackEntry) in mark stack +static const size_t DEFAULT_MAX_ADDRESS_BIT = 46; +// Minimum value returned, if probing fail static const size_t MINIMUM_MAX_ADDRESS_BIT = 36; static size_t probe_valid_max_address_bit() { From 2971cb5769121b47ac8c8db1078d67680a19341f Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Wed, 29 May 2024 06:56:33 +0000 Subject: [PATCH 298/298] 8320692: Null icon returned for .exe without custom icon Backport-of: 6212264cc6fe428e8d15b7f33e2979c081e432d7 --- .../sun/awt/shell/Win32ShellFolder2.java | 10 +- .../FileSystemView/NoIconExeNPE.java | 274 ++++++++++++++++++ 2 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 test/jdk/javax/swing/JFileChooser/FileSystemView/NoIconExeNPE.java 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 9678f00f565..24e2bb45df8 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, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -1125,7 +1125,10 @@ public Image call() { if (hiResIconAvailable(getParentIShellFolder(), getRelativePIDL()) || newIcon == null) { int size = getLargeIcon ? LARGE_ICON_SIZE : SMALL_ICON_SIZE; - newIcon = getIcon(size, size); + newIcon2 = getIcon(size, size); + if (newIcon2 != null) { + newIcon = newIcon2; + } } if (newIcon == null) { @@ -1192,6 +1195,9 @@ public Image getIcon(int width, int height) { newIcon = makeIcon(hIcon); disposeIcon(hIcon); + if (newIcon == null) { + return null; + } multiResolutionIcon.put(s, newIcon); if (size < MIN_QUALITY_ICON || size > MAX_QUALITY_ICON) { break; diff --git a/test/jdk/javax/swing/JFileChooser/FileSystemView/NoIconExeNPE.java b/test/jdk/javax/swing/JFileChooser/FileSystemView/NoIconExeNPE.java new file mode 100644 index 00000000000..5da17d04537 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/FileSystemView/NoIconExeNPE.java @@ -0,0 +1,274 @@ +/* + * 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.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.swing.Icon; +import javax.swing.UIManager; +import javax.swing.filechooser.FileSystemView; + +/* + * @test + * @bug 8320692 + * @requires (os.family == "windows") + * @summary NullPointerException is thrown for .exe file without icon + * @run main/othervm NoIconExeNPE + */ +public class NoIconExeNPE { + + /** + * Bytes of a short {@code Hello.exe} which has no icon. + */ + private static final byte[] bytes = { + (byte) 0x4d, (byte) 0x5a, (byte) 0x80, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, + (byte) 0x10, (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00, + (byte) 0x00, (byte) 0x40, (byte) 0x01, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0e, + (byte) 0x1f, (byte) 0xba, (byte) 0x0e, (byte) 0x00, (byte) 0xb4, + (byte) 0x09, (byte) 0xcd, (byte) 0x21, (byte) 0xb8, (byte) 0x01, + (byte) 0x4c, (byte) 0xcd, (byte) 0x21, (byte) 0x54, (byte) 0x68, + (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x70, (byte) 0x72, + (byte) 0x6f, (byte) 0x67, (byte) 0x72, (byte) 0x61, (byte) 0x6d, + (byte) 0x20, (byte) 0x63, (byte) 0x61, (byte) 0x6e, (byte) 0x6e, + (byte) 0x6f, (byte) 0x74, (byte) 0x20, (byte) 0x62, (byte) 0x65, + (byte) 0x20, (byte) 0x72, (byte) 0x75, (byte) 0x6e, (byte) 0x20, + (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x44, (byte) 0x4f, + (byte) 0x53, (byte) 0x20, (byte) 0x6d, (byte) 0x6f, (byte) 0x64, + (byte) 0x65, (byte) 0x2e, (byte) 0x0d, (byte) 0x0a, (byte) 0x24, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x50, (byte) 0x45, + (byte) 0x00, (byte) 0x00, (byte) 0x4c, (byte) 0x01, (byte) 0x01, + (byte) 0x00, (byte) 0x55, (byte) 0x96, (byte) 0x96, (byte) 0x65, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xe0, (byte) 0x00, + (byte) 0x0f, (byte) 0x01, (byte) 0x0b, (byte) 0x01, (byte) 0x01, + (byte) 0x49, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00, (byte) 0x00, + (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, + (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, + (byte) 0x00, (byte) 0xac, (byte) 0xa3, (byte) 0x00, (byte) 0x00, + (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, + (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x40, (byte) 0x10, (byte) 0x00, (byte) 0x00, + (byte) 0x86, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x2e, (byte) 0x74, (byte) 0x65, (byte) 0x78, + (byte) 0x74, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc6, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00, + (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x6a, (byte) 0x00, (byte) 0x68, + (byte) 0x29, (byte) 0x10, (byte) 0x40, (byte) 0x00, (byte) 0x68, + (byte) 0x1c, (byte) 0x10, (byte) 0x40, (byte) 0x00, (byte) 0x6a, + (byte) 0x00, (byte) 0xff, (byte) 0x15, (byte) 0x88, (byte) 0x10, + (byte) 0x40, (byte) 0x00, (byte) 0x6a, (byte) 0x00, (byte) 0xff, + (byte) 0x15, (byte) 0x80, (byte) 0x10, (byte) 0x40, (byte) 0x00, + (byte) 0x48, (byte) 0x65, (byte) 0x6c, (byte) 0x6c, (byte) 0x6f, + (byte) 0x20, (byte) 0x57, (byte) 0x6f, (byte) 0x72, (byte) 0x6c, + (byte) 0x64, (byte) 0x21, (byte) 0x00, (byte) 0x48, (byte) 0x65, + (byte) 0x6c, (byte) 0x6c, (byte) 0x6f, (byte) 0x20, (byte) 0x66, + (byte) 0x61, (byte) 0x73, (byte) 0x6d, (byte) 0x00, (byte) 0x90, + (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90, + (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90, + (byte) 0x90, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x90, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x10, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x9d, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x88, (byte) 0x10, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x90, (byte) 0x90, (byte) 0x90, (byte) 0x90, + (byte) 0xa8, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xb8, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x6b, (byte) 0x65, (byte) 0x72, (byte) 0x6e, + (byte) 0x65, (byte) 0x6c, (byte) 0x33, (byte) 0x32, (byte) 0x2e, + (byte) 0x64, (byte) 0x6c, (byte) 0x6c, (byte) 0x00, (byte) 0x75, + (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x33, (byte) 0x32, + (byte) 0x2e, (byte) 0x64, (byte) 0x6c, (byte) 0x6c, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x45, (byte) 0x78, (byte) 0x69, + (byte) 0x74, (byte) 0x50, (byte) 0x72, (byte) 0x6f, (byte) 0x63, + (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x00, (byte) 0x90, + (byte) 0x90, (byte) 0x00, (byte) 0x00, (byte) 0x4d, (byte) 0x65, + (byte) 0x73, (byte) 0x73, (byte) 0x61, (byte) 0x67, (byte) 0x65, + (byte) 0x42, (byte) 0x6f, (byte) 0x78, (byte) 0x41, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }; + + public static void main(String[] args) throws Exception { + final Path temp = Files.createTempDirectory("no-icon"); + final Path hello = temp.resolve("Hello.exe"); + + try { + try (OutputStream out = Files.newOutputStream(hello)) { + out.write(bytes); + } + + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + FileSystemView fsv = FileSystemView.getFileSystemView(); + // No NullPointerException is expected + Icon icon = fsv.getSystemIcon(hello.toFile()); + if (icon == null) { + throw new RuntimeException("Null icon returned by FileSystemView.getSystemIcon()"); + } + } finally { + Files.deleteIfExists(hello); + Files.delete(temp); + } + } +}