From db85ffb393e0d6dd1fdb5cefc9ab50f075a1834c Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Fri, 20 Dec 2024 06:52:22 +0000 Subject: [PATCH 01/99] 8346106: Verify.checkEQ: testing utility for recursive value verification Reviewed-by: kvn, tweidmann --- .../jtreg/compiler/lib/verify/Verify.java | 309 +++++++++++++ .../compiler/lib/verify/VerifyException.java | 39 ++ .../examples/TestVerifyInCheckMethod.java | 76 ++++ .../verify/tests/TestVerify.java | 419 ++++++++++++++++++ 4 files changed, 843 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/lib/verify/Verify.java create mode 100644 test/hotspot/jtreg/compiler/lib/verify/VerifyException.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/verify/examples/TestVerifyInCheckMethod.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java diff --git a/test/hotspot/jtreg/compiler/lib/verify/Verify.java b/test/hotspot/jtreg/compiler/lib/verify/Verify.java new file mode 100644 index 00000000000..085ec591b0c --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/verify/Verify.java @@ -0,0 +1,309 @@ +/* + * 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 compiler.lib.verify; + +import java.util.Optional; +import java.lang.foreign.*; + +/** + * The {@link Verify} class provides a single {@link Verify#checkEQ} static method, which recursively + * compares the two {@link Object}s by value. It deconstructs {@link Object[]}, compares boxed primitive + * types, and compares the content of arrays and {@link MemorySegment}s. + * + * When a comparison fail, then methods print helpful messages, before throwing a {@link VerifyException}. + */ +public final class Verify { + + private Verify() {} + + /** + * Verify the content of two Objects, possibly recursively. Only limited types are implemented. + * + * @param a First object to be recursively compared with the second. + * @param b Second object to be recursively compared with the first. + * @throws VerifyException If the comparison fails. + */ + public static void checkEQ(Object a, Object b) { + checkEQ(a, b, ""); + } + + /** + * Verify the content of two Objects, possibly recursively. Only limited types are implemented. + */ + private static void checkEQ(Object a, Object b, String context) { + // Both null + if (a == null && b == null) { + return; + } + + // Null mismatch + if (a == null || b == null) { + System.err.println("ERROR: Verify.checkEQ failed: null mismatch"); + print(a, "a " + context); + print(b, "b " + context); + throw new VerifyException("Object array null mismatch."); + } + + // Class mismatch + Class ca = a.getClass(); + Class cb = b.getClass(); + if (ca != cb) { + System.err.println("ERROR: Verify.checkEQ failed: class mismatch."); + System.err.println(" " + ca.getName() + " vs " + cb.getName()); + print(a, "a " + context); + print(b, "b " + context); + throw new VerifyException("Object class mismatch."); + } + + switch (a) { + case Object[] x -> checkEQimpl(x, (Object[])b, context); + case Byte x -> checkEQimpl(x, ((Byte)b).byteValue(), context); + case Character x -> checkEQimpl(x, ((Character)b).charValue(), context); + case Short x -> checkEQimpl(x, ((Short)b).shortValue(), context); + case Integer x -> checkEQimpl(x, ((Integer)b).intValue(), context); + case Long x -> checkEQimpl(x, ((Long)b).longValue(), context); + case Float x -> checkEQimpl(x, ((Float)b).floatValue(), context); + case Double x -> checkEQimpl(x, ((Double)b).doubleValue(), context); + case byte[] x -> checkEQimpl(x, (byte[])b, context); + case char[] x -> checkEQimpl(x, (char[])b, context); + case short[] x -> checkEQimpl(x, (short[])b, context); + case int[] x -> checkEQimpl(x, (int[])b, context); + case long[] x -> checkEQimpl(x, (long[])b, context); + case float[] x -> checkEQimpl(x, (float[])b, context); + case double[] x -> checkEQimpl(x, (double[])b, context); + case MemorySegment x -> checkEQimpl(x, (MemorySegment) b, context); + default -> { + System.err.println("ERROR: Verify.checkEQ failed: type not supported: " + ca.getName()); + print(a, "a " + context); + print(b, "b " + context); + throw new VerifyException("Object array type not supported: " + ca.getName()); + } + } + } + + /** + * Verify that two bytes are identical. + */ + private static void checkEQimpl(byte a, byte b, String context) { + if (a != b) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch: " + a + " vs " + b + " for " + context); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + + /** + * Verify that two chars are identical. + */ + private static void checkEQimpl(char a, char b, String context) { + if (a != b) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch: " + (int)a + " vs " + (int)b + " for " + context); + throw new VerifyException("Value mismatch: " + (int)a + " vs " + (int)b); + } + } + + /** + * Verify that two shorts are identical. + */ + private static void checkEQimpl(short a, short b, String context) { + if (a != b) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch: " + (int)a + " vs " + (int)b + " for " + context); + throw new VerifyException("Value mismatch: " + (int)a + " vs " + (int)b); + } + } + + /** + * Verify that two ints are identical. + */ + private static void checkEQimpl(int a, int b, String context) { + if (a != b) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch: " + a + " vs " + b + " for " + context); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + + /** + * Verify that two longs are identical. + */ + private static void checkEQimpl(long a, long b, String context) { + if (a != b) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch: " + a + " vs " + b + " for " + context); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + + /** + * Verify that two floats have identical bits. + */ + private static void checkEQimpl(float a, float b, String context) { + if (Float.floatToRawIntBits(a) != Float.floatToRawIntBits(b)) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch for " + context); + System.err.println(" Values: " + a + " vs " + b); + System.err.println(" Values: " + Float.floatToRawIntBits(a) + " vs " + Float.floatToRawIntBits(b)); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + + /** + * Verify that two doubles have identical bits. + */ + private static void checkEQimpl(double a, double b, String context) { + if (Double.doubleToRawLongBits(a) != Double.doubleToRawLongBits(b)) { + System.err.println("ERROR: Verify.checkEQ failed: value mismatch for " + context); + System.err.println(" Values: " + a + " vs " + b); + System.err.println(" Values: " + Double.doubleToRawLongBits(a) + " vs " + Double.doubleToRawLongBits(b)); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + + /** + * Verify that the content of two MemorySegments is identical. Note: we do not check the + * backing type, only the size and content. + */ + private static void checkEQimpl(MemorySegment a, MemorySegment b, String context) { + long offset = a.mismatch(b); + if (offset == -1) { return; } + + // Print some general info + System.err.println("ERROR: Verify.checkEQ failed for: " + context); + + printMemorySegment(a, "a " + context); + printMemorySegment(b, "b " + context); + + // (1) Mismatch on size + if (a.byteSize() != b.byteSize()) { + throw new VerifyException("MemorySegment byteSize mismatch."); + } + + // (2) Value mismatch + System.err.println(" Value mismatch at byte offset: " + offset); + printMemorySegmentValue(a, offset, 16); + printMemorySegmentValue(b, offset, 16); + throw new VerifyException("MemorySegment value mismatch."); + } + + /** + * Verify that the content of two byte arrays is identical. + */ + private static void checkEQimpl(byte[] a, byte[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two char arrays is identical. + */ + private static void checkEQimpl(char[] a, char[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two short arrays is identical. + */ + private static void checkEQimpl(short[] a, short[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two int arrays is identical. + */ + private static void checkEQimpl(int[] a, int[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two long arrays is identical. + */ + private static void checkEQimpl(long[] a, long[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two float arrays is identical. + */ + private static void checkEQimpl(float[] a, float[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two double arrays is identical. + */ + private static void checkEQimpl(double[] a, double[] b, String context) { + checkEQimpl(MemorySegment.ofArray(a), MemorySegment.ofArray(b), context); + } + + /** + * Verify that the content of two Object arrays is identical, recursively: + * every element is compared with checkEQimpl for the corresponding type. + */ + private static void checkEQimpl(Object[] a, Object[] b, String context) { + // (1) Length mismatch + if (a.length != b.length) { + System.err.println("ERROR: Verify.checkEQ failed: length mismatch: " + a.length + " vs " + b.length); + throw new VerifyException("Object array length mismatch."); + } + + for (int i = 0; i < a.length; i++) { + // Recursive checkEQ call. + checkEQ(a[i], b[i], "[" + i + "]" + context); + } + } + + private static void print(Object a, String context) { + if (a == null) { + System.err.println(" " + context + ": null"); + } else { + System.err.println(" " + context + ": " + a); + } + } + + private static void printMemorySegment(MemorySegment a, String context) { + Optional maybeBase = a.heapBase(); + System.err.println(" " + context + " via MemorySegment:"); + if (maybeBase.isEmpty()) { + System.err.println(" no heap base (native)."); + } else { + Object base = maybeBase.get(); + System.err.println(" heap base: " + base); + } + System.err.println(" address: " + a.address()); + System.err.println(" byteSize: " + a.byteSize()); + } + + private static void printMemorySegmentValue(MemorySegment a, long offset, int range) { + long start = Long.max(offset - range, 0); + long end = Long.min(offset + range, a.byteSize()); + for (long i = start; i < end; i++) { + byte b = a.get(ValueLayout.JAVA_BYTE, i); + System.err.print(String.format("%02x ", b)); + } + System.err.println(""); + for (long i = start; i < end; i++) { + if (i == offset) { + System.err.print("^^ "); + } else { + System.err.print(" "); + } + } + System.err.println(""); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/verify/VerifyException.java b/test/hotspot/jtreg/compiler/lib/verify/VerifyException.java new file mode 100644 index 00000000000..e54a0cbef95 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/verify/VerifyException.java @@ -0,0 +1,39 @@ +/* + * 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 compiler.lib.verify; + +/** + * Exception thrown in verification. + */ +public class VerifyException extends RuntimeException { + + /** + * Creates a new verification exception. + * + * @param message Exception message for context when debugging. + */ + public VerifyException(String message) { + super("Value verification failed:" + System.lineSeparator() + message); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/verify/examples/TestVerifyInCheckMethod.java b/test/hotspot/jtreg/testlibrary_tests/verify/examples/TestVerifyInCheckMethod.java new file mode 100644 index 00000000000..c8b4d470d99 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/verify/examples/TestVerifyInCheckMethod.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 + * @summary Example test to show Verify.checkEQ with IR framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver verify.examples.TestVerifyInCheckMethod + */ + +package verify.examples; + +import compiler.lib.verify.*; +import compiler.lib.ir_framework.*; + +/** + * Example to show the use of Verify.checkEQ in @Check method. + */ +public class TestVerifyInCheckMethod { + public static int[] INPUT_A = new int[100]; + static { + for (int i = 0; i < INPUT_A.length; i++) { + INPUT_A[i] = i; + } + } + public static float INPUT_B = 42; + + // Must make sure to clone input arrays, if it is mutated in the test. + public static Object GOLD = test(INPUT_A.clone(), INPUT_B);; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Setup + public static Object[] setup() { + // Must make sure to clone input arrays, if it is mutated in the test. + return new Object[] {INPUT_A.clone(), INPUT_B}; + } + + @Test + @Arguments(setup = "setup") + public static Object test(int[] a, float b) { + for (int i = 0; i < a.length; i++) { + a[i] = (int)(a[i] * b); + } + // Since we have more than one value, we wrap them in an Object[]. + return new Object[] {a, b}; + } + + @Check(test = "test") + public static void check(Object result) { + Verify.checkEQ(result, GOLD); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java new file mode 100644 index 00000000000..bdfeeb149eb --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java @@ -0,0 +1,419 @@ +/* + * 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 + * @summary Test functionality of IntGenerator implementations. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver verify.tests.TestVerify + */ + +package verify.tests; + +import java.lang.foreign.*; +import java.util.Random; +import jdk.test.lib.Utils; + +import compiler.lib.verify.*; + +public class TestVerify { + private static final Random RANDOM = Utils.getRandomInstance(); + + public static void main(String[] args) { + // Test consecutive memory: array, MemorySegment, etc. + testArrayByte(); + testArrayChar(); + testArrayShort(); + testArrayInt(); + testArrayLong(); + testArrayFloat(); + testArrayDouble(); + testNativeMemorySegment(); + + // Test recursive data: Object array of values, etc. + testRecursive(); + } + + public static void testArrayByte() { + byte[] a = new byte[1000]; + byte[] b = new byte[1001]; + byte[] c = new byte[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayShort() { + short[] a = new short[1000]; + short[] b = new short[1001]; + short[] c = new short[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayChar() { + char[] a = new char[1000]; + char[] b = new char[1001]; + char[] c = new char[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayInt() { + int[] a = new int[1000]; + int[] b = new int[1001]; + int[] c = new int[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayLong() { + long[] a = new long[1000]; + long[] b = new long[1001]; + long[] c = new long[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayFloat() { + float[] a = new float[1000]; + float[] b = new float[1001]; + float[] c = new float[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + + public static void testArrayDouble() { + double[] a = new double[1000]; + double[] b = new double[1001]; + double[] c = new double[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(a)); + Verify.checkEQ(MemorySegment.ofArray(b), MemorySegment.ofArray(b)); + Verify.checkEQ(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + Verify.checkEQ(MemorySegment.ofArray(c), MemorySegment.ofArray(a)); + + // Size mismatch + checkNE(a, b); + + // Size mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(b)); + + c[RANDOM.nextInt(c.length)] = 1; + + // Value mismatch + checkNE(a, c); + + // Value mismatch + checkNE(MemorySegment.ofArray(a), MemorySegment.ofArray(c)); + } + + public static void testNativeMemorySegment() { + MemorySegment a = Arena.ofAuto().allocate(1000, 1); + MemorySegment b = Arena.ofAuto().allocate(1001, 1); + MemorySegment c = Arena.ofAuto().allocate(1000, 1); + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + // Size mismatch + checkNE(a, b); + + c.set(ValueLayout.JAVA_BYTE, RANDOM.nextLong(c.byteSize()), (byte)1); + + // Value mismatch + checkNE(a, c); + } + + public static void testRecursive() { + Verify.checkEQ(null, null); + + // Null mismatch + checkNE(42, null); + + byte[] a = new byte[1000]; + int[] b = new int[1000]; + int[] c = new int[1001]; + int[] d = new int[1000]; + + Object[] o1 = new Object[]{a, a}; + Object[] o2 = new Object[]{a, a, a}; + Object[] o3 = new Object[]{a, a, null}; + Object[] o4 = new Object[]{a, a, b}; + Object[] o5 = new Object[]{a, a, c}; + Object[] o6 = new Object[]{a, a, d}; + + Verify.checkEQ(o1, o1); + Verify.checkEQ(o2, o2); + Verify.checkEQ(o3, o3); + Verify.checkEQ(o4, o6); + + // Size mismatch + checkNE(o1, o2); + + // First level value mismatch: a vs null on position 2 + checkNE(o2, o3); + + // First level class mismatch: byte[] vs int[] + checkNE(o2, o4); + + // Second level length mismatch on arrays b and c. + checkNE(o4, o5); + + d[RANDOM.nextInt(d.length)] = 1; + + // Second level value mismatch between b and d. + checkNE(o4, o6); + + // Now test all primitive array types. + byte[] aB = new byte[100]; + char[] aC = new char[100]; + short[] aS = new short[100]; + int[] aI = new int[100]; + long[] aL = new long[100]; + float[] aF = new float[100]; + double[] aD = new double[100]; + + Verify.checkEQ(new Object[] {aB, aC, aS, aI, aL, aF, aD}, new Object[] {aB, aC, aS, aI, aL, aF, aD}); + + // First level class mismatch: char[] vs short[] + checkNE(new Object[] {aC}, new Object[] {aS}); + + // Verify MemorySegment + MemorySegment mC = MemorySegment.ofArray(aC); + MemorySegment mS = MemorySegment.ofArray(aS); + Verify.checkEQ(new Object[] {mC}, new Object[] {mC}); + Verify.checkEQ(new Object[] {mS}, new Object[] {mS}); + + // Second level type mismatch: backing type short[] vs char[] + checkNE(new Object[] {mC}, new Object[] {mS}); + + // Second level type mismatch: backing type int[] vs char[] + MemorySegment mI = MemorySegment.ofArray(aI); + checkNE(new Object[] {mI}, new Object[] {mC}); + + // Verify boxed primitives: + Byte bb1 = 42; + Byte bb2 = 42; + Byte bb3 = 11; + + Verify.checkEQ(new Object[] {(byte)42}, new Object[] {(byte)42}); + Verify.checkEQ(new Object[] {(byte)42}, new Object[] {bb1}); + Verify.checkEQ(new Object[] {bb1}, new Object[] {bb2}); + + // Second level value mismatch: 42 vs 11 + checkNE(new Object[] {bb1}, new Object[] {bb3}); + + Verify.checkEQ((byte)42, (byte)42); + Verify.checkEQ((short)42, (short)42); + Verify.checkEQ((char)42, (char)42); + Verify.checkEQ((int)42, (int)42); + Verify.checkEQ((long)42, (long)42); + Verify.checkEQ((float)42, (float)42); + Verify.checkEQ((double)42, (double)42); + + // Boxed type mismatch: float vs int + checkNE((int)42, (float)42); + + // Boxed value mismatch. + for (int i = 0; i < 10; i++) { + byte v1 = (byte)RANDOM.nextInt(); + byte v2 = (byte)(v1 ^ (1 << RANDOM.nextInt(8))); + checkNE(v1, v2); + } + for (int i = 0; i < 10; i++) { + char v1 = (char)RANDOM.nextInt(); + char v2 = (char)(v1 ^ (1 << RANDOM.nextInt(16))); + checkNE(v1, v2); + } + for (int i = 0; i < 10; i++) { + char v1 = (char)RANDOM.nextInt(); + char v2 = (char)(v1 ^ (1 << RANDOM.nextInt(16))); + checkNE(v1, v2); + } + for (int i = 0; i < 10; i++) { + int v1 = (int)RANDOM.nextInt(); + int v2 = (int)(v1 ^ (1 << RANDOM.nextInt(32))); + checkNE(v1, v2); + checkNE(Float.intBitsToFloat(v1), Float.intBitsToFloat(v2)); + } + for (int i = 0; i < 10; i++) { + long v1 = (long)RANDOM.nextLong(); + long v2 = (long)(v1 ^ (1L << RANDOM.nextInt(64))); + checkNE(v1, v2); + checkNE(Double.longBitsToDouble(v1), Double.longBitsToDouble(v2)); + } + } + + public static void checkNE(Object a, Object b) { + try { + Verify.checkEQ(a, b); + throw new RuntimeException("Should have thrown"); + } catch (VerifyException e) {} + } +} From e7edfeb04203e7241d3f95e5f644ce030a669919 Mon Sep 17 00:00:00 2001 From: liyazzi Date: Fri, 20 Dec 2024 07:05:42 +0000 Subject: [PATCH 02/99] 8331467: FileSystems.getDefault fails with ClassNotFoundException if custom default provider is in run-time image Reviewed-by: alanb, jpai --- .../internal/jimage/ImageReaderFactory.java | 24 +++++++++++++++---- .../java/nio/file/spi/SetDefaultProvider.java | 4 +--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageReaderFactory.java b/src/java.base/share/classes/jdk/internal/jimage/ImageReaderFactory.java index 24ac9bfc18a..2ecec20d6f9 100644 --- a/src/java.base/share/classes/jdk/internal/jimage/ImageReaderFactory.java +++ b/src/java.base/share/classes/jdk/internal/jimage/ImageReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -27,8 +27,9 @@ import java.io.IOException; import java.io.UncheckedIOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.concurrent.ConcurrentHashMap; import java.util.Map; import java.util.Objects; @@ -47,8 +48,23 @@ public class ImageReaderFactory { private ImageReaderFactory() {} private static final String JAVA_HOME = System.getProperty("java.home"); - private static final Path BOOT_MODULES_JIMAGE = - Paths.get(JAVA_HOME, "lib", "modules"); + private static final Path BOOT_MODULES_JIMAGE; + + static { + FileSystem fs; + if (ImageReaderFactory.class.getClassLoader() == null) { + try { + fs = (FileSystem) Class.forName("sun.nio.fs.DefaultFileSystemProvider") + .getMethod("theFileSystem") + .invoke(null); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + } else { + fs = FileSystems.getDefault(); + } + BOOT_MODULES_JIMAGE = fs.getPath(JAVA_HOME, "lib", "modules"); + } private static final Map readers = new ConcurrentHashMap<>(); diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index a8581dc0e7a..ea154b5952e 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 * @modules jdk.jartool jdk.jlink * @library /test/lib * @build testfsp/* testapp/* @@ -45,7 +45,6 @@ import jdk.test.lib.process.ProcessTools; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.BeforeAll; import static org.junit.jupiter.api.Assertions.*; @@ -124,7 +123,6 @@ void testFspOnModulePath2() throws Exception { /** * Test file system provider linked into run-time image. */ - @Disabled @Test void testFspInRuntimeImage() throws Exception { String image = "image"; From b15476259f8f875d59ec6bab17eb68c1d690933a Mon Sep 17 00:00:00 2001 From: Evgeny Nikitin Date: Fri, 20 Dec 2024 08:24:18 +0000 Subject: [PATCH 03/99] 8322983: Virtual Threads: exclude 2 tests Reviewed-by: jpai, lmesnik, syan --- test/hotspot/jtreg/ProblemList-Virtual.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index 34aead4a16c..b5bb2c72779 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -104,7 +104,9 @@ gc/g1/TestMixedGCLiveThreshold.java#25percent 8334759 windows-x64 gc/arguments/TestNewSizeThreadIncrease.java 0000000 generic-all gc/g1/TestSkipRebuildRemsetPhase.java 0000000 generic-all +runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java JDK-8346442 generic-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 0000000 generic-all +runtime/logging/LoaderConstraintsTest.java JDK-8346442 generic-all runtime/Thread/AsyncExceptionOnMonitorEnter.java 0000000 generic-all runtime/Thread/StopAtExit.java 0000000 generic-all runtime/handshake/HandshakeWalkStackTest.java 0000000 generic-all From 67e716ea7a14864ef81709889b154b8e3a79f06a Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Fri, 20 Dec 2024 10:16:04 +0000 Subject: [PATCH 04/99] 8346128: Comparison build fails due to difference in LabelTarget.html Reviewed-by: jlahoda, liach, prappo --- .../classes/java/lang/classfile/instruction/LabelTarget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java b/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java index c5b49973133..94ac1839c75 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java @@ -55,7 +55,7 @@ * {@snippet lang=java : * cob.with(lt); // @link substring="with" target="CodeBuilder#with" * // @link substring="labelBinding" target="CodeBuilder#labelBinding" : - * cob.labelBinding(lt.label()); // @link substring="label" target="#label" + * cob.labelBinding(lt.label()); // @link regex="label(?=\()" target="#label" * } * * @see Label From 823b3915a23db09073038ca7eac72a077ea31263 Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Fri, 20 Dec 2024 10:17:21 +0000 Subject: [PATCH 05/99] 8346667: Doccheck: warning about missing before

Reviewed-by: psandoz --- .../share/classes/jdk/incubator/vector/VectorMask.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java index f5ce894b13f..cdf5b589be7 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, 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 @@ -108,8 +108,6 @@ * } * * - * @param the boxed version of {@code ETYPE}, - * the element type of a vector * *

Value-based classes and identity operations

* @@ -128,6 +126,9 @@ * {@code static final} constants, but storing them in other Java * fields or in array elements, while semantically valid, may incur * performance penalties. + * + * @param the boxed version of {@code ETYPE}, + * the element type of a vector */ @SuppressWarnings("exports") public abstract class VectorMask extends jdk.internal.vm.vector.VectorSupport.VectorMask { From 15229e1b262a4903fd67d7cf6c55e84c8036b363 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Fri, 20 Dec 2024 12:35:35 +0000 Subject: [PATCH 06/99] 8345259: Disallow ALL-MODULE-PATH without explicit --module-path Reviewed-by: mchung --- .../jdk/tools/jlink/internal/JlinkTask.java | 49 +++-- .../tools/jlink/resources/jlink.properties | 4 +- test/jdk/tools/jlink/IntegrationTest.java | 2 +- test/jdk/tools/jlink/JLinkTest.java | 8 +- test/jdk/tools/jlink/basic/AllModulePath.java | 194 ++++++++++++------ test/jdk/tools/jlink/basic/BasicTest.java | 64 +++--- 6 files changed, 214 insertions(+), 107 deletions(-) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java index 6717d5517d1..928b9a47934 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java @@ -277,14 +277,6 @@ int run(String[] args) { return EXIT_OK; } - if (options.modulePath.isEmpty()) { - // no --module-path specified - try to set $JAVA_HOME/jmods if that exists - Path jmods = getDefaultModulePath(); - if (jmods != null) { - options.modulePath.add(jmods); - } - } - JlinkConfiguration config = initJlinkConfig(); outputPath = config.getOutput(); if (options.suggestProviders) { @@ -377,8 +369,13 @@ public static void createImage(JlinkConfiguration config, // the token for "all modules on the module path" private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH"; private JlinkConfiguration initJlinkConfig() throws BadArgs { + // Empty module path not allowed with ALL-MODULE-PATH in --add-modules + if (options.addMods.contains(ALL_MODULE_PATH) && options.modulePath.isEmpty()) { + throw taskHelper.newBadArgs("err.no.module.path"); + } ModuleFinder appModuleFinder = newModuleFinder(options.modulePath); ModuleFinder finder = appModuleFinder; + boolean isLinkFromRuntime = false; if (!appModuleFinder.find("java.base").isPresent()) { // If the application module finder doesn't contain the @@ -393,8 +390,9 @@ private JlinkConfiguration initJlinkConfig() throws BadArgs { // include the java.base module. Path defModPath = getDefaultModulePath(); if (defModPath != null) { - options.modulePath.add(defModPath); - finder = newModuleFinder(options.modulePath); + List combinedPaths = new ArrayList<>(options.modulePath); + combinedPaths.add(defModPath); + finder = newModuleFinder(combinedPaths); } // We've just added the default module path ('jmods'). If we still // don't find java.base, we must resolve JDK modules from the @@ -419,8 +417,31 @@ private JlinkConfiguration initJlinkConfig() throws BadArgs { Set roots = new HashSet<>(); for (String mod : options.addMods) { if (mod.equals(ALL_MODULE_PATH)) { - ModuleFinder mf = newLimitedFinder(finder, options.limitMods, - Set.of()); + // Using --limit-modules with ALL-MODULE-PATH is an error + if (!options.limitMods.isEmpty()) { + throw taskHelper.newBadArgs("err.limit.modules"); + } + // all observable modules in the app module path are roots + Set initialRoots = appModuleFinder.findAll() + .stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .collect(Collectors.toSet()); + + // Error if no module is found on the app module path + if (initialRoots.isEmpty()) { + String modPath = options.modulePath.stream() + .map(a -> a.toString()) + .collect(Collectors.joining(", ")); + throw taskHelper.newBadArgs("err.empty.module.path", modPath); + } + + // Use a module finder with limited observability, as determined + // by initialRoots, to find the observable modules from the + // application module path (--module-path option) only. We must + // not include JDK modules from the default module path or the + // run-time image. + ModuleFinder mf = limitFinder(finder, initialRoots, Set.of()); mf.findAll() .stream() .map(ModuleReference::descriptor) @@ -430,7 +451,7 @@ private JlinkConfiguration initJlinkConfig() throws BadArgs { roots.add(mod); } } - finder = newLimitedFinder(finder, options.limitMods, roots); + finder = limitFinder(finder, options.limitMods, roots); // --keep-packaged-modules doesn't make sense as we are not linking // from packaged modules to begin with. @@ -497,7 +518,7 @@ public static Path getDefaultModulePath() { * specified in {@code limitMods} plus other modules specified in the * {@code roots} set. */ - public static ModuleFinder newLimitedFinder(ModuleFinder finder, + public static ModuleFinder limitFinder(ModuleFinder finder, Set limitMods, Set roots) { // if limitMods is specified then limit the universe diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties index b5880a35561..a491b758ea0 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties @@ -127,7 +127,9 @@ err.runtime.link.packaged.mods=This JDK has no packaged modules.\ err.runtime.link.modified.file={0} has been modified err.runtime.link.patched.module=jlink does not support linking from the run-time image\ \ when running on a patched runtime with --patch-module -err.empty.module.path=empty module path +err.no.module.path=--module-path option must be specified with --add-modules ALL-MODULE-PATH +err.empty.module.path=No module found in module path ''{0}'' with --add-modules ALL-MODULE-PATH +err.limit.modules=--limit-modules not allowed with --add-modules ALL-MODULE-PATH err.jlink.version.mismatch=jlink version {0}.{1} does not match target java.base version {2}.{3} err.automatic.module:automatic module cannot be used with jlink: {0} from {1} err.unknown.byte.order:unknown byte order {0} diff --git a/test/jdk/tools/jlink/IntegrationTest.java b/test/jdk/tools/jlink/IntegrationTest.java index 7f3dc223461..5a8d0bce15a 100644 --- a/test/jdk/tools/jlink/IntegrationTest.java +++ b/test/jdk/tools/jlink/IntegrationTest.java @@ -157,7 +157,7 @@ private static void test() throws Exception { boolean linkFromRuntime = false; JlinkConfiguration config = new Jlink.JlinkConfiguration(output, mods, - JlinkTask.newLimitedFinder(JlinkTask.newModuleFinder(modulePaths), limits, mods), + JlinkTask.limitFinder(JlinkTask.newModuleFinder(modulePaths), limits, mods), linkFromRuntime, false /* ignore modified runtime */, false /* generate run-time image */); diff --git a/test/jdk/tools/jlink/JLinkTest.java b/test/jdk/tools/jlink/JLinkTest.java index c0fabe06a8c..0b7de201ac9 100644 --- a/test/jdk/tools/jlink/JLinkTest.java +++ b/test/jdk/tools/jlink/JLinkTest.java @@ -27,17 +27,15 @@ import java.lang.module.ModuleDescriptor; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.internal.PluginRepository; +import jdk.tools.jlink.plugin.Plugin; import tests.Helper; import tests.JImageGenerator; @@ -135,11 +133,11 @@ public static void main(String[] args) throws Exception { { // No --module-path specified. --add-modules ALL-MODULE-PATH specified. - String imageDir = "bug8189777-all-module-path"; + String imageDir = "bug8345259-all-module-path"; JImageGenerator.getJLinkTask() .output(helper.createNewImageDir(imageDir)) .addMods("ALL-MODULE-PATH") - .call().assertSuccess(); + .call().assertFailure(); } { diff --git a/test/jdk/tools/jlink/basic/AllModulePath.java b/test/jdk/tools/jlink/basic/AllModulePath.java index ba6cc08bd47..a05f2d06d86 100644 --- a/test/jdk/tools/jlink/basic/AllModulePath.java +++ b/test/jdk/tools/jlink/basic/AllModulePath.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 @@ -21,45 +21,52 @@ * questions. */ -/* - * @test - * @summary jlink test of --add-module ALL-MODULE-PATH - * @library /test/lib - * @modules jdk.compiler - * @build jdk.test.lib.process.ProcessTools - * jdk.test.lib.process.OutputAnalyzer - * jdk.test.lib.compiler.CompilerUtils - * @run testng AllModulePath - */ +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; -import java.io.File; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; import java.util.spi.ToolProvider; - -import jdk.test.lib.compiler.CompilerUtils; -import jdk.test.lib.process.ProcessTools; +import java.util.stream.Collectors; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import static org.testng.Assert.*; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.ProcessTools; +import jdk.tools.jlink.internal.LinkableRuntimeImage; +import tests.Helper; +import tests.Result; + +/* + * @test + * @bug 8345259 + * @summary jlink test of --add-module ALL-MODULE-PATH + * @library ../../lib /test/lib + * @modules jdk.compiler + * java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jimage + * @build jdk.test.lib.process.ProcessTools + * jdk.test.lib.process.OutputAnalyzer + * jdk.test.lib.compiler.CompilerUtils + * @run testng/othervm -Duser.language=en -Duser.country=US AllModulePath + */ public class AllModulePath { - private final Path JMODS = Paths.get(System.getProperty("test.jdk")).resolve("jmods"); - private final Path SRC = Paths.get(System.getProperty("test.src")).resolve("src"); - private final Path MODS = Paths.get("mods"); + private static final Path JMODS = Paths.get(System.getProperty("test.jdk")).resolve("jmods"); + private static final Path SRC = Paths.get(System.getProperty("test.src")).resolve("src"); + private static final Path MODS = Paths.get("mods"); + private static final boolean LINKABLE_RUNTIME = LinkableRuntimeImage.isLinkableRuntime(); + private static final boolean JMODS_EXIST = Files.exists(JMODS); private final static Set MODULES = Set.of("test", "m1"); @@ -67,12 +74,22 @@ public class AllModulePath { .orElseThrow(() -> new RuntimeException("jlink tool not found") ); + private static Helper HELPER; + + private static boolean isExplodedJDKImage() { + if (!JMODS_EXIST && !LINKABLE_RUNTIME) { + System.err.println("Test skipped. Not a linkable runtime and no JMODs"); + return true; + } + return false; + } @BeforeClass public void setup() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } + HELPER = Helper.newHelper(LINKABLE_RUNTIME); Files.createDirectories(MODS); @@ -84,60 +101,114 @@ public void setup() throws Throwable { } } + /* + * --add-modules ALL-MODULE-PATH with an existing module-path. + */ @Test public void testAllModulePath() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } - // create custom image - Path image = Paths.get("image"); - createImage(image, "--add-modules", "ALL-MODULE-PATH"); + Path image = HELPER.createNewImageDir("image"); + List opts = List.of("--module-path", MODS.toString(), + "--output", image.toString(), + "--add-modules", "ALL-MODULE-PATH"); + createImage(image, opts, true /* success */); Set modules = new HashSet<>(); - Files.find(JMODS, 1, (Path p, BasicFileAttributes attr) -> - p.toString().endsWith(".jmod")) - .map(p -> JMODS.relativize(p).toString()) - .map(n -> n.substring(0, n.length()-5)) - .forEach(modules::add); + // java.base is a dependency of any external module + modules.add("java.base"); modules.add("m1"); modules.add("test"); checkModules(image, modules); } + /* + * --add-modules ALL-MODULE-PATH with --limit-modules is an error + */ @Test public void testLimitModules() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } - - // create custom image - Path image = Paths.get("image1"); - createImage(image, - "--add-modules", "ALL-MODULE-PATH", - "--limit-modules", "m1"); - - checkModules(image, Set.of("m1", "java.base")); + Path targetPath = HELPER.createNewImageDir("all-mods-limit-mods"); + String moduleName = "com.baz.runtime"; + Result result = HELPER.generateDefaultJModule(moduleName, "jdk.jfr"); + Path customModulePath = result.getFile().getParent(); + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--limit-modules", "jdk.jfr", + "--module-path", customModulePath.toString(), + "--output", targetPath.toString()); + JlinkOutput allOut = createImage(targetPath, allArgs, false /* success */); + String actual = allOut.stdout.trim(); + String expected = "Error: --limit-modules not allowed with --add-modules ALL-MODULE-PATH"; + assertEquals(actual, expected); } + + /* + * --add-modules *includes* ALL-MODULE-PATH with an existing module path + */ @Test public void testAddModules() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } // create custom image - Path image = Paths.get("image2"); - createImage(image, - "--add-modules", "m1,test", - "--add-modules", "ALL-MODULE-PATH", - "--limit-modules", "java.base"); + Path image = HELPER.createNewImageDir("image2"); + List opts = List.of("--module-path", MODS.toString(), + "--output", image.toString(), + "--add-modules", "m1", + "--add-modules", "ALL-MODULE-PATH"); + createImage(image, opts, true /* success */); checkModules(image, Set.of("m1", "test", "java.base")); } /* - * check the modules linked in the image + * No --module-path with --add-modules ALL-MODULE-PATH is an error. + */ + @Test + public void noModulePath() throws IOException { + if (isExplodedJDKImage()) { + return; + } + Path targetPath = HELPER.createNewImageDir("all-mod-path-no-mod-path"); + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--output", targetPath.toString()); + JlinkOutput allOut = createImage(targetPath, allArgs, false /* expect failure */); + String expected = "Error: --module-path option must be specified with --add-modules ALL-MODULE-PATH"; + assertEquals(allOut.stdout.trim(), expected); + } + + /* + * --module-path not-exist and --add-modules ALL-MODULE-PATH is an error. + */ + @Test + public void modulePathEmpty() throws IOException { + if (isExplodedJDKImage()) { + return; + } + Path targetPath = HELPER.createNewImageDir("all-mod-path-not-existing"); + String strNotExists = "not-exist"; + Path notExists = Path.of(strNotExists); + if (Files.exists(notExists)) { + throw new AssertionError("Test setup error, path must not exist!"); + } + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--module-path", notExists.toString(), + "--output", targetPath.toString()); + + JlinkOutput allOut = createImage(targetPath, allArgs, false /* expect failure */); + String actual = allOut.stdout.trim(); + assertTrue(actual.startsWith("Error: No module found in module path")); + assertTrue(actual.contains(strNotExists)); + } + + /* + * check the modules linked in the image using m1/p.ListModules */ private void checkModules(Path image, Set modules) throws Throwable { Path cmd = findTool(image, "java"); @@ -164,16 +235,19 @@ private Path findTool(Path image, String tool) { return cmd; } - private void createImage(Path image, String... options) throws IOException { - String modulepath = JMODS.toString() + File.pathSeparator + MODS.toString(); - List opts = List.of("--module-path", modulepath, - "--output", image.toString()); - String[] args = Stream.concat(opts.stream(), Arrays.stream(options)) - .toArray(String[]::new); - - System.out.println("jlink " + Arrays.stream(args).collect(Collectors.joining(" "))); - PrintWriter pw = new PrintWriter(System.out); - int rc = JLINK_TOOL.run(pw, pw, args); - assertTrue(rc == 0); + private JlinkOutput createImage(Path image, List args, boolean success) throws IOException { + System.out.println("jlink " + args.stream().collect(Collectors.joining(" "))); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter out = new PrintWriter(baos); + ByteArrayOutputStream berrOs = new ByteArrayOutputStream(); + PrintWriter err = new PrintWriter(berrOs); + int rc = JLINK_TOOL.run(out, err, args.toArray(String[]::new)); + String stdOut = new String(baos.toByteArray()); + String stdErr = new String(berrOs.toByteArray()); + assertEquals(rc == 0, success, String.format("Output was: %nstdout: %s%nstderr: %s%n", stdOut, stdErr)); + return new JlinkOutput(stdErr, stdOut); } + + private static record JlinkOutput(String stderr, String stdout) {}; } diff --git a/test/jdk/tools/jlink/basic/BasicTest.java b/test/jdk/tools/jlink/basic/BasicTest.java index a771d4d0002..1a14e620fa6 100644 --- a/test/jdk/tools/jlink/basic/BasicTest.java +++ b/test/jdk/tools/jlink/basic/BasicTest.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 @@ -21,21 +21,6 @@ * questions. */ -/* - * @test - * @summary Basic test of jlink to create jmods and images - * @author Andrei Eremeev - * @library /test/lib - * @modules java.base/jdk.internal.module - * jdk.jlink - * jdk.compiler - * @build jdk.test.lib.process.ProcessTools - * jdk.test.lib.process.OutputAnalyzer - * jdk.test.lib.compiler.CompilerUtils - * jdk.test.lib.util.JarUtils - * @run main BasicTest - */ - import java.io.File; import java.io.PrintWriter; import java.nio.file.Files; @@ -50,7 +35,22 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; +import jdk.tools.jlink.internal.LinkableRuntimeImage; +/* + * @test + * @summary Basic test of jlink to create jmods and images + * @author Andrei Eremeev + * @library /test/lib + * @modules java.base/jdk.internal.module + * jdk.jlink/jdk.tools.jlink.internal + * jdk.compiler + * @build jdk.test.lib.process.ProcessTools + * jdk.test.lib.process.OutputAnalyzer + * jdk.test.lib.compiler.CompilerUtils + * jdk.test.lib.util.JarUtils + * @run main/othervm BasicTest + */ public class BasicTest { static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod") .orElseThrow(() -> @@ -62,21 +62,31 @@ public class BasicTest { new RuntimeException("jlink tool not found") ); - private final String TEST_MODULE = "test"; - private final Path jdkHome = Paths.get(System.getProperty("test.jdk")); - private final Path jdkMods = jdkHome.resolve("jmods"); - private final Path testSrc = Paths.get(System.getProperty("test.src")); - private final Path src = testSrc.resolve("src").resolve(TEST_MODULE); - private final Path classes = Paths.get("classes"); - private final Path jmods = Paths.get("jmods"); - private final Path jars = Paths.get("jars"); + private static final String TEST_MODULE = "test"; + private static final Path jdkHome = Paths.get(System.getProperty("test.jdk")); + private static final Path jdkMods = jdkHome.resolve("jmods"); + private static final boolean JMODS_EXIST = Files.exists(jdkMods); + private static final boolean LINKABLE_RUNTIME = LinkableRuntimeImage.isLinkableRuntime(); + private static final Path testSrc = Paths.get(System.getProperty("test.src")); + private static final Path src = testSrc.resolve("src").resolve(TEST_MODULE); + private static final Path classes = Paths.get("classes"); + private static final Path jmods = Paths.get("jmods"); + private static final Path jars = Paths.get("jars"); public static void main(String[] args) throws Throwable { new BasicTest().run(); } + private static boolean isExplodedJDKImage() { + if (!JMODS_EXIST && !LINKABLE_RUNTIME) { + System.err.println("Test skipped. Not a linkable runtime and no JMODs"); + return true; + } + return false; + } + public void run() throws Throwable { - if (Files.notExists(jdkMods)) { + if (isExplodedJDKImage()) { return; } @@ -146,8 +156,10 @@ private void execute(Path image, String scriptName) throws Throwable { private void runJlink(Path image, String modName, String... options) { List args = new ArrayList<>(); + String modPathArg = (JMODS_EXIST ? jdkMods + File.pathSeparator : "") + + jmods; Collections.addAll(args, - "--module-path", jdkMods + File.pathSeparator + jmods, + "--module-path", modPathArg, "--add-modules", modName, "--output", image.toString()); Collections.addAll(args, options); From 4ca0e9230ada9218cd551dd20d140e502e0c62ab Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 20 Dec 2024 20:08:42 +0000 Subject: [PATCH 07/99] 8346739: jpackage tests failed after JDK-8345259 Reviewed-by: kcr, asemenyuk --- .../tools/jpackage/share/RuntimeImageSymbolicLinksTest.java | 2 ++ test/jdk/tools/jpackage/share/RuntimeImageTest.java | 2 ++ test/jdk/tools/jpackage/share/RuntimePackageTest.java | 3 +++ 3 files changed, 7 insertions(+) diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index 404cd3b6d3a..db74e3456c4 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -51,6 +51,7 @@ public class RuntimeImageSymbolicLinksTest { @Test public static void test() throws Exception { + final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); final Path jlinkOutputDir = workDir.resolve("temp.runtime"); Files.createDirectories(jlinkOutputDir.getParent()); @@ -61,6 +62,7 @@ public static void test() throws Exception { .addArguments( "--output", jlinkOutputDir.toString(), "--add-modules", "ALL-MODULE-PATH", + "--module-path", jmods.toString(), "--strip-debug", "--no-header-files", "--no-man-pages", diff --git a/test/jdk/tools/jpackage/share/RuntimeImageTest.java b/test/jdk/tools/jpackage/share/RuntimeImageTest.java index f3751c9ee47..65e8c448d39 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageTest.java @@ -44,6 +44,7 @@ public class RuntimeImageTest { @Test public static void test() throws Exception { + final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); final Path jlinkOutputDir = workDir.resolve("temp.runtime"); Files.createDirectories(jlinkOutputDir.getParent()); @@ -54,6 +55,7 @@ public static void test() throws Exception { .addArguments( "--output", jlinkOutputDir.toString(), "--add-modules", "ALL-MODULE-PATH", + "--module-path", jmods.toString(), "--strip-debug", "--no-header-files", "--no-man-pages", diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java index 0b505babcc5..73f1c525654 100644 --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java @@ -101,6 +101,8 @@ private static PackageTest init(Set types) { .forTypes(types) .addInitializer(cmd -> { final Path runtimeImageDir; + final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); + if (JPackageCommand.DEFAULT_RUNTIME_IMAGE != null) { runtimeImageDir = JPackageCommand.DEFAULT_RUNTIME_IMAGE; } else { @@ -112,6 +114,7 @@ private static PackageTest init(Set types) { .addArguments( "--output", runtimeImageDir.toString(), "--add-modules", "ALL-MODULE-PATH", + "--module-path", jmods.toString(), "--strip-debug", "--no-header-files", "--no-man-pages") From 6f6478d718989a9713fd59e086bac75cd333abca Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 20 Dec 2024 20:52:48 +0000 Subject: [PATCH 08/99] 8343882: BasicAnnoTests doesn't handle multiple annotations at the same position Reviewed-by: darcy --- .../processing/model/type/BasicAnnoTests.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java index 904e4e78cad..f94ba461a45 100644 --- a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java +++ b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java @@ -163,7 +163,7 @@ public Void scan(Element elem, Void ignore) { */ class TestTypeScanner extends TypeScanner { Element elem; - NavigableMap toBeFound; + NavigableMap> toBeFound; int count = 0; Set seen = new HashSet<>(); @@ -171,10 +171,10 @@ class TestTypeScanner extends TypeScanner { super(types); this.elem = elem; - NavigableMap testByPos = new TreeMap<>(); + NavigableMap> testByPos = new TreeMap<>(); for (AnnotationMirror test : tests) { for (int pos : getPosn(test)) { - testByPos.put(pos, test); + testByPos.computeIfAbsent(pos, ArrayList::new).add(test); } } this.toBeFound = testByPos; @@ -196,17 +196,18 @@ Void scan(TypeMirror t, Void ignore) { out.println("scan " + count + ": " + t); if (toBeFound.size() > 0) { if (toBeFound.firstKey().equals(count)) { - AnnotationMirror test = toBeFound.pollFirstEntry().getValue(); - String annoType = getAnnoType(test); - AnnotationMirror anno = getAnnotation(t, annoType); - if (anno == null) { - error(elem, "annotation not found on " + count + ": " + t); - } else { - String v = getValue(anno, "value").toString(); - if (v.equals(getExpect(test))) { - out.println("found " + anno + " as expected"); + for (AnnotationMirror test : toBeFound.pollFirstEntry().getValue()) { + String annoType = getAnnoType(test); + AnnotationMirror anno = getAnnotation(t, annoType); + if (anno == null) { + error(elem, "annotation not found on " + count + ": " + t); } else { - error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); + String v = getValue(anno, "value").toString(); + if (v.equals(getExpect(test))) { + out.println("found " + anno + " as expected"); + } else { + error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); + } } } } else if (count > toBeFound.firstKey()) { From 2c3ce35ce8eb8ebe01f2a86c0bf19ea980fff69d Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sat, 21 Dec 2024 03:40:48 +0000 Subject: [PATCH 09/99] 8346713: [testsuite] NeverActAsServerClassMachine breaks TestPLABAdaptToMinTLABSize.java TestPinnedHumongousFragmentation.java TestPinnedObjectContents.java Reviewed-by: stefank, tschatzl --- .../jtreg/gc/TestPLABAdaptToMinTLABSize.java | 25 ++++++++++++++----- .../TestPinnedHumongousFragmentation.java | 2 +- .../pinnedobjs/TestPinnedObjectContents.java | 3 ++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java b/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java index 73d3c475335..e1e29432f53 100644 --- a/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java +++ b/test/hotspot/jtreg/gc/TestPLABAdaptToMinTLABSize.java @@ -24,17 +24,29 @@ package gc; /* - * @test TestPLABAdaptToMinTLABSize + * @test TestPLABAdaptToMinTLABSizeG1 * @bug 8289137 * @summary Make sure that Young/OldPLABSize adapt to MinTLABSize setting. - * @requires vm.gc.Parallel | vm.gc.G1 + * @requires vm.gc.G1 * @library /test/lib * @modules java.base/jdk.internal.misc * java.management - * @run driver gc.TestPLABAdaptToMinTLABSize + * @run driver gc.TestPLABAdaptToMinTLABSize -XX:+UseG1GC + */ + +/* + * @test TestPLABAdaptToMinTLABSizeParallel + * @bug 8289137 + * @summary Make sure that Young/OldPLABSize adapt to MinTLABSize setting. + * @requires vm.gc.Parallel + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run driver gc.TestPLABAdaptToMinTLABSize -XX:+UseParallelGC */ import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import jdk.test.lib.process.OutputAnalyzer; @@ -68,9 +80,10 @@ private static void runTest(boolean shouldSucceed, String... extraArgs) throws E } public static void main(String[] args) throws Exception { - runTest(true, "-XX:MinTLABSize=100k"); + String gc = args[0]; + runTest(true, gc, "-XX:MinTLABSize=100k"); // Should not succeed when explicitly specifying invalid combination. - runTest(false, "-XX:MinTLABSize=100k", "-XX:OldPLABSize=5k"); - runTest(false, "-XX:MinTLABSize=100k", "-XX:YoungPLABSize=5k"); + runTest(false, gc, "-XX:MinTLABSize=100k", "-XX:OldPLABSize=5k"); + runTest(false, gc, "-XX:MinTLABSize=100k", "-XX:YoungPLABSize=5k"); } } diff --git a/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedHumongousFragmentation.java b/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedHumongousFragmentation.java index fad01ab0022..f147dcbe62e 100644 --- a/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedHumongousFragmentation.java +++ b/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedHumongousFragmentation.java @@ -36,7 +36,7 @@ * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xlog:gc+region=trace -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g - * -XX:VerifyGCType=full -XX:+VerifyDuringGC -XX:+VerifyAfterGC -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:VerifyGCType=full -XX:+VerifyDuringGC -XX:+VerifyAfterGC -XX:+WhiteBoxAPI -XX:+UseG1GC -Xbootclasspath/a:. * gc.g1.pinnedobjs.TestPinnedHumongousFragmentation */ diff --git a/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedObjectContents.java b/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedObjectContents.java index e0fdc88e2a1..dcc87f811b3 100644 --- a/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedObjectContents.java +++ b/test/hotspot/jtreg/gc/g1/pinnedobjs/TestPinnedObjectContents.java @@ -33,7 +33,8 @@ * java.management * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -XX:+ZapUnusedHeapArea -Xlog:gc,gc+ergo+cset=trace gc.g1.pinnedobjs.TestPinnedObjectContents + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC + * -Xbootclasspath/a:. -XX:+ZapUnusedHeapArea -Xlog:gc,gc+ergo+cset=trace gc.g1.pinnedobjs.TestPinnedObjectContents */ package gc.g1.pinnedobjs; From cb64b59d04773f2562d11747a7c37691e14f207b Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 23 Dec 2024 11:56:24 +0000 Subject: [PATCH 10/99] 8346477: Clarify the Java manpage in relation to the JVM's OnOutOfMemoryError flags Co-authored-by: Thomas Stuefe Reviewed-by: jpai, stuefe --- src/java.base/share/man/java.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 0beb5bf935c..01f7b3f7e77 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -1292,10 +1292,15 @@ These `java` options control the runtime behavior of the Java HotSpot VM. `-XX:OnOutOfMemoryError=`*string* : Sets a custom command or a series of semicolon-separated commands to run - when an `OutOfMemoryError` exception is first thrown. If the string + when an `OutOfMemoryError` exception is first thrown by the JVM. + If the string contains spaces, then it must be enclosed in quotation marks. For an example of a command string, see the description of the `-XX:OnError` option. + This applies only to `OutOfMemoryError` exceptions caused by Java Heap + exhaustion; it does not apply to `OutOfMemoryError` exceptions thrown + directly from Java code, nor by the JVM for other types of resource + exhaustion (such as native thread creation errors). `-XX:+PrintCommandLineFlags` : Enables printing of ergonomically selected JVM flags that appeared on the @@ -2189,10 +2194,14 @@ perform extensive debugging. `-XX:+HeapDumpOnOutOfMemoryError` : Enables the dumping of the Java heap to a file in the current directory by using the heap profiler (HPROF) when a `java.lang.OutOfMemoryError` - exception is thrown. You can explicitly set the heap dump file path and + exception is thrown by the JVM. You can explicitly set the heap dump file path and name using the `-XX:HeapDumpPath` option. By default, this option is disabled and the heap isn't dumped when an `OutOfMemoryError` exception is thrown. + This applies only to `OutOfMemoryError` exceptions caused by Java Heap + exhaustion; it does not apply to `OutOfMemoryError` exceptions thrown + directly from Java code, nor by the JVM for other types of resource + exhaustion (such as native thread creation errors). `-XX:HeapDumpPath=`*path* : Sets the path and file name for writing the heap dump provided by the heap From f6f907c7803419989c5734bb57f8f5134d061750 Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Mon, 23 Dec 2024 13:50:39 +0000 Subject: [PATCH 11/99] 8337111: Bad HTML checker for generated documentation 8337113: Bad character checker for generated documentation 8337116: Internal links checker for generated documentation 8337114: DocType checker for generated documentation Reviewed-by: hannesw --- test/docs/jdk/javadoc/doccheck/DocCheck.java | 194 +++++ .../docs/jdk/javadoc/doccheck/ExtLinksJdk.txt | 773 ++++++++++++++++++ .../doccheck/checks/jdkCheckExtlinks.java | 31 + .../javadoc/doccheck/checks/jdkCheckHtml.java | 31 + .../doccheck/checks/jdkCheckLinks.java | 31 + .../checks/jdkDoctypeBadcharsCheck.java} | 23 +- .../doccheck/doccheckutils/Checker.java | 39 + .../doccheck/doccheckutils/FileChecker.java | 30 + .../doccheck/doccheckutils/FileProcessor.java | 64 ++ .../doccheck/doccheckutils/HtmlChecker.java | 94 +++ .../doccheckutils/HtmlFileChecker.java | 389 +++++++++ .../javadoc/doccheck/doccheckutils/Log.java | 95 +++ .../checkers/BadCharacterChecker.java | 158 ++++ .../checkers/DocTypeChecker.java | 159 ++++ .../checkers/ExtLinkChecker.java | 220 +++++ .../doccheckutils/checkers/LinkChecker.java | 440 ++++++++++ .../doccheckutils/checkers/TidyChecker.java | 259 ++++++ 17 files changed, 3012 insertions(+), 18 deletions(-) create mode 100644 test/docs/jdk/javadoc/doccheck/DocCheck.java create mode 100644 test/docs/jdk/javadoc/doccheck/ExtLinksJdk.txt create mode 100644 test/docs/jdk/javadoc/doccheck/checks/jdkCheckExtlinks.java create mode 100644 test/docs/jdk/javadoc/doccheck/checks/jdkCheckHtml.java create mode 100644 test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java rename test/docs/jdk/javadoc/{TestDocs.java => doccheck/checks/jdkDoctypeBadcharsCheck.java} (63%) create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/Checker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/FileChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlFileChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/Log.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/BadCharacterChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/DocTypeChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/ExtLinkChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java create mode 100644 test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/TidyChecker.java diff --git a/test/docs/jdk/javadoc/doccheck/DocCheck.java b/test/docs/jdk/javadoc/doccheck/DocCheck.java new file mode 100644 index 00000000000..acd61b0e76e --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/DocCheck.java @@ -0,0 +1,194 @@ +/* + * 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 doccheckutils.FileChecker; +import doccheckutils.FileProcessor; +import doccheckutils.HtmlFileChecker; +import doccheckutils.checkers.BadCharacterChecker; +import doccheckutils.checkers.DocTypeChecker; +import doccheckutils.checkers.LinkChecker; +import doccheckutils.checkers.TidyChecker; +import doccheckutils.checkers.ExtLinkChecker; +import toolbox.TestRunner; + +import java.nio.file.Path; +import java.util.*; + +/** + * DocCheck + *

+ * For the sake of brevity, to run all of these checkers use + *

+ * `make test-docs_all TEST_DEPS=docs-jdk` + *

+ * This collection of tests provide a variety of checks for JDK documentation bundle. + *

+ * It is meant to provide a convenient way to alert users of any errors in their documentation + * before a push and verify the quality of the documentation. + * It is not meant to replace more authoritative checkers; instead, + * it is more focused on providing a convenient, easy overview of any possible issues. + *

+ * It supports the following checks: + *

+ * *HTML* -- We use the standard `tidy` utility to check for HTML compliance, + * according to the declared version of HTML. + * The output from `tidy` is analysed to generate a report summarizing any issues that were found. + *

+ * Version `5.9.20` of `tidy` is expected, or the output from the `--version` option should contain the string `version 5`. + * The test warns the user if he is using an earlier version. + *

+ * *Bad Characters* -- We assumee that HTML files are encoded in UTF-8, + * and reports any character encoding issues that it finds. + *

+ * *DocType* -- We assume that HTML files should use HTML5, and reports + * any files for which that is not the case. + *

+ * *Links* -- We check links within a set of files, and reports on links + * to external resources, without otherwise checking them. + *

+ * *External Links* -- We scan the files for URLs that refer to + * external resources, and validates those references using a "golden file" that includes a list of vetted links. + *

+ * Each external reference is only checked once; but if an issue is found, all the files containing the + * reference will be reported. + */ +public class DocCheck extends TestRunner { + + private static final String DOCCHECK_DIR = System.getProperty("doccheck.dir"); + private static final Path DIR = Path.of(DOCCHECK_DIR != null ? DOCCHECK_DIR : ""); + private static final Set CHECKS_LIST = new HashSet<>(); + private static Path DOCS_DIR; + + private static boolean html; + private static boolean links; + private static boolean badchars; + private static boolean doctype; + private static boolean extlinks; + + private List files; + + public DocCheck() { + super(System.err); + init(); + } + + public static void main(String... args) throws Exception { + chooseCheckers(); + DocCheck docCheck = new DocCheck(); + docCheck.runTests(); + } + + private static void chooseCheckers() { + final String checks = System.getProperty("doccheck.checks"); + + if (!checks.isEmpty()) { + if (checks.contains(",")) { + CHECKS_LIST.addAll(Arrays.asList(checks.split(","))); + } else { + CHECKS_LIST.add(checks); + } + } + + if (CHECKS_LIST.contains("all")) { + html = true; + links = true; + badchars = true; + doctype = true; + extlinks = true; + } else { + if (CHECKS_LIST.contains("html")) { + html = true; + } + if (CHECKS_LIST.contains("links")) { + links = true; + } + if (CHECKS_LIST.contains("badchars")) { + badchars = true; + } + if (CHECKS_LIST.contains("doctype")) { + doctype = true; + } + if (CHECKS_LIST.contains("extlinks")) { + extlinks = true; + } + } + } + + public void init() { + var fileTester = new FileProcessor(); + DOCS_DIR = DocTester.resolveDocs(); + var baseDir = DOCS_DIR.resolve(DIR); + fileTester.processFiles(baseDir); + files = fileTester.getFiles(); + } + + public List getCheckers() { + + List checkers = new ArrayList<>(); + if (html) { + checkers.add(new TidyChecker()); + } + if (links) { + var linkChecker = new LinkChecker(); + linkChecker.setBaseDir(DOCS_DIR); + checkers.add(new HtmlFileChecker(linkChecker, DOCS_DIR)); + } + + if (extlinks) { + checkers.add(new HtmlFileChecker(new ExtLinkChecker(), DOCS_DIR)); + } + + // there should be almost nothing reported from these two checkers + // most reports should be broken anchors/links, missing files and errors in html + if (badchars) { + checkers.add(new BadCharacterChecker()); + } + if (doctype) { + checkers.add(new HtmlFileChecker(new DocTypeChecker(), DOCS_DIR)); + } + + return checkers; + } + + @Test + public void test() throws Exception { + List checkers = getCheckers(); + runCheckersSequentially(checkers); + } + + private void runCheckersSequentially(List checkers) throws Exception { + List exceptions = new ArrayList<>(); + + for (FileChecker checker : checkers) { + try (checker) { + checker.checkFiles(files); + } catch (Exception e) { + exceptions.add(e); + } + } + + if (!exceptions.isEmpty()) { + throw new Exception("One or more HTML checkers failed: " + exceptions); + } + } +} diff --git a/test/docs/jdk/javadoc/doccheck/ExtLinksJdk.txt b/test/docs/jdk/javadoc/doccheck/ExtLinksJdk.txt new file mode 100644 index 00000000000..704bdffb283 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/ExtLinksJdk.txt @@ -0,0 +1,773 @@ +# This file is used to check external links in the JDK generated documentation +# to prevent broken links from backsliding into the JDK source. +# +# The file serves as a "whitelist" of links that have been checked to be working as intended +# and JDK developers should add external links to this file whenever they add them to their documentation. +# +# +# The links in this file are checked before every release. +# +# +# +http://cldr.unicode.org/ +http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf +http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf +http://docs.oracle.com/javase/feedback.html +http://docs.oracle.com/javase/jndi/tutorial/index.html +http://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-12.html +http://docs.oracle.com/javase/tutorial/collections/index.html +http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html +http://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html +http://docs.oracle.com/javase/tutorial/jdbc/ +http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html +http://docs.oracle.com/javase/tutorial/jdbc/basics/rowset.html +http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html +http://en.wikipedia.org/wiki/Skip_list +http://jclark.com/xml/xmlns.htm +http://jcp.org/en/jsr/detail?id=173 +http://jcp.org/en/jsr/detail?id=268 +http://relaxng.org/spec-20011203.html +http://sax.sourceforge.net/?selected=get-set +http://standards.iso.org/iso/9075/2002/12/sqlxml.xsd +http://svn.python.org/projects/python/trunk/Objects/listsort.txt +http://tools.ietf.org/html/rfc1421 +http://tools.ietf.org/html/rfc5869 +http://unicode.org/reports/tr35/ +http://unicode.org/reports/tr35/tr35-numbers.html +http://web.archive.org/web/20051219043731/http://archive.ncsa.uiuc.edu/SDG/Software/Mosaic/Demo/url-primer.html +http://www.cl.cam.ac.uk/~mgk25/time/utc-sls/ +http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf +http://www.iana.org/ +http://www.iana.org/assignments/character-sets +http://www.iana.org/assignments/character-sets/character-sets.xhtml +http://www.iana.org/assignments/media-types/ +http://www.iana.org/assignments/uri-schemes.html +http://www.ietf.org/ +http://www.ietf.org/rfc/rfc0793.txt +http://www.ietf.org/rfc/rfc0822.txt +http://www.ietf.org/rfc/rfc1122.txt +http://www.ietf.org/rfc/rfc1123.txt +http://www.ietf.org/rfc/rfc1323.txt +http://www.ietf.org/rfc/rfc1349.txt +http://www.ietf.org/rfc/rfc1521.txt +http://www.ietf.org/rfc/rfc1522.txt +http://www.ietf.org/rfc/rfc1918.txt +http://www.ietf.org/rfc/rfc1950.txt +http://www.ietf.org/rfc/rfc1950.txt.pdf +http://www.ietf.org/rfc/rfc1951.txt +http://www.ietf.org/rfc/rfc1951.txt.pdf +http://www.ietf.org/rfc/rfc1952.txt +http://www.ietf.org/rfc/rfc1952.txt.pdf +http://www.ietf.org/rfc/rfc1964.txt +http://www.ietf.org/rfc/rfc2045.txt +http://www.ietf.org/rfc/rfc2046.txt +http://www.ietf.org/rfc/rfc2078.txt +http://www.ietf.org/rfc/rfc2104.txt +http://www.ietf.org/rfc/rfc2109.txt +http://www.ietf.org/rfc/rfc2222.txt +http://www.ietf.org/rfc/rfc2236.txt +http://www.ietf.org/rfc/rfc2245.txt +http://www.ietf.org/rfc/rfc2246.txt +http://www.ietf.org/rfc/rfc2251.txt +http://www.ietf.org/rfc/rfc2253.txt +http://www.ietf.org/rfc/rfc2254.txt +http://www.ietf.org/rfc/rfc2255.txt +http://www.ietf.org/rfc/rfc2268.txt +http://www.ietf.org/rfc/rfc2278.txt +http://www.ietf.org/rfc/rfc2279.txt +http://www.ietf.org/rfc/rfc2296.txt +http://www.ietf.org/rfc/rfc2365.txt +http://www.ietf.org/rfc/rfc2373.txt +http://www.ietf.org/rfc/rfc2396.txt +http://www.ietf.org/rfc/rfc2440.txt +http://www.ietf.org/rfc/rfc2474.txt +http://www.ietf.org/rfc/rfc2609.txt +http://www.ietf.org/rfc/rfc2616.txt +http://www.ietf.org/rfc/rfc2696 +http://www.ietf.org/rfc/rfc2696.txt +http://www.ietf.org/rfc/rfc2710.txt +http://www.ietf.org/rfc/rfc2732.txt +http://www.ietf.org/rfc/rfc2743.txt +http://www.ietf.org/rfc/rfc2781.txt +http://www.ietf.org/rfc/rfc2782.txt +http://www.ietf.org/rfc/rfc2830.txt +http://www.ietf.org/rfc/rfc2831.txt +http://www.ietf.org/rfc/rfc2853.txt +http://www.ietf.org/rfc/rfc2891.txt +http://www.ietf.org/rfc/rfc2898.txt +http://www.ietf.org/rfc/rfc2965.txt +http://www.ietf.org/rfc/rfc3023.txt +http://www.ietf.org/rfc/rfc3111.txt +http://www.ietf.org/rfc/rfc3275.txt +http://www.ietf.org/rfc/rfc3279.txt +http://www.ietf.org/rfc/rfc3296.txt +http://www.ietf.org/rfc/rfc3330.txt +http://www.ietf.org/rfc/rfc3376.txt +http://www.ietf.org/rfc/rfc3454.txt +http://www.ietf.org/rfc/rfc3490.txt +http://www.ietf.org/rfc/rfc3491.txt +http://www.ietf.org/rfc/rfc3492.txt +http://www.ietf.org/rfc/rfc3530.txt +http://www.ietf.org/rfc/rfc3720.txt +http://www.ietf.org/rfc/rfc3720.txt.pdf +http://www.ietf.org/rfc/rfc3758.txt +http://www.ietf.org/rfc/rfc3810.txt +http://www.ietf.org/rfc/rfc3986.txt +http://www.ietf.org/rfc/rfc4120.txt +http://www.ietf.org/rfc/rfc4122.txt +http://www.ietf.org/rfc/rfc4366.txt +http://www.ietf.org/rfc/rfc4512.txt +http://www.ietf.org/rfc/rfc4648.txt +http://www.ietf.org/rfc/rfc5116.txt +http://www.ietf.org/rfc/rfc5280.txt +http://www.ietf.org/rfc/rfc5890.txt +http://www.ietf.org/rfc/rfc6066.txt +http://www.ietf.org/rfc/rfc7301.txt +http://www.ietf.org/rfc/rfc790.txt +http://www.ietf.org/rfc/rfc793.txt +http://www.ietf.org/rfc/rfc822.txt +http://www.ietf.org/rfc/rfc919.txt +http://www.info-zip.org/doc/appnote-19970311-iz.zip +http://www.ioplex.com/utilities/keytab.txt +http://www.iso.org/iso/home/standards/currency_codes.htm +http://www.jcp.org +http://www.jcp.org/en/jsr/detail?id=203 +http://www.jpeg.org +http://www.libpng.org/pub/png/spec/ +http://www.microsoft.com/typography/otspec/ +http://www.midi.org +http://www.oasis-open.org/committees/entity/spec-2001-08-06.html +http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=dss +http://www.opengroup.org +http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html +http://www.oracle.com/technetwork/java/architecture-142923.html +http://www.oracle.com/technetwork/java/javase/documentation/serialized-criteria-137781.html +http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html +http://www.oracle.com/technetwork/java/javase/javasecarootcertsprogram-1876540.html +http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html +http://www.oracle.com/technetwork/java/painting-140037.html +http://www.oracle.com/technetwork/java/persistence2-141443.html +http://www.oracle.com/technetwork/java/persistence3-139471.html +http://www.oracle.com/technetwork/java/persistence4-140124.html +http://www.oreilly.com/catalog/regex/ +http://www.oreilly.com/catalog/regex3/ +http://www.reactive-streams.org/ +http://www.relaxng.org/ +http://www.rfc-editor.org/rfc/bcp/bcp47.txt +http://www.saxproject.org +http://www.saxproject.org/ +http://www.unicode.org +http://www.unicode.org/ +http://www.unicode.org/glossary/ +http://www.unicode.org/reports/tr15/ +http://www.unicode.org/reports/tr18/ +http://www.unicode.org/reports/tr24/ +http://www.unicode.org/reports/tr27/ +http://www.unicode.org/reports/tr36/ +http://www.unicode.org/reports/tr44/ +http://www.unicode.org/standard/standard.html +http://www.w3.org/2000/09/xmldsig +http://www.w3.org/2000/xmlns/ +http://www.w3.org/2001/04/xmldsig-more +http://www.w3.org/2001/04/xmlenc +http://www.w3.org/2001/05/xmlschema-errata +http://www.w3.org/2001/10/xml-exc-c14n +http://www.w3.org/2002/06/xmldsig-filter2 +http://www.w3.org/2007/05/xmldsig-more +http://www.w3.org/2009/xmldsig11 +http://www.w3.org/2021/04/xmldsig-more +http://www.w3.org/Graphics/GIF/spec-gif89a.txt +http://www.w3.org/TR/1998/REC-CSS2-19980512 +http://www.w3.org/TR/1999/REC-html401-19991224/ +http://www.w3.org/TR/1999/REC-xml-names-19990114/ +http://www.w3.org/TR/1999/REC-xpath-19991116 +http://www.w3.org/TR/1999/REC-xslt-19991116 +http://www.w3.org/TR/2000/CR-DOM-Level-2-20000510 +http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113 +http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113 +http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113 +http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113 +http://www.w3.org/TR/2000/REC-DOM-Level-2-Views-20001113 +http://www.w3.org/TR/2001/REC-xml-c14n-20010315 +http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/ +http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107 +http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109 +http://www.w3.org/TR/2003/REC-SVG11-20030114/ +http://www.w3.org/TR/2003/REC-xptr-framework-20030325/ +http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407 +http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html +http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407 +http://www.w3.org/TR/2004/REC-DOM-Level-3-Val-20040127/ +http://www.w3.org/TR/2004/REC-xml-20040204 +http://www.w3.org/TR/2004/REC-xml-infoset-20040204 +http://www.w3.org/TR/2004/REC-xml-infoset-20040204/ +http://www.w3.org/TR/2004/REC-xml-names11-20040204/ +http://www.w3.org/TR/2004/REC-xml11-20040204/ +http://www.w3.org/TR/DOM-Level-2 +http://www.w3.org/TR/DOM-Level-2-Core/ +http://www.w3.org/TR/DOM-Level-3-Core +http://www.w3.org/TR/DOM-Level-3-LS +http://www.w3.org/TR/ElementTraversal/ +http://www.w3.org/TR/NOTE-datetime +http://www.w3.org/TR/REC-CSS1 +http://www.w3.org/TR/REC-html32.html +http://www.w3.org/TR/REC-xml +http://www.w3.org/TR/REC-xml-names +http://www.w3.org/TR/REC-xml-names/ +http://www.w3.org/TR/REC-xml/ +http://www.w3.org/TR/html4/ +http://www.w3.org/TR/html40/appendix/notes.html +http://www.w3.org/TR/xinclude/ +http://www.w3.org/TR/xml-exc-c14n/ +http://www.w3.org/TR/xml-names11/ +http://www.w3.org/TR/xml-stylesheet/ +http://www.w3.org/TR/xml11/ +http://www.w3.org/TR/xmldsig-core/ +http://www.w3.org/TR/xmldsig-filter2 +http://www.w3.org/TR/xmldsig-filter2/ +http://www.w3.org/TR/xmlschema-1 +http://www.w3.org/TR/xmlschema-1/ +http://www.w3.org/TR/xmlschema-2/ +http://www.w3.org/TR/xpath +http://www.w3.org/TR/xpath-datamodel +http://www.w3.org/TR/xpath/ +http://www.w3.org/TR/xslt +http://www.w3.org/XML/1998/namespace +http://www.w3.org/XML/Schema +http://www.w3.org/XML/xml-V10-2e-errata +http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html +http://www.w3.org/pub/WWW/Protocols/ +http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd +https://bugreport.java.com/bugreport/ +https://bugs.openjdk.org/secure/attachment/75649/JVM_CodeHeap_StateAnalytics_V2.pdf +https://cldr.unicode.org/index/downloads +https://csrc.nist.gov/publications/PubsFIPS.html +https://csrc.nist.gov/publications/fips/archive/fips186-2/fips186-2.pdf +https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf +https://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf +https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf +https://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf +https://csrc.nist.gov/publications/fips/fips81/fips81.htm +https://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf +https://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf +https://csrc.nist.gov/pubs/fips/203/final +https://csrc.nist.gov/pubs/fips/204/final +https://datatracker.ietf.org/doc/html/rfc5646 +https://datatracker.ietf.org/doc/html/rfc8017 +https://developer.apple.com/documentation +https://docs.oracle.com/en/java/javase/11/tools/java.html +https://docs.oracle.com/en/java/javase/12/language/index.html +https://docs.oracle.com/en/java/javase/12/tools/java.html +https://docs.oracle.com/en/java/javase/12/vm/compiler-control1.html +https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/14/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/15/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/16/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/20/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/22/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/lang/Double.html +https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/math/BigDecimal.html +https://docs.oracle.com/en/java/javase/23/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/24/docs/specs/man/java.html +https://docs.oracle.com/en/java/javase/@@JAVASE_VERSION@@/docs/api/java.base/java/lang/String.html +https://docs.oracle.com/en/java/javase/@@JAVASE_VERSION@@/docs/specs/javadoc/javadoc-search-spec.html +https://docs.oracle.com/en/java/javase/@@JAVASE_VERSION@@/docs/specs/man/javadoc.html +https://docs.oracle.com/en/java/javase/index.html +https://docs.oracle.com/javase/10/tools/java.htm +https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html +https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html +https://docs.oracle.com/javase/9/tools/java.htm +https://docs.oracle.com/javase/specs/ +https://docs.oracle.com/javase/specs/jls/se10/html/index.html +https://docs.oracle.com/javase/specs/jls/se11/html/index.html +https://docs.oracle.com/javase/specs/jls/se12/html/index.html +https://docs.oracle.com/javase/specs/jls/se13/html/index.html +https://docs.oracle.com/javase/specs/jls/se14/html/index.html +https://docs.oracle.com/javase/specs/jls/se15/html/index.html +https://docs.oracle.com/javase/specs/jls/se16/html/index.html +https://docs.oracle.com/javase/specs/jls/se17/html/index.html +https://docs.oracle.com/javase/specs/jls/se18/html/index.html +https://docs.oracle.com/javase/specs/jls/se19/html/index.html +https://docs.oracle.com/javase/specs/jls/se20/html/index.html +https://docs.oracle.com/javase/specs/jls/se21/html/index.html +https://docs.oracle.com/javase/specs/jls/se22/html/index.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-13.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-14.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-15.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-17.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-3.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-4.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-5.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-6.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-8.html +https://docs.oracle.com/javase/specs/jls/se22/html/jls-9.html +https://docs.oracle.com/javase/specs/jls/se23/html +https://docs.oracle.com/javase/specs/jls/se23/html/index.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-10.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-11.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-12.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-14.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-15.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-16.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-18.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-2.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-3.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-7.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html +https://docs.oracle.com/javase/specs/jls/se23/html/jls-9.html +https://docs.oracle.com/javase/specs/jls/se24/html/index.html +https://docs.oracle.com/javase/specs/jls/se24/html/jls-9.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/ +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/index.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-10.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-11.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-12.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-13.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-14.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-15.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-17.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-18.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-3.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-4.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-5.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-6.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-7.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-8.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/html/jls-9.html +https://docs.oracle.com/javase/specs/jls/se@@JAVASE_VERSION@@/jls@@JAVASE_VERSION@@.pdf +https://docs.oracle.com/javase/specs/jls/se6/html/j3TOC.html +https://docs.oracle.com/javase/specs/jls/se7/html/index.html +https://docs.oracle.com/javase/specs/jls/se8/html/index.html +https://docs.oracle.com/javase/specs/jls/se9/html/index.html +https://docs.oracle.com/javase/specs/jvms/se10/html/index.html +https://docs.oracle.com/javase/specs/jvms/se11/html/index.html +https://docs.oracle.com/javase/specs/jvms/se12/html/index.html +https://docs.oracle.com/javase/specs/jvms/se13/html/index.html +https://docs.oracle.com/javase/specs/jvms/se14/html/index.html +https://docs.oracle.com/javase/specs/jvms/se15/html/index.html +https://docs.oracle.com/javase/specs/jvms/se16/html/index.html +https://docs.oracle.com/javase/specs/jvms/se17/html/index.html +https://docs.oracle.com/javase/specs/jvms/se18/html/index.html +https://docs.oracle.com/javase/specs/jvms/se19/html/index.html +https://docs.oracle.com/javase/specs/jvms/se20/html/index.html +https://docs.oracle.com/javase/specs/jvms/se21/html/index.html +https://docs.oracle.com/javase/specs/jvms/se22/html/index.html +https://docs.oracle.com/javase/specs/jvms/se23/html +https://docs.oracle.com/javase/specs/jvms/se23/html/index.html +https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-5.html +https://docs.oracle.com/javase/specs/jvms/se24/html/index.html +https://docs.oracle.com/javase/specs/jvms/se24/html/jvms-4.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/index.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-1.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-2.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-3.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-4.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-5.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/html/jvms-6.html +https://docs.oracle.com/javase/specs/jvms/se@@JAVASE_VERSION@@/jvms@@JAVASE_VERSION@@.pdf +https://docs.oracle.com/javase/specs/jvms/se7/html/index.html +https://docs.oracle.com/javase/specs/jvms/se8/html/index.html +https://docs.oracle.com/javase/specs/jvms/se9/html/index.html +https://docs.oracle.com/javase/tutorial/ +https://docs.oracle.com/javase/tutorial/2d/text/fonts.html +https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html +https://docs.oracle.com/javase/tutorial/index.html +https://docs.oracle.com/javase/tutorial/javabeans/ +https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html +https://docs.oracle.com/javase/tutorial/sound/ +https://docs.oracle.com/javase/tutorial/uiswing/ +https://docs.oracle.com/javase/tutorial/uiswing/components/applet.html +https://docs.oracle.com/javase/tutorial/uiswing/components/border.html +https://docs.oracle.com/javase/tutorial/uiswing/components/button.html +https://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html +https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html +https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html +https://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html +https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html +https://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html +https://docs.oracle.com/javase/tutorial/uiswing/components/icon.html +https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html +https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html +https://docs.oracle.com/javase/tutorial/uiswing/components/label.html +https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html +https://docs.oracle.com/javase/tutorial/uiswing/components/list.html +https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html +https://docs.oracle.com/javase/tutorial/uiswing/components/panel.html +https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html +https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html +https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html +https://docs.oracle.com/javase/tutorial/uiswing/components/slider.html +https://docs.oracle.com/javase/tutorial/uiswing/components/spinner.html +https://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html +https://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html +https://docs.oracle.com/javase/tutorial/uiswing/components/table.html +https://docs.oracle.com/javase/tutorial/uiswing/components/text.html +https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html +https://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html +https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html +https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html +https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html +https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html +https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html +https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/index.html +https://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/treeexpansionlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/treemodellistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/treeselectionlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html +https://docs.oracle.com/javase/tutorial/uiswing/index.html +https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html +https://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html +https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html +https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html +https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html +https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html +https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=GUID-FE2D2E28-C991-4EF9-9DBE-2A4982726313 +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=homepage +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=i18n_overview +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=imf_overview +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=jndi_ldap_gl_prop +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=jndi_overview +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=logging_overview +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=monitoring_and_management_using_jmx_technology +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=rmi_guide +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=secure_coding_guidelines_javase +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_impl_provider +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_jca +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_jca_provider +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_jdk_providers +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_jgss_tutorial +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_overview +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_pki +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_sasl +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=security_guide_tools +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=serialization_filter_guide +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=serialver_tool_reference +https://docs.oracle.com/pls/topic/lookup?ctx=javase@@JAVASE_VERSION@@&id=using_jconsole +https://ftp.pwg.org/pub/pwg/candidates/cs-ippoutputbin10-20010207-5100.2.pdf +https://ftp.pwg.org/pub/pwg/standards/temp_archive/pwg5100.3.pdf +https://github.github.com/gfm/ +https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles +https://html.spec.whatwg.org +https://html.spec.whatwg.org/multipage/ +https://html.spec.whatwg.org/multipage/introduction.html +https://html.spec.whatwg.org/multipage/sections.html +https://html.spec.whatwg.org/multipage/semantics.html +https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index.html +https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index2.html +https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html +https://jcp.org/en/jsr/detail?id=14 +https://jcp.org/en/jsr/detail?id=175 +https://jcp.org/en/jsr/detail?id=201 +https://jcp.org/en/jsr/detail?id=221 +https://jcp.org/en/jsr/detail?id=269 +https://jcp.org/en/jsr/detail?id=334 +https://jcp.org/en/jsr/detail?id=335 +https://jcp.org/en/jsr/detail?id=376 +https://jcp.org/en/jsr/detail?id=41 +https://jcp.org/en/procedures/jcp2 +https://mermaid.js.org +https://msdn.microsoft.com/en-us/library/cc236621.aspx +https://msdn.microsoft.com/en-us/library/dd183391.aspx +https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf +https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf +https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf +https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf +https://openjdk.org/jeps/11 +https://openjdk.org/jeps/12 +https://openjdk.org/jeps/181 +https://openjdk.org/jeps/213 +https://openjdk.org/jeps/225 +https://openjdk.org/jeps/261 +https://openjdk.org/jeps/286 +https://openjdk.org/jeps/306 +https://openjdk.org/jeps/323 +https://openjdk.org/jeps/361 +https://openjdk.org/jeps/371 +https://openjdk.org/jeps/378 +https://openjdk.org/jeps/394 +https://openjdk.org/jeps/395 +https://openjdk.org/jeps/396 +https://openjdk.org/jeps/403 +https://openjdk.org/jeps/409 +https://openjdk.org/jeps/421 +https://openjdk.org/jeps/440 +https://openjdk.org/jeps/441 +https://openjdk.org/jeps/454 +https://openjdk.org/jeps/456 +https://openjdk.org/jeps/458 +https://openjdk.org/jeps/467 +https://openjdk.org/jeps/478 +https://openjdk.org/jeps/487 +https://openjdk.org/jeps/488 +https://openjdk.org/jeps/492 +https://openjdk.org/jeps/494 +https://openjdk.org/jeps/495 +https://openjdk.org/jeps/499 +https://prismjs.com +https://pubs.opengroup.org/onlinepubs/9699919799/functions/inet_addr.html +https://relaxng.org/ +https://reproducible-builds.org/ +https://spec.commonmark.org/0.31.2 +https://spec.commonmark.org/0.31.2/ +https://standards.ieee.org/ieee/754/6210/ +https://standards.iso.org/ittf/PubliclyAvailableStandards/c055982_ISO_IEC_19757-3_2016.zip +https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html +https://support.pkware.com/pkzip/appnote +https://tools.ietf.org/html/rfc1319 +https://tools.ietf.org/html/rfc1321 +https://tools.ietf.org/html/rfc1779 +https://tools.ietf.org/html/rfc2040 +https://tools.ietf.org/html/rfc2104 +https://tools.ietf.org/html/rfc2195 +https://tools.ietf.org/html/rfc2222 +https://tools.ietf.org/html/rfc2246 +https://tools.ietf.org/html/rfc2253 +https://tools.ietf.org/html/rfc2595 +https://tools.ietf.org/html/rfc2616 +https://tools.ietf.org/html/rfc2712 +https://tools.ietf.org/html/rfc2818 +https://tools.ietf.org/html/rfc2830 +https://tools.ietf.org/html/rfc2831 +https://tools.ietf.org/html/rfc3217 +https://tools.ietf.org/html/rfc3278 +https://tools.ietf.org/html/rfc3394 +https://tools.ietf.org/html/rfc3986 +https://tools.ietf.org/html/rfc4086 +https://tools.ietf.org/html/rfc4121 +https://tools.ietf.org/html/rfc4162 +https://tools.ietf.org/html/rfc4178 +https://tools.ietf.org/html/rfc4234 +https://tools.ietf.org/html/rfc4279 +https://tools.ietf.org/html/rfc4346 +https://tools.ietf.org/html/rfc4347 +https://tools.ietf.org/html/rfc4492 +https://tools.ietf.org/html/rfc4512 +https://tools.ietf.org/html/rfc4647 +https://tools.ietf.org/html/rfc4785 +https://tools.ietf.org/html/rfc4960 +https://tools.ietf.org/html/rfc5054 +https://tools.ietf.org/html/rfc5061 +https://tools.ietf.org/html/rfc5084 +https://tools.ietf.org/html/rfc5246 +https://tools.ietf.org/html/rfc5280 +https://tools.ietf.org/html/rfc5288 +https://tools.ietf.org/html/rfc5289 +https://tools.ietf.org/html/rfc5469 +https://tools.ietf.org/html/rfc5487 +https://tools.ietf.org/html/rfc5489 +https://tools.ietf.org/html/rfc5639 +https://tools.ietf.org/html/rfc5646 +https://tools.ietf.org/html/rfc5649 +https://tools.ietf.org/html/rfc5746 +https://tools.ietf.org/html/rfc5932 +https://tools.ietf.org/html/rfc6209 +https://tools.ietf.org/html/rfc6347 +https://tools.ietf.org/html/rfc6367 +https://tools.ietf.org/html/rfc6454 +https://tools.ietf.org/html/rfc6455 +https://tools.ietf.org/html/rfc6655 +https://tools.ietf.org/html/rfc6931 +https://tools.ietf.org/html/rfc7230 +https://tools.ietf.org/html/rfc7231 +https://tools.ietf.org/html/rfc7251 +https://tools.ietf.org/html/rfc7292 +https://tools.ietf.org/html/rfc7507 +https://tools.ietf.org/html/rfc7539 +https://tools.ietf.org/html/rfc7540 +https://tools.ietf.org/html/rfc7748 +https://tools.ietf.org/html/rfc7905 +https://tools.ietf.org/html/rfc7919 +https://tools.ietf.org/html/rfc8017 +https://tools.ietf.org/html/rfc8018 +https://tools.ietf.org/html/rfc8032 +https://tools.ietf.org/html/rfc8103 +https://tools.ietf.org/html/rfc8353 +https://tools.ietf.org/html/rfc8422 +https://tools.ietf.org/html/rfc8446 +https://tools.ietf.org/html/rfc8554 +https://tools.ietf.org/id/draft-kaukonen-cipher-arcfour-03.txt +https://tools.ietf.org/rfc/rfc5280.txt +https://tools.ietf.org/rfc/rfc8017.txt +https://unicode.org/reports/tr31/ +https://unicode.org/reports/tr35/ +https://unicode.org/reports/tr35/tr35-dates.html +https://unicode.org/reports/tr35/tr35-numbers.html +https://unicode.org/reports/tr51/ +https://web.mit.edu/kerberos/ +https://webhome.phy.duke.edu/~rgb/General/dieharder.php +https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf +https://www.color.org +https://www.color.org/ICC1V42.pdf +https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml +https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml +https://www.iana.org/time-zones +https://www.ietf.org/rfc/rfc2616.txt +https://www.ietf.org/rfc/rfc2818.txt +https://www.ietf.org/rfc/rfc6931.txt +https://www.ietf.org/rfc/rfc6943.html +https://www.iso.org/home.html +https://www.iso.org/iso-4217-currency-codes.html +https://www.iso.org/iso-8601-date-and-time-format.html +https://www.iso.org/standard/18114.html +https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf +https://www.itu.int/rec/T-REC-X.509/en +https://www.netlib.org/fdlibm/ +https://www.oasis-open.org +https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html +https://www.oracle.com/java/javase/terms/license/java@@JAVASE_VERSION@@speclicense.html +https://www.oracle.com/java/technologies/a-swing-architecture.html +https://www.oracle.com/java/technologies/javase/seccodeguide.html +https://www.oracle.com/java/technologies/javase/training-support.html +https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase&id=security_guide_implement_provider_jca +https://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html +https://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html +https://www.oracle.com/technetwork/java/redist-137594.html +https://www.oracle.com/technetwork/java/seccodeguide-139067.html +https://www.owasp.org +https://www.rfc-editor.org/info/rfc1122 +https://www.rfc-editor.org/info/rfc1123 +https://www.rfc-editor.org/info/rfc1323 +https://www.rfc-editor.org/info/rfc1349 +https://www.rfc-editor.org/info/rfc1738 +https://www.rfc-editor.org/info/rfc1779 +https://www.rfc-editor.org/info/rfc1918 +https://www.rfc-editor.org/info/rfc1950 +https://www.rfc-editor.org/info/rfc1951 +https://www.rfc-editor.org/info/rfc1952 +https://www.rfc-editor.org/info/rfc2040 +https://www.rfc-editor.org/info/rfc2045 +https://www.rfc-editor.org/info/rfc2046 +https://www.rfc-editor.org/info/rfc2109 +https://www.rfc-editor.org/info/rfc2236 +https://www.rfc-editor.org/info/rfc2246 +https://www.rfc-editor.org/info/rfc2253 +https://www.rfc-editor.org/info/rfc2268 +https://www.rfc-editor.org/info/rfc2278 +https://www.rfc-editor.org/info/rfc2279 +https://www.rfc-editor.org/info/rfc2296 +https://www.rfc-editor.org/info/rfc2306 +https://www.rfc-editor.org/info/rfc2365 +https://www.rfc-editor.org/info/rfc2368 +https://www.rfc-editor.org/info/rfc2373 +https://www.rfc-editor.org/info/rfc2396 +https://www.rfc-editor.org/info/rfc2474 +https://www.rfc-editor.org/info/rfc2560 +https://www.rfc-editor.org/info/rfc2616 +https://www.rfc-editor.org/info/rfc2710 +https://www.rfc-editor.org/info/rfc2732 +https://www.rfc-editor.org/info/rfc2781 +https://www.rfc-editor.org/info/rfc2898 +https://www.rfc-editor.org/info/rfc2911 +https://www.rfc-editor.org/info/rfc2965 +https://www.rfc-editor.org/info/rfc3279 +https://www.rfc-editor.org/info/rfc3330 +https://www.rfc-editor.org/info/rfc3376 +https://www.rfc-editor.org/info/rfc3454 +https://www.rfc-editor.org/info/rfc3490 +https://www.rfc-editor.org/info/rfc3491 +https://www.rfc-editor.org/info/rfc3492 +https://www.rfc-editor.org/info/rfc3530 +https://www.rfc-editor.org/info/rfc3720 +https://www.rfc-editor.org/info/rfc3810 +https://www.rfc-editor.org/info/rfc3986 +https://www.rfc-editor.org/info/rfc4007 +https://www.rfc-editor.org/info/rfc4086 +https://www.rfc-editor.org/info/rfc4122 +https://www.rfc-editor.org/info/rfc4234 +https://www.rfc-editor.org/info/rfc4366 +https://www.rfc-editor.org/info/rfc4512 +https://www.rfc-editor.org/info/rfc4647 +https://www.rfc-editor.org/info/rfc4648 +https://www.rfc-editor.org/info/rfc5116 +https://www.rfc-editor.org/info/rfc5280 +https://www.rfc-editor.org/info/rfc5646 +https://www.rfc-editor.org/info/rfc5869 +https://www.rfc-editor.org/info/rfc5890 +https://www.rfc-editor.org/info/rfc6066 +https://www.rfc-editor.org/info/rfc7301 +https://www.rfc-editor.org/info/rfc7539 +https://www.rfc-editor.org/info/rfc790 +https://www.rfc-editor.org/info/rfc793 +https://www.rfc-editor.org/info/rfc8017 +https://www.rfc-editor.org/info/rfc8032 +https://www.rfc-editor.org/info/rfc822 +https://www.rfc-editor.org/info/rfc919 +https://www.rfc-editor.org/info/rfc9231 +https://www.rfc-editor.org/rfc/rfc2315.txt +https://www.rfc-editor.org/rfc/rfc5208.html +https://www.rfc-editor.org/rfc/rfc5280.html +https://www.rfc-editor.org/rfc/rfc5646 +https://www.rfc-editor.org/rfc/rfc5646.html +https://www.rfc-editor.org/rfc/rfc5869 +https://www.rfc-editor.org/rfc/rfc6943.html +https://www.rfc-editor.org/rfc/rfc8017 +https://www.rfc-editor.org/rfc/rfc8017.html +https://www.rfc-editor.org/rfc/rfc9180 +https://www.schneier.com/blowfish.html +https://www.secg.org/sec2-v2.pdf +https://www.unicode.org/reports/tr15 +https://www.unicode.org/reports/tr15/ +https://www.unicode.org/reports/tr18 +https://www.unicode.org/reports/tr24 +https://www.unicode.org/reports/tr27 +https://www.unicode.org/reports/tr29/ +https://www.unicode.org/reports/tr31 +https://www.unicode.org/reports/tr35 +https://www.unicode.org/reports/tr35/ +https://www.unicode.org/reports/tr35/tr35-collation.html +https://www.unicode.org/reports/tr35/tr35-dates.html +https://www.unicode.org/reports/tr35/tr35-general.html +https://www.unicode.org/reports/tr35/tr35.html +https://www.unicode.org/reports/tr36 +https://www.unicode.org/reports/tr44 +https://www.unicode.org/reports/tr44/ +https://www.usno.navy.mil/USNO +https://www.usno.navy.mil/USNO/time/master-clock/systems-of-time +https://www.w3.org +https://www.w3.org/Daemon/User/Config/Logging.html +https://www.w3.org/TR/1998/REC-html40-19980424/ +https://www.w3.org/TR/1999/REC-xpath-19991116/ +https://www.w3.org/TR/2001/REC-xml-c14n-20010315 +https://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/ +https://www.w3.org/TR/2002/REC-xmldsig-filter2-20021108/ +https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html +https://www.w3.org/TR/CSS22 +https://www.w3.org/TR/CSS22/syndata.html +https://www.w3.org/TR/DOM-Level-3-XPath/ +https://www.w3.org/TR/NOTE-datetime +https://www.w3.org/TR/REC-CSS1 +https://www.w3.org/TR/REC-html32.html +https://www.w3.org/TR/REC-xml-names/ +https://www.w3.org/TR/html4 +https://www.w3.org/TR/html52 +https://www.w3.org/TR/html52/dom.html +https://www.w3.org/TR/html52/syntax.html +https://www.w3.org/TR/xml +https://www.w3.org/TR/xml-c14n11/ +https://www.w3.org/TR/xml/ +https://www.w3.org/TR/xmldsig-core/ +https://www.w3.org/TR/xmlschema-2 +https://www.w3.org/WAI/standards-guidelines/wcag/ +https://www.w3.org/XML/Schema +https://www.w3.org/XML/xml-names-19990114-errata.html +https://www.wapforum.org/what/technical/SPEC-WAESpec-19990524.pdf diff --git a/test/docs/jdk/javadoc/doccheck/checks/jdkCheckExtlinks.java b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckExtlinks.java new file mode 100644 index 00000000000..846cf917c3a --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckExtlinks.java @@ -0,0 +1,31 @@ +/* + * 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 8337109 + * @summary Check external links in the generated documentation + * @library /test/langtools/tools/lib ../../doccheck /test/lib ../../../../tools/tester + * @build DocTester toolbox.TestRunner + * @run main/othervm -Ddoccheck.checks=extlinks DocCheck + */ diff --git a/test/docs/jdk/javadoc/doccheck/checks/jdkCheckHtml.java b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckHtml.java new file mode 100644 index 00000000000..3e9f3ab9f82 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckHtml.java @@ -0,0 +1,31 @@ +/* + * 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 8337109 + * @summary Check the html in the generated documentation + * @library /test/langtools/tools/lib ../../doccheck /test/lib ../../../../tools/tester + * @build DocTester toolbox.TestRunner + * @run main/othervm -Ddoccheck.checks=html DocCheck + */ diff --git a/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java new file mode 100644 index 00000000000..bd818923d9f --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java @@ -0,0 +1,31 @@ +/* + * 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 8337109 + * @summary Check Links in the generated documentation + * @library /test/langtools/tools/lib ../../doccheck /test/lib ../../../../tools/tester + * @build DocTester toolbox.TestRunner + * @run main/othervm -Ddoccheck.checks=links DocCheck + */ diff --git a/test/docs/jdk/javadoc/TestDocs.java b/test/docs/jdk/javadoc/doccheck/checks/jdkDoctypeBadcharsCheck.java similarity index 63% rename from test/docs/jdk/javadoc/TestDocs.java rename to test/docs/jdk/javadoc/doccheck/checks/jdkDoctypeBadcharsCheck.java index 3ccd89ab2e0..a0c145e2b79 100644 --- a/test/docs/jdk/javadoc/TestDocs.java +++ b/test/docs/jdk/javadoc/doccheck/checks/jdkDoctypeBadcharsCheck.java @@ -23,22 +23,9 @@ /* * @test - * @library /test/lib ../../tools/tester - * @build jtreg.SkippedException - * @summary example of a test on the generated documentation - * @run main TestDocs + * @bug 8337109 + * @summary Check doctype and character encoding in the generated documentation + * @library /test/langtools/tools/lib ../../doccheck /test/lib ../../../../tools/tester + * @build DocTester toolbox.TestRunner + * @run main/othervm -Ddoccheck.checks=doctype,badchars DocCheck */ - -import java.nio.file.Files; - -public class TestDocs { - public static void main(String... args) throws Exception { - var docs = DocTester.resolveDocs(); - System.err.println("Path to the docs is: " + docs); - System.err.println("Do docs exits?"); - System.err.println(Files.exists(docs)); - System.err.println("tidy location"); - System.err.println(System.getProperty("tidy")); - System.err.println("End of test"); - } -} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/Checker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/Checker.java new file mode 100644 index 00000000000..614c32105a6 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/Checker.java @@ -0,0 +1,39 @@ +/* + * 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 doccheckutils; + +import java.io.Closeable; + +/** + * Base class for {@link FileChecker file checkers} and + */ +public interface Checker extends Closeable { + + /** + * Writes a report at the end of a run, to summarize the results of the + * checking done by this checker. + */ + void report(); + + boolean isOK(); +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/FileChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileChecker.java new file mode 100644 index 00000000000..4577c3b2b26 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileChecker.java @@ -0,0 +1,30 @@ +/* + * 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 doccheckutils; + +import java.nio.file.Path; +import java.util.List; + +public interface FileChecker extends Checker { + void checkFiles(List files); +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java new file mode 100644 index 00000000000..6ae3a473bdb --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java @@ -0,0 +1,64 @@ +/* + * 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 doccheckutils; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; + +public class FileProcessor { + private final List files; + + public FileProcessor() { + files = new ArrayList<>(); + } + + public List getFiles() { + return files; + } + + public void processFiles(Path directory) { + try { + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.toString().endsWith(".html")) + files.add(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new RuntimeException(); + } + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlChecker.java new file mode 100644 index 00000000000..e27c21ea212 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlChecker.java @@ -0,0 +1,94 @@ +/* + * 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 doccheckutils; + +import java.nio.file.Path; +import java.util.Map; + +/** + * Base class for HTML checkers. + *

+ * For details on HTML syntax and the terms used in this API, see + * W3C The HTML syntax. + */ +public interface HtmlChecker extends Checker { + /** + * Starts checking a new file, + *

+ * The file becomes the current file until {@link #endFile endFile} + * is called. + * + * @param path the file. + */ + void startFile(Path path); + + /** + * Ends checking the current file. + */ + void endFile(); + + /** + * Checks the content of a {@code } declaration in the + * current file. + * + * @param line the line number on which the declaration was found + * @param attrs the content of the declaration + */ + void xml(int line, Map attrs); + + /** + * Checks the content of a {@code } declaration in the + * current file. + * + * @param line the line number on which the declaration was found + * @param docType the content of the declaration + */ + void docType(int line, String docType); + + /** + * Checks the start of an HTML tag in the current file. + * + * @param line the line number on which the start tag for an element was found + * @param name the name of the tag + * @param attrs the attributes of the tag + * @param selfClosing whether the tag is self-closing + */ + void startElement(int line, String name, Map attrs, boolean selfClosing); + + /** + * Checks the end of an HTML tag in the current file. + * + * @param line the line number on which the end tag for an element was found + * @param name the name of the tag + */ + void endElement(int line, String name); + + /** + * Checks the content appearing in between HTML tags. + * + * @param line the line number on which the content was found + * @param content the content + */ + default void content(int line, String content) { + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlFileChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlFileChecker.java new file mode 100644 index 00000000000..e9ba1643c50 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/HtmlFileChecker.java @@ -0,0 +1,389 @@ +/* + * 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 doccheckutils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Reads an HTML file, and calls a series of{@link HtmlChecker HTML checkers} + * for the HTML constructs found therein. + */ +public class HtmlFileChecker implements FileChecker { + private final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder() + .onMalformedInput(CodingErrorAction.IGNORE) + .onUnmappableCharacter(CodingErrorAction.IGNORE); + + private final Log log; + private final HtmlChecker htmlChecker; + private Path path; + private BufferedReader in; + private int ch; + private int lineNumber; + private boolean inScript; + private boolean xml; + + public HtmlFileChecker(HtmlChecker htmlChecker, Path BaseDir) { + this.log = new Log(); + log.setBaseDirectory(BaseDir); + this.htmlChecker = htmlChecker; + } + + @Override + public void checkFiles(List files) { + for (Path file : files) { + read(file); + } + } + + @Override + public void report() { + System.err.println(log); + } + + @Override + public void close() throws IOException { +// report(); + htmlChecker.close(); + } + + private void read(Path path) { + try (BufferedReader r = new BufferedReader( + new InputStreamReader(Files.newInputStream(path), decoder))) { + this.path = path; + this.in = r; + StringBuilder content = new StringBuilder(); + + startFile(path); + try { + lineNumber = 1; + xml = false; + nextChar(); + + while (ch != -1) { + if (ch == '<') { + content(content.toString()); + content.setLength(0); + html(); + } else { + content.append((char) ch); + if (ch == '\n') { + content(content.toString()); + content.setLength(0); + } + nextChar(); + } + } + } finally { + endFile(); + } + } catch (IOException e) { + log.log(path, lineNumber, e); + } catch (Throwable t) { + log.log(path, lineNumber, t); + log.log(String.valueOf(t)); + } + } + + private void startFile(Path path) { + htmlChecker.startFile(path); + } + + private void endFile() { + htmlChecker.endFile(); + } + + private void docType(String s) { + htmlChecker.docType(lineNumber, s); + } + + private void startElement(String name, Map attrs, boolean selfClosing) { + htmlChecker.startElement(lineNumber, name, attrs, selfClosing); + } + + private void endElement(String name) { + htmlChecker.endElement(lineNumber, name); + } + + private void content(String s) { + htmlChecker.content(lineNumber, s); + } + + private void nextChar() throws IOException { + ch = in.read(); + if (ch == '\n') + lineNumber++; + } + + /** + * Read the start or end of an HTML tag, or an HTML comment + * {@literal } or {@literal } + * + * @throws IOException if there is a problem reading the file + */ + protected void html() throws IOException { + nextChar(); + if (isIdentifierStart((char) ch)) { + String name = readIdentifier().toLowerCase(Locale.US); + Map attrs = htmlAttrs(); + if (attrs != null) { + boolean selfClosing = false; + if (ch == '/') { + nextChar(); + selfClosing = true; + } + if (ch == '>') { + nextChar(); + startElement(name, attrs, selfClosing); + if (name.equals("script")) { + inScript = true; + } + return; + } + } + } else if (ch == '/') { + nextChar(); + if (isIdentifierStart((char) ch)) { + String name = readIdentifier().toLowerCase(Locale.US); + skipWhitespace(); + if (ch == '>') { + nextChar(); + endElement(name); + if (name.equals("script")) { + inScript = false; + } + return; + } + } + } else if (ch == '!') { + nextChar(); + if (ch == '-') { + nextChar(); + if (ch == '-') { + nextChar(); + while (ch != -1) { + int dash = 0; + while (ch == '-') { + dash++; + nextChar(); + } + // Strictly speaking, a comment should not contain "--" + // so dash > 2 is an error, dash == 2 implies ch == '>' + // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments + // for more details. + if (dash >= 2 && ch == '>') { + nextChar(); + return; + } + + nextChar(); + } + } + } else if (ch == '[') { + nextChar(); + if (ch == 'C') { + nextChar(); + if (ch == 'D') { + nextChar(); + if (ch == 'A') { + nextChar(); + if (ch == 'T') { + nextChar(); + if (ch == 'A') { + nextChar(); + if (ch == '[') { + while (true) { + nextChar(); + if (ch == ']') { + nextChar(); + if (ch == ']') { + nextChar(); + if (ch == '>') { + nextChar(); + return; + } + } + } + } + + } + } + } + } + } + } + } else { + StringBuilder sb = new StringBuilder(); + while (ch != -1 && ch != '>') { + sb.append((char) ch); + nextChar(); + } + Pattern p = Pattern.compile("(?is)doctype\\s+html\\s?.*"); + String s = sb.toString(); + if (p.matcher(s).matches()) { + xml = s.contains("XHTML"); + docType(s); + return; + } + } + } else if (ch == '?') { + nextChar(); + if (ch == 'x') { + nextChar(); + if (ch == 'm') { + nextChar(); + if (ch == 'l') { + nextChar(); + if (ch == '?') { + nextChar(); + if (ch == '>') { + nextChar(); + xml = true; + return; + } + } + } + } + + } + } + + if (!inScript) { + log.log(path, lineNumber, "bad html"); + } + } + + /** + * Read a series of HTML attributes, terminated by {@literal > }. + * Each attribute is of the form {@literal identifier[=value] }. + * "value" may be unquoted, single-quoted, or double-quoted. + */ + protected Map htmlAttrs() throws IOException { + Map map = new LinkedHashMap<>(); + skipWhitespace(); + + while (isIdentifierStart((char) ch)) { + String name = readAttributeName().toLowerCase(Locale.US); + skipWhitespace(); + String value = null; + if (ch == '=') { + nextChar(); + skipWhitespace(); + if (ch == '\'' || ch == '"') { + char quote = (char) ch; + nextChar(); + StringBuilder sb = new StringBuilder(); + while (ch != -1 && ch != quote) { +// if (ch == '\n') { +// error(path, lineNumber, "unterminated string"); +// // No point trying to read more. +// // In fact, all attrs get discarded by the caller +// // and superseded by a malformed.html node because +// // the html tag itself is not terminated correctly. +// break loop; +// } + sb.append((char) ch); + nextChar(); + } + value = sb.toString() // hack to replace common entities + .replace("<", "<") + .replace(">", ">") + .replace("&", "&"); + nextChar(); + } else { + StringBuilder sb = new StringBuilder(); + while (ch != -1 && !isUnquotedAttrValueTerminator((char) ch)) { + sb.append((char) ch); + nextChar(); + } + value = sb.toString(); + } + skipWhitespace(); + } + map.put(name, value); + } + + return map; + } + + protected boolean isIdentifierStart(char ch) { + return Character.isUnicodeIdentifierStart(ch); + } + + protected String readIdentifier() throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append((char) ch); + nextChar(); + while (ch != -1 && Character.isUnicodeIdentifierPart(ch)) { + sb.append((char) ch); + nextChar(); + } + return sb.toString(); + } + + protected String readAttributeName() throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append((char) ch); + nextChar(); + while ((ch != -1 && Character.isUnicodeIdentifierPart(ch)) + || ch == '-' + || (xml && ch == ':')) { + sb.append((char) ch); + nextChar(); + } + return sb.toString(); + } + + protected boolean isWhitespace(char ch) { + return Character.isWhitespace(ch); + } + + protected void skipWhitespace() throws IOException { + while (isWhitespace((char) ch)) { + nextChar(); + } + } + + protected boolean isUnquotedAttrValueTerminator(char ch) { + return switch (ch) { + case '\f', '\n', '\r', '\t', ' ', '"', '\'', '`', '=', '<', '>' -> true; + default -> false; + }; + } + + @Override + public boolean isOK() { + throw new UnsupportedOperationException(); + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/Log.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/Log.java new file mode 100644 index 00000000000..9626c59e9ca --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/Log.java @@ -0,0 +1,95 @@ +/* + * 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 doccheckutils; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +public class Log { + private final ArrayList errors; + + private Path baseDir; + + public Log() { + errors = new ArrayList<>(); + } + + public List getErrors() { + return errors; + } + + public void log(Path path, int line, String message, Object... args) { + errors.add(formatErrorMessage(path, line, message, args)); + } + + + public String formatErrorMessage(Path path, int line, String message, Object... args) { + return path + ":" + line + ": " + formatErrorMessage(message, args); + } + + public String formatErrorMessage(Path path, int line, Throwable t) { + return path + ":" + line + ": " + t; + } + + public String formatErrorMessage(Path path, Throwable t) { + return path + ": " + t; + } + + + public String formatErrorMessage(String message, Object... args) { + return String.format(message, args); + } + + public void log(String message) { + errors.add(message); + } + + public void log(Path path, int lineNumber, String s, int errorsOnLine) { + log(formatErrorMessage(path, lineNumber, s, errorsOnLine)); + } + + public void log(Path path, int line, Throwable t) { + log(formatErrorMessage(path, line, t)); + } + + public void log(Path path, Throwable t) { + log(formatErrorMessage(path, t)); + } + + public void log(String message, Object... args) { + log(formatErrorMessage(message, args)); + } + + public void setBaseDirectory(Path baseDir) { + this.baseDir = baseDir.toAbsolutePath(); + } + + public Path relativize(Path path) { + return baseDir != null && path.startsWith(baseDir) ? baseDir.relativize(path) : path; + } + + public boolean noErrors() { + return errors.isEmpty(); + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/BadCharacterChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/BadCharacterChecker.java new file mode 100644 index 00000000000..f979c34c9a3 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/BadCharacterChecker.java @@ -0,0 +1,158 @@ +/* + * 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 doccheckutils.checkers; + +import doccheckutils.FileChecker; +import doccheckutils.Log; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Checks the contents of an HTML file for bad/unmappable characters. + *

+ * The file encoding is determined from the file contents. + */ +public class BadCharacterChecker implements FileChecker, AutoCloseable { + private static final Pattern doctype = Pattern.compile("(?i)"); + private static final Pattern metaCharset = Pattern.compile("(?i)"); + private static final Pattern metaContentType = Pattern.compile("(?i)"); + private final Log errors; + private int files = 0; + private int badFiles = 0; + + public BadCharacterChecker() { + errors = new Log(); + } + + public void checkFile(Path path) { + files++; + boolean ok = true; + try (InputStream in = new BufferedInputStream(Files.newInputStream(path))) { + CharsetDecoder d = getCharset(in).newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + BufferedReader r = new BufferedReader(new InputStreamReader(in, d)); + int lineNumber = 0; + String line; + try { + while ((line = r.readLine()) != null) { + lineNumber++; + int errorsOnLine = 0; + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + if (ch == 0xFFFD) { + errorsOnLine++; + } + } + if (errorsOnLine > 0) { + errors.log(path, lineNumber, "found %d invalid characters", errorsOnLine); + ok = false; + } + } + } catch (IOException e) { + errors.log(path, lineNumber, e); + ok = false; + + } + } catch (IOException e) { + errors.log(path, e); + ok = false; + } + if (!ok) + badFiles++; + } + + @Override + public void checkFiles(List files) { + for (Path file : files) { + checkFile(file); + } + } + + private Charset getCharset(InputStream in) throws IOException { + CharsetDecoder initial = StandardCharsets.US_ASCII.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + + in.mark(1024); + try { + BufferedReader r = new BufferedReader(new InputStreamReader(in, initial)); + char[] buf = new char[1024]; + int n = r.read(buf, 0, buf.length); + String head = new String(buf, 0, n); + boolean html5 = doctype.matcher(head).find(); + Matcher m1 = metaCharset.matcher(head); + if (m1.find()) { + return Charset.forName(m1.group(1)); + } + Matcher m2 = metaContentType.matcher(head); + if (m2.find()) { + return Charset.forName(m2.group(1)); + } + return html5 ? StandardCharsets.UTF_8 : StandardCharsets.ISO_8859_1; + } finally { + in.reset(); + } + } + + @Override + public void report() { + if (!errors.noErrors() && files > 0) { + System.err.println("Bad characters found in the generated HTML"); + + System.err.println(MessageFormat.format( + """ + Bad Characters Report + {0} files read + {1} files contained bad characters" + {2} bad characters or other errors found + """, + files, badFiles, files)); + + for (String s : errors.getErrors()) { + System.err.println(s); + } + throw new RuntimeException("Bad character found in the generated HTML"); + } + } + + @Override + public boolean isOK() { + return errors.noErrors(); + } + + @Override + public void close() { + report(); + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/DocTypeChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/DocTypeChecker.java new file mode 100644 index 00000000000..1f53318de18 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/DocTypeChecker.java @@ -0,0 +1,159 @@ +/* + * 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 doccheckutils.checkers; + +import doccheckutils.HtmlChecker; +import doccheckutils.Log; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Checks the DocType declared at the head of an HTML file. + * + * @see + * W3C HTML5 8.1.1 The DOCTYPE + */ +public class DocTypeChecker implements HtmlChecker { + private final Log log; + private final Map counts = new HashMap<>(); + private int html5; + private int html5_legacy; + private int xml; + private int other; + + private Path path; + + public DocTypeChecker() { + log = new Log(); + } + + @Override + public void startFile(Path path) { + this.path = path; + } + + @Override + public void endFile() { + } + + @Override + public void xml(int line, Map attrs) { + xml++; + } + + @Override + public void docType(int line, String docType) { + if (docType.equalsIgnoreCase("doctype html")) { + html5++; + } else { + Pattern p = Pattern.compile("(?i)doctype" + + "\\s+html" + + "\\s+([a-z]+)" + + "\\s+(?:\"([^\"]+)\"|'([^']+)')" + + "(?:\\s+(?:\"([^\"]+)\"|'([^']+)'))?" + + "\\s*"); + Matcher m = p.matcher(docType); + if (m.matches()) { + // See http://www.w3.org/tr/html52/syntax.html#the-doctype + if (m.group(1).equalsIgnoreCase("system") + && m.group(2).equals("about:legacy-compat")) { + html5_legacy++; + } else { + String version = m.group(2); + List allowedVersions = List.of( + "-//W3C//DTD XHTML 1.0 Strict//EN" + ); + if (allowedVersions.stream().noneMatch(v -> v.equals(version))) { + log.log(path, line, "unexpected doctype: " + version); + } + counts.put(version, counts.getOrDefault(version, 0) + 1); + } + } else { + log.log(path, line, "doctype not recognized: " + docType); + other++; + } + } + } + + @Override + public void startElement(int line, String name, Map attrs, boolean selfClosing) { + } + + @Override + public void endElement(int line, String name) { + } + + @Override + public void report() { + log.log("DocType Report"); + if (xml > 0) { + log.log("%6d: XHTML%n", xml); + } + if (html5 > 0) { + log.log("%6d: HTML5%n", html5); + } + if (html5_legacy > 0) { + log.log("%6d: HTML5 (legacy)%n", html5_legacy); + } + + Map> sortedCounts = new TreeMap<>(Comparator.reverseOrder()); + + for (Map.Entry e : counts.entrySet()) { + String s = e.getKey(); + Integer n = e.getValue(); + Set set = sortedCounts.computeIfAbsent(n, k -> new TreeSet<>()); + set.add(s); + } + + for (Map.Entry> e : sortedCounts.entrySet()) { + for (String p : e.getValue()) { + log.log("%6d: %s%n", e.getKey(), p); + } + } + + if (other > 0) { + log.log("%6d: other/unrecognized%n", other); + } + + for (var line : log.getErrors()) { + System.err.println(line); + } + } + + @Override + public boolean isOK() { + return counts.isEmpty() && (other == 0); + } + + @Override + public void close() { + if (!isOK()) { + report(); + throw new RuntimeException("Found HTML files with missing doctype declaration"); + } + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/ExtLinkChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/ExtLinkChecker.java new file mode 100644 index 00000000000..7e6c5a8ed5a --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/ExtLinkChecker.java @@ -0,0 +1,220 @@ +/* + * 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 doccheckutils.checkers; + + +import doccheckutils.HtmlChecker; +import doccheckutils.Log; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Checks the external links referenced in HTML files. + */ +public class ExtLinkChecker implements HtmlChecker, AutoCloseable { + private static final Path testBasePath = Path.of(System.getProperty("test.src")); + private static final Set extLinks = new HashSet<>(); + + private static final String currentVersion = String.valueOf(Runtime.version().feature()); + + static { + String input = null; + try { + input = Files.readString(testBasePath.getParent().resolve("ExtLinksJdk.txt")); + } catch (IOException e) { + throw new RuntimeException(e); + } + extLinks.addAll(input.lines() + .filter(line -> !line.startsWith("#")) + .map(line -> line.replaceAll("\\@\\@JAVASE_VERSION\\@\\@", currentVersion)) + .collect(Collectors.toUnmodifiableSet())); + } + + private final Log log; + private final Map> allURIs; + private int badURIs; + private Path currFile; + + public ExtLinkChecker() { + this.log = new Log(); + allURIs = new TreeMap<>(); + } + + @Override + public void startFile(Path path) { + currFile = path.toAbsolutePath().normalize(); + } + + @Override + public void endFile() { + } + + @Override + public void xml(int line, Map attrs) { + } + + @Override + public void docType(int line, String doctype) { + } + + @Override + @SuppressWarnings("fallthrough") + public void startElement(int line, String name, Map attrs, boolean selfClosing) { + switch (name) { + case "a": + case "link": + String href = attrs.get("href"); + if (href != null) { + foundReference(line, href); + } + break; + } + } + + @Override + public void endElement(int line, String name) { + } + + private void foundReference(int line, String ref) { + try { + String uriPath = ref; + String fragment = null; + + // The checker runs into a problem with links that have more than one hash character. + // You cannot create a URI unless the second hash is escaped. + + int firstHashIndex = ref.indexOf('#'); + int lastHashIndex = ref.lastIndexOf('#'); + if (firstHashIndex != -1 && firstHashIndex != lastHashIndex) { + uriPath = ref.substring(0, firstHashIndex); + fragment = ref.substring(firstHashIndex + 1).replace("#", "%23"); + } else if (firstHashIndex != -1) { + uriPath = ref.substring(0, firstHashIndex); + fragment = ref.substring(firstHashIndex + 1); + } + + URI uri = new URI(uriPath); + if (fragment != null) { + uri = new URI(uri + "#" + fragment); + } + + if (uri.isAbsolute()) { + if (Objects.equals(uri.getScheme(), "javascript")) { + // ignore JavaScript URIs + return; + } + String rawFragment = uri.getRawFragment(); + URI noFrag = new URI(uri.toString().replaceAll("#\\Q" + rawFragment + "\\E$", "")); + allURIs.computeIfAbsent(noFrag, _ -> new LinkedHashSet<>()).add(currFile); + } + } catch (URISyntaxException e) { + log.log(currFile, line, "invalid URI: " + e); + } + } + + @Override + public void report() { + checkURIs(); + } + + @Override + public boolean isOK() { + return badURIs == 0; + } + + @Override + public void close() { + report(); + } + + private void checkURIs() { + System.err.println("ExtLinkChecker: checking external links"); + allURIs.forEach(this::checkURI); + System.err.println("ExtLinkChecker: finished checking external links"); + } + + private void checkURI(URI uri, Set files) { + try { + switch (uri.getScheme()) { + case "ftp": + case "http": + case "https": + isVettedLink(uri, files); + break; + default: + warning(files, uri); + } + } catch (Throwable t) { + badURIs++; + error(files, uri, t); + } + } + + private void isVettedLink(URI uri, Set files) { + if (!extLinks.contains(uri.toString())) { + System.err.println(MessageFormat.format(""" + The external link {0} needs to be added to the whitelist test/docs/jdk/javadoc/doccheck/ExtLinksJdk.txt in order to be checked regularly\s + The link is present in: + {1}\n + """, uri, files.stream().map(Path::toString).collect(Collectors.joining("\n ")))); + } + } + + private void warning(Set files, Object... args) { + Iterator iter = files.iterator(); + Path first = iter.next(); + log.log(String.valueOf(first), "URI not supported: %s", args); + reportAlsoFoundIn(iter); + } + + private void error(Set files, Object... args) { + Iterator iter = files.iterator(); + Path first = iter.next(); + log.log(String.valueOf(first), "Exception accessing uri: %s%n [%s]", args); + reportAlsoFoundIn(iter); + } + + private void reportAlsoFoundIn(Iterator iter) { + int MAX_EXTRA = 10; + int n = 0; + while (iter.hasNext()) { + log.log(" Also found in %s", log.relativize(iter.next())); + if (n++ == MAX_EXTRA) { + int rest = 0; + while (iter.hasNext()) { + iter.next(); + rest++; + } + log.log(" ... and %d more", rest); + } + } + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java new file mode 100644 index 00000000000..62ead5a25d3 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java @@ -0,0 +1,440 @@ +/* + * 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 doccheckutils.checkers; + + +import doccheckutils.HtmlChecker; +import doccheckutils.Log; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +/** + * Checks the links defined by and referenced in HTML files. + */ +public class LinkChecker implements HtmlChecker { + + private final Log log; + private final Map allFiles; + private final Map allURIs; + // left for debugging + private final boolean checkInwardReferencesOnly = false; + private int files; + private int links; + private int duplicateIds; + private int missingFiles; + private int missingIds; + private int badSchemes; + private Path currFile; + private IDTable currTable; + private boolean html5; + public LinkChecker() { + this.log = new Log(); + allFiles = new HashMap<>(); + allURIs = new HashMap<>(); + } + + public void setBaseDir(Path dir) { + log.setBaseDirectory(dir); + } + + @Override + public void startFile(Path path) { + currFile = path.toAbsolutePath().normalize(); + currTable = allFiles.computeIfAbsent(currFile, p -> new IDTable(log.relativize(p))); + html5 = false; + files++; + } + + @Override + public void endFile() { + currTable.check(); + } + + + //unused + public List getUncheckedFiles() { + return allFiles.entrySet().stream() + .filter(e -> !e.getValue().checked + && e.getKey().toString().endsWith(".html") + && Files.exists(e.getKey())) + .map(Map.Entry::getKey) + .toList(); + } + + public List getMissingFiles() { + return allFiles.keySet().stream() + .filter(idTable -> !Files.exists(idTable)).toList(); + } + + @Override + public void xml(int line, Map attrs) { + } + + @Override + public void docType(int line, String doctype) { + html5 = doctype.matches("(?i)<\\?doctype\\s+html>"); + } + + @Override + @SuppressWarnings("fallthrough") + public void startElement(int line, String name, Map attrs, boolean selfClosing) { + switch (name) { + case "a": + String nameAttr = html5 ? null : attrs.get("name"); + if (nameAttr != null) { + foundAnchor(line, nameAttr); + } + // fallthrough + case "link": + String href = attrs.get("href"); + if (href != null && !checkInwardReferencesOnly) { + foundReference(line, href); + } + break; + } + + String idAttr = attrs.get("id"); + if (idAttr != null) { + foundAnchor(line, idAttr); + } + } + + @Override + public void endElement(int line, String name) { + } + + @Override + public void content(int line, String content) { + HtmlChecker.super.content(line, content); + } + + @Override + public void report() { + List pathList = getMissingFiles(); + log.log(""); + log.log("Link Checker Report"); + + if (!pathList.isEmpty()) { + log.log(""); + log.log("Missing files: (" + pathList.size() + ")"); + pathList.stream() + .sorted() + .forEach(this::reportMissingFile); + } + + int anchors = 0; + for (IDTable t : allFiles.values()) { + anchors += (int) t.map.values().stream() + .filter(e -> !e.getReferences().isEmpty()) + .count(); + } + for (IDTable t : allURIs.values()) { + anchors += (int) t.map.values().stream() + .filter(e -> !e.references.isEmpty()) + .count(); + } + + log.log("Checked " + files + " files."); + log.log("Found " + links + " references to " + anchors + " anchors " + + "in " + allFiles.size() + " files and " + allURIs.size() + " other URIs."); + if (!pathList.isEmpty()) { + log.log("%6d missing files", pathList.size()); + } + if (duplicateIds > 0) { + log.log("%6d duplicate ids", duplicateIds); + + } + if (missingIds > 0) { + log.log("%6d missing ids", missingIds); + + } + + Map hostCounts = new TreeMap<>(new HostComparator()); + for (URI uri : allURIs.keySet()) { + String host = uri.getHost(); + if (host != null) { + hostCounts.put(host, hostCounts.computeIfAbsent(host, h -> 0) + 1); + } + } + +// if (hostCounts.size() > 0) { +// log.log(""); +// log.log("Hosts"); +// hostCounts.forEach((h, n) -> log.log("%6d %s", n, h)); +// } + + + for (String message : log.getErrors()) { + System.err.println(message); + } + + } + + private void reportMissingFile(Path file) { + log.log(log.relativize(file).toString()); + IDTable table = allFiles.get(file); + Set refs = new TreeSet<>(); + for (IDInfo id : table.map.values()) { + if (id.references != null) { + for (Position ref : id.references) { + refs.add(ref.path); + } + } + } + int n = 0; + int MAX_REFS = 10; + for (Path ref : refs) { + log.log(" in " + log.relativize(ref)); + if (++n == MAX_REFS) { + log.log(" ... and %d more", refs.size() - n); + break; + } + } + missingFiles++; + } + + @Override + public boolean isOK() { + return duplicateIds == 0 + && missingIds == 0 + && missingFiles == 0 + && badSchemes == 0; + } + + @Override + public void close() { + report(); + if (!isOK()) { + throw new RuntimeException( + "LinkChecker encountered errors. Duplicate IDs: " + + duplicateIds + ", Missing IDs: " + missingIds + + ", Missing Files: " + missingFiles + ", Bad Schemes: " + badSchemes); + } + } + + private void foundAnchor(int line, String name) { + currTable.addID(line, name); + } + + private void foundReference(int line, String ref) { + links++; + try { + String uriPath = ref; + String fragment = null; + + // The checker runs into a problem with links that have more than one hash character. + // You cannot create a URI unless the second hash is escaped. + + int firstHashIndex = ref.indexOf('#'); + int lastHashIndex = ref.lastIndexOf('#'); + if (firstHashIndex != -1 && firstHashIndex != lastHashIndex) { + uriPath = ref.substring(0, firstHashIndex); + fragment = ref.substring(firstHashIndex + 1).replace("#", "%23"); + } else if (firstHashIndex != -1) { + uriPath = ref.substring(0, firstHashIndex); + fragment = ref.substring(firstHashIndex + 1); + } + + URI uri = new URI(uriPath); + if (fragment != null) { + uri = new URI(uri + "#" + fragment); + } + + if (uri.isAbsolute()) { + foundReference(line, uri); + } else { + Path p; + String resolvedUriPath = uri.getPath(); + if (resolvedUriPath == null || resolvedUriPath.isEmpty()) { + p = currFile; + } else { + p = currFile.getParent().resolve(resolvedUriPath).normalize(); + } + + if (fragment != null && !fragment.isEmpty()) { + foundReference(line, p, fragment); + } + } + } catch (URISyntaxException e) { + System.err.println("Failed to create URI: " + ref); + log.log(currFile, line, "invalid URI: " + e); + } + } + + + private void foundReference(int line, Path p, String fragment) { + IDTable t = allFiles.computeIfAbsent(p, key -> new IDTable(log.relativize(key))); + t.addReference(fragment, currFile, line); + } + + private void foundReference(int line, URI uri) { + if (!isSchemeOK(uri.getScheme()) && !checkInwardReferencesOnly) { + log.log(currFile, line, "bad scheme in URI"); + badSchemes++; + } + + String fragment = uri.getRawFragment(); + if (fragment != null && !fragment.isEmpty()) { + try { + URI noFrag = new URI(uri.toString().replaceAll("#\\Q" + fragment + "\\E$", "")); + IDTable t = allURIs.computeIfAbsent(noFrag, IDTable::new); + t.addReference(fragment, currFile, line); + } catch (URISyntaxException e) { + throw new Error(e); + } + } + } + + private boolean isSchemeOK(String uriScheme) { + if (uriScheme == null) { + return true; + } + + return switch (uriScheme) { + case "ftp", "http", "https", "javascript" -> true; + default -> false; + }; + } + + static class Position implements Comparable { + Path path; + int line; + + Position(Path path, int line) { + this.path = path; + this.line = line; + } + + @Override + public int compareTo(Position o) { + int v = path.compareTo(o.path); + return v != 0 ? v : Integer.compare(line, o.line); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null || getClass() != obj.getClass()) { + return false; + } else { + final Position other = (Position) obj; + return Objects.equals(this.path, other.path) + && this.line == other.line; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(path) * 37 + line; + } + } + + static class IDInfo { + boolean declared; + Set references; + + Set getReferences() { + return references == null ? Collections.emptySet() : references; + } + } + + static class HostComparator implements Comparator { + @Override + public int compare(String h1, String h2) { + List l1 = new ArrayList<>(Arrays.asList(h1.split("\\."))); + Collections.reverse(l1); + String r1 = String.join(".", l1); + List l2 = new ArrayList<>(Arrays.asList(h2.split("\\."))); + Collections.reverse(l2); + String r2 = String.join(".", l2); + return r1.compareTo(r2); + } + } + + class IDTable { + private final Map map = new HashMap<>(); + private final String pathOrURI; + private boolean checked; + + IDTable(Path path) { + this.pathOrURI = path.toString(); + } + + IDTable(URI uri) { + this.pathOrURI = uri.toString(); + } + + void addID(int line, String name) { + if (checked) { + throw new IllegalStateException("Adding ID after file has been"); + } + Objects.requireNonNull(name); + IDInfo info = map.computeIfAbsent(name, _ -> new IDInfo()); + if (info.declared) { + if (info.references != null || !checkInwardReferencesOnly) { + // don't report error if we're only checking inbound references + // and there are no references to this ID. + log.log(log.relativize(currFile), line, "name already declared: " + name); + duplicateIds++; + } + } else { + info.declared = true; + } + } + + void addReference(String name, Path from, int line) { + if (checked) { + if (name != null) { + IDInfo id = map.get(name); + if (id == null || !id.declared) { + log.log(log.relativize(from), line, "id not found: " + this.pathOrURI + "#" + name); + } + } + } else { + IDInfo id = map.computeIfAbsent(name, x -> new IDInfo()); + if (id.references == null) { + id.references = new TreeSet<>(); + } + id.references.add(new Position(from, line)); + } + } + + void check() { + map.forEach((name, id) -> { + if (name != null && !id.declared) { + for (Position ref : id.references) { + log.log(log.relativize(ref.path), ref.line, "id not found: " + this.pathOrURI + "#" + name); + } + missingIds++; + } + }); + checked = true; + } + } +} diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/TidyChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/TidyChecker.java new file mode 100644 index 00000000000..727e90a76e3 --- /dev/null +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/TidyChecker.java @@ -0,0 +1,259 @@ +/* + * 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 doccheckutils.checkers; + + +import doccheckutils.FileChecker; +import doccheckutils.Log; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class TidyChecker implements FileChecker, AutoCloseable { + private final Path TIDY; + final Map counts = new HashMap<>(); + final Pattern okPattern = Pattern.compile("No warnings or errors were found."); + final Pattern countPattern = Pattern.compile("([0-9]+) warnings, ([0-9]+) errors were found!.*?(Not all warnings/errors were shown.)?"); + final Pattern countPattern2 = Pattern.compile("Tidy found ([0-9]+) warning[s]? and ([0-9]+) error[s]?!.*?(Not all warnings/errors were shown.)?"); + final Pattern cssPattern = Pattern.compile("You are recommended to use CSS.*"); + final Pattern guardPattern = Pattern.compile("(line [0-9]+ column [0-9]+ - |[^:]+:[0-9]+:[0-9]+: )(Error|Warning):.*"); + + final Pattern[] patterns = { + Pattern.compile(".*Error: <.*> is not recognized!"), + Pattern.compile(".*Error: missing quote mark for attribute value"), + Pattern.compile(".*Warning: '<' \\+ '/' \\+ letter not allowed here"), + Pattern.compile(".*Warning: <.*> anchor \".*\" already defined"), + Pattern.compile(".*Warning: <.*> attribute \".*\" has invalid value \".*\""), + Pattern.compile(".*Warning: <.*> attribute \".*\" lacks value"), + Pattern.compile(".*Warning: <.*> attribute \".*\" lacks value"), + Pattern.compile(".*Warning: <.*> attribute with missing trailing quote mark"), + Pattern.compile(".*Warning: <.*> dropping value \".*\" for repeated attribute \".*\""), + Pattern.compile(".*Warning: <.*> inserting \".*\" attribute"), + Pattern.compile(".*Warning: <.*> is probably intended as "), + Pattern.compile(".*Warning: <.*> isn't allowed in <.*> elements"), + Pattern.compile(".*Warning: <.*> lacks \".*\" attribute"), + Pattern.compile(".*Warning: <.*> missing '>' for end of tag"), + Pattern.compile(".*Warning: <.*> proprietary attribute \".*\""), + Pattern.compile(".*Warning: <.*> unexpected or duplicate quote mark"), + Pattern.compile(".*Warning: id and name attribute value mismatch"), + Pattern.compile(".*Warning: cannot copy name attribute to id"), + Pattern.compile(".*Warning: escaping malformed URI reference"), + Pattern.compile(".*Warning:

proprietary attribute \"pre\""), + Pattern.compile(".*Warning: discarding unexpected <.*>"), + Pattern.compile(".*Warning: discarding unexpected "), + Pattern.compile(".*Warning: entity \".*\" doesn't end in ';'"), + Pattern.compile(".*Warning: inserting implicit <.*>"), + Pattern.compile(".*Warning: inserting missing 'title' element"), + Pattern.compile(".*Warning: missing declaration"), + Pattern.compile(".*Warning: missing <.*>"), + Pattern.compile(".*Warning: missing before <.*>"), + Pattern.compile(".*Warning: nested emphasis <.*>"), + Pattern.compile(".*Warning: plain text isn't allowed in <.*> elements"), + Pattern.compile(".*Warning: removing whitespace preceding XML Declaration"), + Pattern.compile(".*Warning: replacing

(by|with)
"), + Pattern.compile(".*Warning: replacing invalid numeric character reference .*"), + Pattern.compile(".*Warning: replacing obsolete element

with <pre>"), + Pattern.compile(".*Warning: replacing unexpected .* (by|with) </.*>"), + Pattern.compile(".*Warning: trimming empty <.*>"), + Pattern.compile(".*Warning: unescaped & or unknown entity \".*\""), + Pattern.compile(".*Warning: unescaped & which should be written as &amp;"), + Pattern.compile(".*Warning: using <br> in place of <p>"), + Pattern.compile(".*Warning: <.*> element removed from HTML5"), + Pattern.compile(".*Warning: <.*> attribute \".*\" not allowed for HTML5"), + Pattern.compile(".*Warning: The summary attribute on the <table> element is obsolete in HTML5"), + Pattern.compile(".*Warning: replacing invalid UTF-8 bytes \\(char. code U\\+.*\\)") + }; + private final Log errors; + private int files = 0; + private int ok; + private int warns; + private int errs; + private int css; + private int overflow; + + public TidyChecker() { + TIDY = initTidy(); + errors = new Log(); + } + + @Override + public void checkFiles(List<Path> sb) { + files += sb.size(); + try { + for (int i = 0; i < sb.size(); i += 1024) { + List<String> command = new ArrayList<>(); + command.add(TIDY.toString()); + command.add("-q"); + command.add("-e"); + command.add("--gnu-emacs"); + command.add("true"); + List<Path> sublist = sb.subList(i, Math.min(i + 1024, sb.size())); + for (Path p : sublist) { + command.add(p.toString()); + } + Process p = new ProcessBuilder() + .command(command) + .redirectErrorStream(true) + .start(); + try (BufferedReader r = + new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = r.readLine()) != null) { + checkLine(line); + } + } + } + } catch (IOException e) { + throw new RuntimeException(); + } + } + + private Path initTidy() { + Path tidyExePath; + String tidyProperty = System.getProperty("tidy"); + if (tidyProperty != null) { + tidyExePath = Path.of(tidyProperty); + if (!Files.exists(tidyExePath)) { + System.err.println("tidy not found: " + tidyExePath); + } + if (!Files.isExecutable(tidyExePath)) { + System.err.println("tidy not executable: " + tidyExePath); + } + } else { + boolean isWindows = System.getProperty("os.name") + .toLowerCase(Locale.US) + .startsWith("windows"); + String tidyExe = isWindows ? "tidy.exe" : "tidy"; + Optional<Path> p = Stream.of(System.getenv("PATH") + .split(File.pathSeparator)) + .map(Path::of) + .map(d -> d.resolve(tidyExe)) + .filter(Files::exists) + .filter(Files::isExecutable) + .findFirst(); + if (p.isPresent()) { + tidyExePath = p.get(); + } else { + System.err.println("tidy not found on PATH"); + return Path.of("tidy"); //non-null placeholder return; exception would be better + } + } + + try { + Process p = new ProcessBuilder() + .command(tidyExePath.toString(), "-version") + .redirectErrorStream(true) + .start(); + try (BufferedReader r = + new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8))) { + List<String> lines = r.lines().collect(Collectors.toList()); + // Look for a line containing "version" and a dotted identifier beginning 5. + // If not found, look for known old/bad versions, to report in error message + Pattern version = Pattern.compile("version.* [5678]\\.\\d+(\\.\\d+)"); + if (lines.stream().noneMatch(line -> version.matcher(line).find())) { + Pattern oldVersion = Pattern.compile("2006"); // 2006 implies old macOS version + String lineSep = System.lineSeparator(); + String message = lines.stream().anyMatch(line -> oldVersion.matcher(line).find()) + ? "old version of 'tidy' found on the PATH\n" + : "could not determine the version of 'tidy' on the PATH\n"; + System.err.println(message + String.join(lineSep, lines)); + } + } + } catch (IOException e) { + System.err.println("Could not execute 'tidy -version': " + e); + } + + return tidyExePath; + } + + @Override + public void report() { + if (files > 0) { + System.err.println("Tidy found errors in the generated HTML"); + if (!errors.noErrors()) { + for (String s : errors.getErrors()) { + System.err.println(s); + } + System.err.println("Tidy output end."); + System.err.println(); + System.err.println(); + throw new RuntimeException("Tidy found errors in the generated HTML"); + } + } + } + + @Override + public boolean isOK() { + return (ok == files) + && (overflow == 0) + && (errs == 0) + && (warns == 0) + && (css == 0); + } + + void checkLine(String line) { + Matcher m; + if (okPattern.matcher(line).matches()) { + ok++; + } else if ((m = countPattern.matcher(line)).matches() || (m = countPattern2.matcher(line)).matches()) { + warns += Integer.parseInt(m.group(1)); + errs += Integer.parseInt(m.group(2)); + if (m.group(3) != null) + overflow++; + } else if (guardPattern.matcher(line).matches()) { + boolean found = false; + for (Pattern p : patterns) { + if (p.matcher(line).matches()) { + errors.log("%s", line); + found = true; + count(p); + break; + } + } + if (!found) + errors.log("unrecognized line: " + line); + } else if (cssPattern.matcher(line).matches()) { + css++; + } + } + + void count(Pattern p) { + Integer i = counts.get(p); + counts.put(p, (i == null) ? 1 : i + 1); + } + + @Override + public void close() { + report(); + } +} From 408a725dd63be4a7403f9d80d0183060d1308379 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore <wetmore@openjdk.org> Date: Mon, 23 Dec 2024 19:05:07 +0000 Subject: [PATCH 12/99] 8345840: Add missing TLS handshake messages to SSLHandshake.java Reviewed-by: jnimeh --- .../sun/security/ssl/SSLHandshake.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java b/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java index 4c931c93fea..7c78f6c3005 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, 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,6 +31,15 @@ import java.util.Map; import javax.net.ssl.SSLException; +/** + * An enum of the defined TLS handshake message types. + * <p> + * These are defined in the IANA TLS Parameters. + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 + * <p> + * Most of these come from the SLS/TLS specs in RFCs 6601/2246/4346/8446 and + * friends. Others are called out where defined. + */ enum SSLHandshake implements SSLConsumer, HandshakeProducer { @SuppressWarnings({"unchecked", "rawtypes"}) HELLO_REQUEST ((byte)0x00, "hello_request", @@ -81,6 +90,10 @@ enum SSLHandshake implements SSLConsumer, HandshakeProducer { ) }), + // Even though there is a TLS HandshakeType entry for + // hello_retry_request_RESERVED (0x06), the TLSv1.3 (RFC 8446) + // HelloRetryRequest is actually a ServerHello with a specific Random value + // (Section 4.1.3). @SuppressWarnings({"unchecked", "rawtypes"}) HELLO_RETRY_REQUEST ((byte)0x02, "hello_retry_request", new Map.Entry[] { @@ -130,6 +143,7 @@ enum SSLHandshake implements SSLConsumer, HandshakeProducer { ProtocolVersion.PROTOCOLS_TO_12 ) }), + END_OF_EARLY_DATA ((byte)0x05, "end_of_early_data"), @SuppressWarnings({"unchecked", "rawtypes"}) @@ -147,6 +161,10 @@ enum SSLHandshake implements SSLConsumer, HandshakeProducer { ) }), + // RFC 9147 - DTLS 1.3 + REQUEST_CONNECTION_ID ((byte)0x09, "request_connection_id"), + NEW_CONNECTION_ID ((byte)0x0a, "new_connection_id"), + @SuppressWarnings({"unchecked", "rawtypes"}) CERTIFICATE ((byte)0x0B, "certificate", new Map.Entry[] { @@ -285,6 +303,9 @@ enum SSLHandshake implements SSLConsumer, HandshakeProducer { ) }), + // RFC 9261 - Exported Authenticators + CLIENT_CERTIFICATE_REQUEST ((byte)0x11, "client_certificate_request"), + @SuppressWarnings({"unchecked", "rawtypes"}) FINISHED ((byte)0x14, "finished", new Map.Entry[] { @@ -347,6 +368,13 @@ enum SSLHandshake implements SSLConsumer, HandshakeProducer { ProtocolVersion.PROTOCOLS_OF_13 ) }), + + // RFC 8879 - TLS Certificate Compression + COMPRESSED_CERTIFICATE ((byte)0x19, "compressed_certificate"), + + // RFC 8870 - Encrypted Key Transport for DTLS/Secure RTP + EKT_KEY ((byte)0x1A, "ekt_key"), + MESSAGE_HASH ((byte)0xFE, "message_hash"), NOT_APPLICABLE ((byte)0xFF, "not_applicable"); From f5520857863d4c720344961803abd9db6b7771b9 Mon Sep 17 00:00:00 2001 From: Nizar Benalla <nbenalla@openjdk.org> Date: Tue, 24 Dec 2024 18:23:14 +0000 Subject: [PATCH 13/99] 8346295: Update --release 24 symbol information for JDK 24 build 29 Reviewed-by: liach --- src/jdk.compiler/share/data/symbols/java.base-O.sym.txt | 4 +++- src/jdk.compiler/share/data/symbols/java.se-O.sym.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/jdk.compiler/share/data/symbols/java.base-O.sym.txt b/src/jdk.compiler/share/data/symbols/java.base-O.sym.txt index dae8317f73b..e3a1eb04b46 100644 --- a/src/jdk.compiler/share/data/symbols/java.base-O.sym.txt +++ b/src/jdk.compiler/share/data/symbols/java.base-O.sym.txt @@ -27,7 +27,7 @@ # ########################################################## # module name java.base -header exports java/io,java/lang,java/lang/annotation,java/lang/classfile,java/lang/classfile/attribute,java/lang/classfile/constantpool,java/lang/classfile/instruction,java/lang/constant,java/lang/foreign,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/javac[java.compiler\u005C;u002C;java.desktop\u005C;u002C;java.se\u005C;u002C;jdk.compiler\u005C;u002C;jdk.incubator.vector\u005C;u002C;jdk.jartool\u005C;u002C;jdk.jdeps\u005C;u002C;jdk.jfr\u005C;u002C;jdk.jlink\u005C;u002C;jdk.jshell],jdk/internal/vm/vector[jdk.incubator.vector] extraModulePackages jdk/internal/access/foreign,jdk/internal/classfile/impl,jdk/internal/constant,jdk/internal/foreign/abi,jdk/internal/foreign/abi/aarch64/linux,jdk/internal/foreign/abi/aarch64/macos,jdk/internal/foreign/abi/aarch64/windows,jdk/internal/foreign/abi/fallback,jdk/internal/foreign/abi/ppc64/aix,jdk/internal/foreign/abi/ppc64/linux,jdk/internal/foreign/abi/riscv64/linux,jdk/internal/foreign/abi/s390/linux,jdk/internal/foreign/abi/x64/sysv,jdk/internal/foreign/abi/x64/windows,jdk/internal/foreign/layout,sun/nio/ch,sun/net,jdk/internal/foreign,jdk/internal/foreign,sun/net,sun/nio/ch uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/InetAddressResolverProvider,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/io/JdkConsoleProvider,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target macos-aarch64 flags 8000 +header exports java/io,java/lang,java/lang/annotation,java/lang/classfile,java/lang/classfile/attribute,java/lang/classfile/constantpool,java/lang/classfile/instruction,java/lang/constant,java/lang/foreign,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/javac[java.compiler\u005C;u002C;java.desktop\u005C;u002C;jdk.compiler\u005C;u002C;jdk.incubator.vector\u005C;u002C;jdk.jartool\u005C;u002C;jdk.jdeps\u005C;u002C;jdk.jfr\u005C;u002C;jdk.jlink\u005C;u002C;jdk.jshell],jdk/internal/vm/vector[jdk.incubator.vector] extraModulePackages jdk/internal/access/foreign,jdk/internal/classfile/impl,jdk/internal/constant,jdk/internal/foreign/abi,jdk/internal/foreign/abi/aarch64/linux,jdk/internal/foreign/abi/aarch64/macos,jdk/internal/foreign/abi/aarch64/windows,jdk/internal/foreign/abi/fallback,jdk/internal/foreign/abi/ppc64/aix,jdk/internal/foreign/abi/ppc64/linux,jdk/internal/foreign/abi/riscv64/linux,jdk/internal/foreign/abi/s390/linux,jdk/internal/foreign/abi/x64/sysv,jdk/internal/foreign/abi/x64/windows,jdk/internal/foreign/layout,sun/nio/ch,sun/net,jdk/internal/foreign,jdk/internal/foreign,sun/net,sun/nio/ch uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/InetAddressResolverProvider,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/io/JdkConsoleProvider,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target macos-aarch64 flags 8000 class name java/io/BufferedInputStream -method name read descriptor ()I @@ -970,9 +970,11 @@ header extends java/lang/Object implements java/lang/classfile/ClassFileTransfor class name java/lang/classfile/CompoundElement header extends java/lang/Object implements java/lang/classfile/ClassFileElement,java/lang/Iterable sealed true permittedSubclasses java/lang/classfile/ClassModel,java/lang/classfile/CodeModel,java/lang/classfile/FieldModel,java/lang/classfile/MethodModel,jdk/internal/classfile/impl/AbstractUnboundModel flags 601 signature <E::Ljava/lang/classfile/ClassFileElement;>Ljava/lang/Object;Ljava/lang/classfile/ClassFileElement;Ljava/lang/Iterable<TE;>; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 -method name forEachElement descriptor (Ljava/util/function/Consumer;)V -method name elements descriptor ()Ljava/lang/Iterable; method name forEach descriptor (Ljava/util/function/Consumer;)V flags 401 signature (Ljava/util/function/Consumer<-TE;>;)V +method name toDebugString descriptor ()Ljava/lang/String; flags 1 class name java/lang/classfile/CustomAttribute header extends java/lang/Object implements java/lang/classfile/Attribute,java/lang/classfile/CodeElement,java/lang/classfile/ClassElement,java/lang/classfile/MethodElement,java/lang/classfile/FieldElement flags 421 signature <T:Ljava/lang/classfile/CustomAttribute<TT;>;>Ljava/lang/Object;Ljava/lang/classfile/Attribute<TT;>;Ljava/lang/classfile/CodeElement;Ljava/lang/classfile/ClassElement;Ljava/lang/classfile/MethodElement;Ljava/lang/classfile/FieldElement; diff --git a/src/jdk.compiler/share/data/symbols/java.se-O.sym.txt b/src/jdk.compiler/share/data/symbols/java.se-O.sym.txt index 65b19c089fe..e6caf5dac14 100644 --- a/src/jdk.compiler/share/data/symbols/java.se-O.sym.txt +++ b/src/jdk.compiler/share/data/symbols/java.se-O.sym.txt @@ -27,5 +27,5 @@ # ########################################################## # module name java.se -header requires name\u0020;java.base\u0020;flags\u0020;20,name\u0020;java.compiler\u0020;flags\u0020;20,name\u0020;java.datatransfer\u0020;flags\u0020;20,name\u0020;java.desktop\u0020;flags\u0020;20,name\u0020;java.instrument\u0020;flags\u0020;20,name\u0020;java.logging\u0020;flags\u0020;20,name\u0020;java.management\u0020;flags\u0020;20,name\u0020;java.management.rmi\u0020;flags\u0020;20,name\u0020;java.naming\u0020;flags\u0020;20,name\u0020;java.net.http\u0020;flags\u0020;20,name\u0020;java.prefs\u0020;flags\u0020;20,name\u0020;java.rmi\u0020;flags\u0020;20,name\u0020;java.scripting\u0020;flags\u0020;20,name\u0020;java.security.jgss\u0020;flags\u0020;20,name\u0020;java.security.sasl\u0020;flags\u0020;20,name\u0020;java.sql\u0020;flags\u0020;20,name\u0020;java.sql.rowset\u0020;flags\u0020;20,name\u0020;java.transaction.xa\u0020;flags\u0020;20,name\u0020;java.xml\u0020;flags\u0020;20,name\u0020;java.xml.crypto\u0020;flags\u0020;20 target macos-aarch64 flags 8000 classAnnotations @Ljdk/internal/javac/ParticipatesInPreview; +header requires name\u0020;java.base\u0020;flags\u0020;20,name\u0020;java.compiler\u0020;flags\u0020;20,name\u0020;java.datatransfer\u0020;flags\u0020;20,name\u0020;java.desktop\u0020;flags\u0020;20,name\u0020;java.instrument\u0020;flags\u0020;20,name\u0020;java.logging\u0020;flags\u0020;20,name\u0020;java.management\u0020;flags\u0020;20,name\u0020;java.management.rmi\u0020;flags\u0020;20,name\u0020;java.naming\u0020;flags\u0020;20,name\u0020;java.net.http\u0020;flags\u0020;20,name\u0020;java.prefs\u0020;flags\u0020;20,name\u0020;java.rmi\u0020;flags\u0020;20,name\u0020;java.scripting\u0020;flags\u0020;20,name\u0020;java.security.jgss\u0020;flags\u0020;20,name\u0020;java.security.sasl\u0020;flags\u0020;20,name\u0020;java.sql\u0020;flags\u0020;20,name\u0020;java.sql.rowset\u0020;flags\u0020;20,name\u0020;java.transaction.xa\u0020;flags\u0020;20,name\u0020;java.xml\u0020;flags\u0020;20,name\u0020;java.xml.crypto\u0020;flags\u0020;20 target macos-aarch64 flags 8000 From 5c96088eac51d89d711188c4c171347b651532d2 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 25 Dec 2024 00:40:18 +0000 Subject: [PATCH 14/99] 8346829: Problem list com/sun/jdi/ReattachStressTest.java & ProcessAttachTest.java on Linux Reviewed-by: lmesnik --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 0d737d3f727..e9d7c769523 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -727,6 +727,8 @@ javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all # jdk_jdi +com/sun/jdi/ProcessAttachTest.java 8346827 linux-all +com/sun/jdi/ReattachStressTest.java 8346827 linux-all com/sun/jdi/RepStep.java 8043571 generic-all com/sun/jdi/InvokeHangTest.java 8218463 linux-all From 1b9a3413e98df8939deaa368654b3ce6d5178cdc Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Wed, 25 Dec 2024 01:27:35 +0000 Subject: [PATCH 15/99] 8345757: [ASAN] clang17 report 'dprintf' macro redefined Reviewed-by: kbarrett, valeriep --- .../share/native/libj2pcsc/pcsc.c | 38 ++++++++----------- .../share/native/libj2pkcs11/j2secmod.c | 26 ++++++------- .../share/native/libj2pkcs11/j2secmod.h | 12 ++---- .../unix/native/libj2pkcs11/j2secmod_md.c | 8 ++-- .../windows/native/libj2pkcs11/j2secmod_md.c | 8 ++-- 5 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c index 733c28a159a..4d2cfc5f86c 100644 --- a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c +++ b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c @@ -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 @@ -40,15 +40,9 @@ // #define J2PCSC_DEBUG #ifdef J2PCSC_DEBUG -#define dprintf(s) printf(s) -#define dprintf1(s, p1) printf(s, p1) -#define dprintf2(s, p1, p2) printf(s, p1, p2) -#define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3) +#define debug_printf(format, ...) printf(format, ##__VA_ARGS__) #else -#define dprintf(s) -#define dprintf1(s, p1) -#define dprintf2(s, p1, p2) -#define dprintf3(s, p1, p2, p3) +#define debug_printf(format, ...) #endif #include "sun_security_smartcardio_PCSC.h" @@ -112,7 +106,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardEstablishContext { SCARDCONTEXT context = 0; LONG rv; - dprintf("-establishContext\n"); + debug_printf("-establishContext\n"); rv = CALL_SCardEstablishContext(dwScope, NULL, NULL, &context); if (handleRV(env, rv)) { return 0; @@ -185,12 +179,12 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade DWORD size = 0; jobjectArray result; - dprintf1("-context: %x\n", context); + debug_printf("-context: %x\n", context); rv = CALL_SCardListReaders(context, NULL, NULL, &size); if (handleRV(env, rv)) { return NULL; } - dprintf1("-size: %d\n", size); + debug_printf("-size: %d\n", size); if (size != 0) { mszReaders = malloc(size); @@ -204,7 +198,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade free(mszReaders); return NULL; } - dprintf1("-String: %s\n", mszReaders); + debug_printf("-String: %s\n", mszReaders); } else { return NULL; } @@ -230,8 +224,8 @@ JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardConnect } rv = CALL_SCardConnect(context, readerName, jShareMode, jPreferredProtocols, &card, &proto); (*env)->ReleaseStringUTFChars(env, jReaderName, readerName); - dprintf1("-cardhandle: %x\n", card); - dprintf1("-protocol: %d\n", proto); + debug_printf("-cardhandle: %x\n", card); + debug_printf("-protocol: %d\n", proto); if (handleRV(env, rv)) { return 0; } @@ -295,9 +289,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_smartcardio_PCSC_SCardStatus if (handleRV(env, rv)) { return NULL; } - dprintf1("-reader: %s\n", readerName); - dprintf1("-status: %d\n", state); - dprintf1("-protocol: %d\n", protocol); + debug_printf("-reader: %s\n", readerName); + debug_printf("-status: %d\n", state); + debug_printf("-protocol: %d\n", protocol); jArray = (*env)->NewByteArray(env, atrLen); if (jArray == NULL) { @@ -323,7 +317,7 @@ JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardDisconnect LONG rv; rv = CALL_SCardDisconnect(card, jDisposition); - dprintf1("-disconnect: 0x%X\n", rv); + debug_printf("-disconnect: 0x%X\n", rv); handleRV(env, rv); return; } @@ -392,7 +386,7 @@ JNIEXPORT jintArray JNICALL Java_sun_security_smartcardio_PCSC_SCardGetStatusCha } for (i = 0; i < readers; i++) { jint eventStateTmp; - dprintf3("-reader status %s: 0x%X, 0x%X\n", readerState[i].szReader, + debug_printf("-reader status %s: 0x%X, 0x%X\n", readerState[i].szReader, readerState[i].dwCurrentState, readerState[i].dwEventState); eventStateTmp = (jint)readerState[i].dwEventState; (*env)->SetIntArrayRegion(env, jEventState, i, 1, &eventStateTmp); @@ -417,7 +411,7 @@ JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardBeginTransaction LONG rv; rv = CALL_SCardBeginTransaction(card); - dprintf1("-beginTransaction: 0x%X\n", rv); + debug_printf("-beginTransaction: 0x%X\n", rv); handleRV(env, rv); return; } @@ -429,7 +423,7 @@ JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardEndTransaction LONG rv; rv = CALL_SCardEndTransaction(card, jDisposition); - dprintf1("-endTransaction: 0x%X\n", rv); + debug_printf("-endTransaction: 0x%X\n", rv); handleRV(env, rv); return; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c index fe87c924f28..92a83a3276c 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c @@ -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 @@ -52,7 +52,7 @@ JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssVersionCheck } res = versionCheck(requiredVersion); - dprintf2("-version >=%s: %d\n", requiredVersion, res); + debug_printf("-version >=%s: %d\n", requiredVersion, res); (*env)->ReleaseStringUTFChars(env, jVersion, requiredVersion); return (res == 0) ? JNI_FALSE : JNI_TRUE; @@ -146,11 +146,11 @@ JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssInitialize if (configDir != NULL) { (*env)->ReleaseStringUTFChars(env, jConfigDir, configDir); } - dprintf1("-res: %d\n", res); + debug_printf("-res: %d\n", res); #ifdef SECMOD_DEBUG if (res == -1) { if (getError != NULL) { - dprintf1("-NSS error: %d\n", getError()); + debug_printf("-NSS error: %d\n", getError()); } } #endif // SECMOD_DEBUG @@ -173,12 +173,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList jint i, jSlotID; if (getModuleList == NULL) { - dprintf("-getmodulelist function not found\n"); + debug_printf("-getmodulelist function not found\n"); return NULL; } list = getModuleList(); if (list == NULL) { - dprintf("-module list is null\n"); + debug_printf("-module list is null\n"); return NULL; } @@ -211,12 +211,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList while (list != NULL) { module = list->module; // assert module != null - dprintf1("-commonname: %s\n", module->commonName); - dprintf1("-dllname: %s\n", (module->dllName != NULL) ? module->dllName : "NULL"); - dprintf1("-slots: %d\n", module->slotCount); - dprintf1("-loaded: %d\n", module->loaded); - dprintf1("-internal: %d\n", module->internal); - dprintf1("-fips: %d\n", module->isFIPS); + debug_printf("-commonname: %s\n", module->commonName); + debug_printf("-dllname: %s\n", (module->dllName != NULL) ? module->dllName : "NULL"); + debug_printf("-slots: %d\n", module->slotCount); + debug_printf("-loaded: %d\n", module->loaded); + debug_printf("-internal: %d\n", module->internal); + debug_printf("-fips: %d\n", module->isFIPS); jCommonName = (*env)->NewStringUTF(env, module->commonName); if (jCommonName == NULL) { return NULL; @@ -248,7 +248,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList } list = list->next; } - dprintf("-ok\n"); + debug_printf("-ok\n"); return jList; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h index 4cdb7ba37ee..71d2008d0cd 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h @@ -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 @@ -37,15 +37,9 @@ void *p11FindFunction(JNIEnv *env, jlong jHandle, const char *functionName); #ifdef SECMOD_DEBUG -#define dprintf(s) printf(s) -#define dprintf1(s, p1) printf(s, p1) -#define dprintf2(s, p1, p2) printf(s, p1, p2) -#define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3) +#define debug_printf(format, ...) printf(format, ##__VA_ARGS__) #else -#define dprintf(s) -#define dprintf1(s, p1) -#define dprintf2(s, p1, p2) -#define dprintf3(s, p1, p2, p3) +#define debug_printf(format, ...) #endif // NSS types diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c index 46cef13fd2d..b1d2d5ee4e8 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c @@ -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 @@ -61,7 +61,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle #else hModule = dlopen(libName, RTLD_NOLOAD); #endif - dprintf2("-handle for %s: %u\n", libName, hModule); + debug_printf("-handle for %s: %u\n", libName, hModule); (*env)->ReleaseStringUTFChars(env, jLibName, libName); return ptr_to_jlong(hModule); } @@ -75,10 +75,10 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary return 0L; } - dprintf1("-lib %s\n", libName); + debug_printf("-lib %s\n", libName); hModule = dlopen(libName, RTLD_LAZY); (*env)->ReleaseStringUTFChars(env, jLibName, libName); - dprintf2("-handle: %u (0X%X)\n", hModule, hModule); + debug_printf("-handle: %u (0X%X)\n", hModule, hModule); if (hModule == NULL) { p11ThrowIOException(env, dlerror()); diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c index a5cd5e63d02..5009b8a280f 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c @@ -51,7 +51,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle { const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL); HMODULE hModule = GetModuleHandle(libName); - dprintf2("-handle for %s: %d\n", libName, hModule); + debug_printf("-handle for %s: %d\n", libName, hModule); (*env)->ReleaseStringUTFChars(env, jLibName, libName); return (jlong)hModule; } @@ -63,7 +63,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary LPVOID lpMsgBuf; const char *libName = (*env)->GetStringUTFChars(env, jName, NULL); - dprintf1("-lib %s\n", libName); + debug_printf("-lib %s\n", libName); hModule = LoadLibrary(libName); (*env)->ReleaseStringUTFChars(env, jName, libName); @@ -80,11 +80,11 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary 0, NULL ); - dprintf1("-error: %s\n", lpMsgBuf); + debug_printf("-error: %s\n", lpMsgBuf); p11ThrowIOException(env, (char*)lpMsgBuf); LocalFree(lpMsgBuf); return 0; } - dprintf2("-handle: %d (0X%X)\n", hModule, hModule); + debug_printf("-handle: %d (0X%X)\n", hModule, hModule); return (jlong)hModule; } From db1e2d78a28583f9020155a1aa2d45e738ea2783 Mon Sep 17 00:00:00 2001 From: Matthias Baesken <mbaesken@openjdk.org> Date: Sat, 28 Dec 2024 15:45:26 +0000 Subject: [PATCH 16/99] 8346712: Remove com/sun/net/httpserver/TcpNoDelayNotRequired.java test Reviewed-by: djelinski, lucy, jpai --- .../net/httpserver/TcpNoDelayNotRequired.java | 145 ------------------ 1 file changed, 145 deletions(-) delete mode 100644 test/jdk/com/sun/net/httpserver/TcpNoDelayNotRequired.java diff --git a/test/jdk/com/sun/net/httpserver/TcpNoDelayNotRequired.java b/test/jdk/com/sun/net/httpserver/TcpNoDelayNotRequired.java deleted file mode 100644 index a66f25dd487..00000000000 --- a/test/jdk/com/sun/net/httpserver/TcpNoDelayNotRequired.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 6968351 - * @summary tcp no delay not required for small payloads - * @requires vm.compMode != "Xcomp" - * @library /test/lib - * @run main/othervm/timeout=5 -Dsun.net.httpserver.nodelay=false TcpNoDelayNotRequired - */ - -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpContext; -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.test.lib.net.SimpleSSLContext; -import jdk.test.lib.net.URIBuilder; - -import javax.net.ssl.SSLContext; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.logging.SimpleFormatter; -import java.util.logging.StreamHandler; - -public class TcpNoDelayNotRequired { - - public static final Logger LOGGER = Logger.getLogger("sun.net.www.protocol.http"); - - public static void main (String[] args) throws Exception { - - java.util.logging.Handler outHandler = new StreamHandler(System.out, - new SimpleFormatter()); - outHandler.setLevel(Level.FINEST); - LOGGER.setLevel(Level.FINEST); - LOGGER.addHandler(outHandler); - - InetAddress loopback = InetAddress.getLoopbackAddress(); - InetSocketAddress addr = new InetSocketAddress (loopback, 0); - - SSLContext sslContext = new SimpleSSLContext().get(); - - HttpServer httpServer = HttpServer.create (addr, 0); - testHttpServer("http",httpServer,sslContext); - - HttpsServer httpsServer = HttpsServer.create (addr, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - - testHttpServer("https",httpsServer,sslContext); - } - - private static void testHttpServer(String scheme,HttpServer server,SSLContext sslContext) throws Exception { - HttpContext ctx = server.createContext ("/test", new Handler()); - HttpContext ctx2 = server.createContext ("/chunked", new ChunkedHandler()); - ExecutorService executor = Executors.newCachedThreadPool(); - server.setExecutor (executor); - server.start (); - try { - try (HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build()) { - long start = System.currentTimeMillis(); - for (int i = 0; i < 1000; i++) { - var uri = URIBuilder.newBuilder().scheme(scheme).loopback().port(server.getAddress().getPort()).path("/test").build(); - var response = client.send(HttpRequest.newBuilder(uri).build(), HttpResponse.BodyHandlers.ofString()); - if (!response.body().equals("hello")) - throw new IllegalStateException("incorrect body " + response.body()); - } - for (int i = 0; i < 1000; i++) { - var uri = URIBuilder.newBuilder().scheme(scheme).loopback().port(server.getAddress().getPort()).path("/chunked").build(); - var response = client.send(HttpRequest.newBuilder(uri).build(), HttpResponse.BodyHandlers.ofString()); - if (!response.body().equals("hello")) - throw new IllegalStateException("incorrect body " + response.body()); - } - long time = System.currentTimeMillis() - start; - System.out.println("time " + time); - } - } finally { - server.stop(0); - } - executor.shutdown(); - } - - static class Handler implements HttpHandler { - public void handle (HttpExchange t) - throws IOException - { - Headers rmap = t.getResponseHeaders(); - try (var is = t.getRequestBody()) { - is.readAllBytes(); - } - rmap.add("content-type","text/plain"); - t.sendResponseHeaders(200,5); - try (var os = t.getResponseBody()) { - os.write("hello".getBytes(StandardCharsets.ISO_8859_1)); - } - } - } - static class ChunkedHandler implements HttpHandler { - public void handle (HttpExchange t) - throws IOException - { - Headers rmap = t.getResponseHeaders(); - try (var is = t.getRequestBody()) { - is.readAllBytes(); - } - rmap.add("content-type","text/plain"); - t.sendResponseHeaders(200,0); - try (var os = t.getResponseBody()) { - os.write("hello".getBytes(StandardCharsets.ISO_8859_1)); - } - } - } -} From e897d0f8faddecdd640825deaa7e020b00bb8dd2 Mon Sep 17 00:00:00 2001 From: GennadiyKrivoshein <164895822+GennadiyKrivoshein@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:48:57 +0000 Subject: [PATCH 17/99] 8343224: print/Dialog/PaperSizeError.java fails with MediaSizeName is not A4: A4 Reviewed-by: azvegint, alexsch, psadhukhan, achung --- .../classes/sun/print/CustomMediaSizeName.java | 17 +++++++++-------- .../java/awt/print/Dialog/PaperSizeError.java | 18 ++++++++++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java b/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java index b8d3ec723b8..04772f29858 100644 --- a/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java +++ b/src/java.desktop/share/classes/sun/print/CustomMediaSizeName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, 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,16 +203,17 @@ public static CustomMediaSizeName create(String name, String choice, 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) { + if (value.getStandardMedia() == null) { + // 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); + new MediaSize(length, width, Size2DSyntax.INCH, value); + } } } } diff --git a/test/jdk/java/awt/print/Dialog/PaperSizeError.java b/test/jdk/java/awt/print/Dialog/PaperSizeError.java index fea7bb85af8..18f33704a06 100644 --- a/test/jdk/java/awt/print/Dialog/PaperSizeError.java +++ b/test/jdk/java/awt/print/Dialog/PaperSizeError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 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,16 +23,22 @@ /** * @test - * @bug 6360339 + * @bug 6360339 8343224 * @key printer * @summary Test for fp error in paper size calculations. * @run main/manual PaperSizeError */ -import java.awt.print.*; -import javax.print.*; -import javax.print.attribute.*; -import javax.print.attribute.standard.*; +import javax.print.PrintService; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.Size2DSyntax; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.OrientationRequested; +import java.awt.print.PageFormat; +import java.awt.print.Paper; +import java.awt.print.PrinterJob; public class PaperSizeError { From 48de421842b57891c64970b39d8d456cfb0f52de Mon Sep 17 00:00:00 2001 From: Qizheng Xing <qxing@openjdk.org> Date: Sun, 29 Dec 2024 08:32:38 +0000 Subject: [PATCH 18/99] 8346831: Remove the extra closing parenthesis in CTW Makefile Reviewed-by: liach, kbarrett, lmesnik, jwaters --- test/hotspot/jtreg/testlibrary/ctw/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/testlibrary/ctw/Makefile b/test/hotspot/jtreg/testlibrary/ctw/Makefile index 4cf20b12e52..5c64c67d828 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/Makefile +++ b/test/hotspot/jtreg/testlibrary/ctw/Makefile @@ -47,7 +47,7 @@ LIB_FILES = $(shell find $(TESTLIBRARY_DIR)/jdk/test/lib/ \ $(TESTLIBRARY_DIR)/jdk/test/lib/process \ $(TESTLIBRARY_DIR)/jdk/test/lib/util \ $(TESTLIBRARY_DIR)/jtreg \ - -maxdepth 1 -name '*.java')) + -maxdepth 1 -name '*.java') WB_SRC_FILES = $(shell find $(TESTLIBRARY_DIR)/jdk/test/lib/compiler $(TESTLIBRARY_DIR)/jdk/test/whitebox -name '*.java') WB_CLASS_FILES := $(subst $(TESTLIBRARY_DIR)/,,$(WB_SRC_FILES)) WB_CLASS_FILES := $(patsubst %.java,%.class,$(WB_CLASS_FILES)) From 0b86247333131bd5c6a7d4bfb10d78d7ee357d1f Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Sun, 29 Dec 2024 08:37:25 +0000 Subject: [PATCH 19/99] 8302293: jar --create fails with IllegalArgumentException if archive name is shorter than 3 characters Reviewed-by: lancea --- .../share/classes/sun/tools/jar/Main.java | 13 ++-- test/jdk/tools/jar/JarCreateFileNameTest.java | 70 +++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 test/jdk/tools/jar/JarCreateFileNameTest.java diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index 02afd5fdbcb..ae6893c021b 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -315,11 +315,13 @@ public synchronized boolean run(String[] args) { // error("Warning: -v option ignored"); vflag = false; } - final String tmpbase = (fname == null) + String tmpFilePrefix = (fname == null) ? "tmpjar" : fname.substring(fname.indexOf(File.separatorChar) + 1); - - tmpFile = createTemporaryFile(tmpbase, ".jar"); + if (tmpFilePrefix.length() < 3) { + tmpFilePrefix = "tmpjar" + tmpFilePrefix; + } + tmpFile = createTemporaryFile(tmpFilePrefix, ".jar"); try (OutputStream out = new FileOutputStream(tmpFile)) { create(new BufferedOutputStream(out, 4096), manifest); } @@ -1775,11 +1777,12 @@ private File createTemporaryFile(String tmpbase, String suffix) { // Unable to create file due to permission violation or security exception } if (tmpfile == null) { - // Were unable to create temporary file, fall back to temporary file in the same folder + // We were unable to create temporary file, fall back to temporary file in the + // same folder as the JAR file if (fname != null) { try { File tmpfolder = new File(fname).getAbsoluteFile().getParentFile(); - tmpfile = File.createTempFile(fname, ".tmp" + suffix, tmpfolder); + tmpfile = File.createTempFile(tmpbase, ".tmp" + suffix, tmpfolder); } catch (IOException ioe) { // Last option failed - fall gracefully fatalError(ioe); diff --git a/test/jdk/tools/jar/JarCreateFileNameTest.java b/test/jdk/tools/jar/JarCreateFileNameTest.java new file mode 100644 index 00000000000..fb2b6a2e732 --- /dev/null +++ b/test/jdk/tools/jar/JarCreateFileNameTest.java @@ -0,0 +1,70 @@ +/* + * 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.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarFile; +import java.util.spi.ToolProvider; +import java.util.zip.ZipEntry; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/* + * @test + * @bug 8302293 + * @summary verify that a JAR file creation through "jar --create" operation + * works fine if the JAR file name is less than 3 characters in length + * @run junit JarCreateFileNameTest + */ +public class JarCreateFileNameTest { + + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") + .orElseThrow(() -> + new RuntimeException("jar tool not found") + ); + + /* + * Launches "jar --create --file" with file names of varying lengths and verifies + * that the JAR file was successfully created. + */ + @ParameterizedTest + @ValueSource(strings = {"abcd", "abc", "ab", "a", "d.jar", "ef.jar"}) + void testCreate(final String targetJarFileName) throws Exception { + final Path cwd = Path.of("."); + final Path tmpFile = Files.createTempFile(cwd, "8302293", ".txt"); + final String fileName = tmpFile.getFileName().toString(); + final int exitCode = JAR_TOOL.run(System.out, System.err, + "--create", "--file", targetJarFileName, fileName); + assertEquals(0, exitCode, "jar command failed"); + // verify the JAR file is created and contains the expected entry + try (final JarFile jarFile = new JarFile(new File(targetJarFileName))) { + final ZipEntry entry = jarFile.getEntry(fileName); + assertNotNull(entry, "missing " + fileName + " entry in JAR file " + targetJarFileName); + } + } +} + From 4fe2c5dedf0757b6be265ce520dcfabdd084bb68 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Mon, 30 Dec 2024 00:53:15 +0000 Subject: [PATCH 20/99] 8346871: Improve robustness of java/util/zip/EntryCount64k.java test Reviewed-by: lancea --- test/jdk/java/util/zip/EntryCount64k.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index d8c46d22364..8830a87ea64 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2013 Google Inc. All rights reserved. + * 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 @@ -47,9 +48,12 @@ import jdk.test.lib.process.ProcessTools; public class EntryCount64k { + + private static final String MAIN_CLASS_MSG = "foo bar hello world Main"; + public static class Main { public static void main(String[] args) { - System.out.print("Main"); + System.out.println(MAIN_CLASS_MSG); } } @@ -162,7 +166,10 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { // Check java -jar OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); - a.stdoutShouldMatch("\\AMain\\Z"); + // expect the message from the application on stdout + a.stdoutContains(MAIN_CLASS_MSG); + // nothing is expected on stderr (apart from any probable deprecation + // warnings from the launcher/JVM) a.stderrShouldMatchIgnoreDeprecatedWarnings("\\A\\Z"); } } From 520e5ac858e927a4f4b72c70df8cf8437403e5fe Mon Sep 17 00:00:00 2001 From: Volker Simonis <simonis@openjdk.org> Date: Wed, 1 Jan 2025 17:20:27 +0000 Subject: [PATCH 21/99] 8346101: [JVMCI] Export jdk.internal.misc to jdk.graal.compiler Reviewed-by: dnsimon, phh --- src/java.base/share/classes/module-info.java | 3 ++- src/jdk.graal.compiler/share/classes/module-info.java | 4 ++-- test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 614842e064c..2904f665732 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -226,7 +226,8 @@ jdk.jshell, jdk.nio.mapmode, jdk.unsupported, - jdk.internal.vm.ci; + jdk.internal.vm.ci, + jdk.graal.compiler; exports jdk.internal.module to java.instrument, java.management.rmi, diff --git a/src/jdk.graal.compiler/share/classes/module-info.java b/src/jdk.graal.compiler/share/classes/module-info.java index bc8987ee919..f2bc1ae9842 100644 --- a/src/jdk.graal.compiler/share/classes/module-info.java +++ b/src/jdk.graal.compiler/share/classes/module-info.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 @@ -30,7 +30,7 @@ * external implementation of a JVMCI compiler. It must be upgradeable so * that it can be replaced when jlinking a new JDK image without failing * the hash check for the qualified exports in jdk.internal.vm.ci's - * module descriptor. + * and java.base's module descriptors. * * @moduleGraph * @since 22 diff --git a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java index 4718e10e862..551e3792fc2 100644 --- a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java +++ b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.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 @@ -74,7 +74,8 @@ static void check(ModuleDescriptor md) { "jdk.internal.vm.ci/jdk.vm.ci.hotspot", "jdk.internal.vm.ci/jdk.vm.ci.meta", "jdk.internal.vm.ci/jdk.vm.ci.code", - "java.base/jdk.internal.javac"); + "java.base/jdk.internal.javac", + "java.base/jdk.internal.misc"); static void checkExports(ModuleDescriptor md) { // build a map of upgradeable module to Exports that are qualified to it From ef689331bf32fa4a3ace4f738c3c21ffbd7f2355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= <volkan.yazici@oracle.com> Date: Thu, 2 Jan 2025 09:19:58 +0000 Subject: [PATCH 22/99] 8336412: sun.net.www.MimeTable has a few unused methods Reviewed-by: jpai --- .../share/classes/java/net/URLConnection.java | 2 +- .../share/classes/sun/net/www/MimeTable.java | 204 ++---------------- 2 files changed, 24 insertions(+), 182 deletions(-) diff --git a/src/java.base/share/classes/java/net/URLConnection.java b/src/java.base/share/classes/java/net/URLConnection.java index 69f71942561..585ab4fa15a 100644 --- a/src/java.base/share/classes/java/net/URLConnection.java +++ b/src/java.base/share/classes/java/net/URLConnection.java @@ -306,7 +306,7 @@ public static FileNameMap getFileNameMap() { if (map == null) { fileNameMap = map = new FileNameMap() { private final FileNameMap internalMap = - sun.net.www.MimeTable.loadTable(); + sun.net.www.MimeTable.getDefaultTable(); public String getContentTypeFor(String fileName) { return internalMap.getContentTypeFor(fileName); diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java b/src/java.base/share/classes/sun/net/www/MimeTable.java index eea633e94fa..5b760241671 100644 --- a/src/java.base/share/classes/sun/net/www/MimeTable.java +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java @@ -25,12 +25,9 @@ package sun.net.www; -import jdk.internal.util.StaticProperty; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.net.FileNameMap; @@ -40,30 +37,22 @@ import java.util.Properties; import java.util.StringTokenizer; -public class MimeTable implements FileNameMap { +public final class MimeTable implements FileNameMap { + /** Hash mark introducing a URI fragment */ private static final int HASH_MARK = '#'; - /** Keyed by content type, returns MimeEntries */ - private final Hashtable<String, MimeEntry> entries = new Hashtable<>(); - /** Keyed by file extension (with the .), returns MimeEntries */ private final Hashtable<String, MimeEntry> extensionMap = new Hashtable<>(); - // Will be reset if in the platform-specific data file - private static String tempFileTemplate = - System.getProperty("content.types.temp.file.template", "/tmp/%s"); - - private static final String filePreamble = "sun.net.www MIME content-types table"; - - MimeTable() { + private MimeTable() { load(); } - private static class DefaultInstanceHolder { - static final MimeTable defaultInstance = getDefaultInstance(); + private static final class DefaultInstanceHolder { + private static final MimeTable defaultInstance = getDefaultInstance(); - static MimeTable getDefaultInstance() { + private static MimeTable getDefaultInstance() { final MimeTable instance = new MimeTable(); URLConnection.setFileNameMap(instance); return instance; @@ -78,15 +67,6 @@ public static MimeTable getDefaultTable() { return DefaultInstanceHolder.defaultInstance; } - public static FileNameMap loadTable() { - MimeTable mt = getDefaultTable(); - return mt; - } - - public synchronized int getSize() { - return entries.size(); - } - public synchronized String getContentTypeFor(String fileName) { MimeEntry entry = findByFileName(fileName); if (entry != null) { @@ -96,55 +76,21 @@ public synchronized String getContentTypeFor(String fileName) { } } - public synchronized void add(MimeEntry m) { - entries.put(m.getType(), m); - - String exts[] = m.getExtensions(); + private void add(MimeEntry m) { + String[] exts = m.getExtensions(); if (exts == null) { return; } - for (int i = 0; i < exts.length; i++) { - extensionMap.put(exts[i], m); + for (String ext : exts) { + extensionMap.put(ext, m); } } - public synchronized MimeEntry remove(String type) { - MimeEntry entry = entries.get(type); - return remove(entry); - } - - public synchronized MimeEntry remove(MimeEntry entry) { - String[] extensionKeys = entry.getExtensions(); - if (extensionKeys != null) { - for (int i = 0; i < extensionKeys.length; i++) { - extensionMap.remove(extensionKeys[i]); - } - } - - return entries.remove(entry.getType()); - } - - public synchronized MimeEntry find(String type) { - MimeEntry entry = entries.get(type); - if (entry == null) { - // try a wildcard lookup - Enumeration<MimeEntry> e = entries.elements(); - while (e.hasMoreElements()) { - MimeEntry wild = e.nextElement(); - if (wild.matches(type)) { - return wild; - } - } - } - - return entry; - } - /** * Extracts the file extension and uses it to look up the entry. */ - private MimeEntry findViaFileExtension(String fname) { + private MimeEntry findByFileExtension(String fname) { int i = fname.lastIndexOf('.'); // REMIND: OS specific delimiters appear here i = Math.max(i, fname.lastIndexOf('/')); @@ -155,7 +101,8 @@ private MimeEntry findViaFileExtension(String fname) { ext = fname.substring(i).toLowerCase(Locale.ROOT); } - return findByExt(ext); + return extensionMap.get(ext); + } /** @@ -166,74 +113,27 @@ private MimeEntry findViaFileExtension(String fname) { * * @return the MIME entry associated with the file name or {@code null} */ - public MimeEntry findByFileName(String fname) { - MimeEntry entry = null; + private MimeEntry findByFileName(String fname) { // If an optional fragment introduced by a hash mark is // present, then strip it and use the prefix int hashIndex = fname.lastIndexOf(HASH_MARK); if (hashIndex > 0) { - entry = findViaFileExtension(fname.substring(0, hashIndex)); + MimeEntry entry = findByFileExtension(fname.substring(0, hashIndex)); if (entry != null) { return entry; } } - assert entry == null; - // If either no optional fragment was present, or the entry was not // found with the fragment stripped, then try again with the full name - if (entry == null) { - entry = findViaFileExtension(fname); - } - - return entry; - } - - /** - * Locate a MimeEntry by the file extension that has been associated - * with it. - */ - public synchronized MimeEntry findByExt(String fileExtension) { - return extensionMap.get(fileExtension); - } - - public synchronized MimeEntry findByDescription(String description) { - Enumeration<MimeEntry> e = elements(); - while (e.hasMoreElements()) { - MimeEntry entry = e.nextElement(); - if (description.equals(entry.getDescription())) { - return entry; - } - } - - // We failed, now try treating description as type - return find(description); - } + return findByFileExtension(fname); - String getTempFileTemplate() { - return tempFileTemplate; } - public synchronized Enumeration<MimeEntry> elements() { - return entries.elements(); - } - - // For backward compatibility -- mailcap format files - // This is not currently used, but may in the future when we add ability - // to read BOTH the properties format and the mailcap format. - protected static String[] mailcapLocations = - new String[]{ - System.getProperty("user.mailcap"), - StaticProperty.userHome() + "/.mailcap", - "/etc/mailcap", - "/usr/etc/mailcap", - "/usr/local/etc/mailcap" - }; - - public synchronized void load() { + private synchronized void load() { Properties entries = new Properties(); - File file = null; + File file; InputStream in; // First try to load the user-specific table, if it exists @@ -260,12 +160,11 @@ public synchronized void load() { parse(entries); } - void parse(Properties entries) { + private void parse(Properties entries) { // first, strip out the platform-specific temp file template String tempFileTemplate = (String)entries.get("temp.file.template"); if (tempFileTemplate != null) { entries.remove("temp.file.template"); - MimeTable.tempFileTemplate = tempFileTemplate; } // now, parse the mime-type spec's @@ -304,7 +203,7 @@ void parse(Properties entries) { // associated with. // - void parse(String type, String attrs) { + private void parse(String type, String attrs) { MimeEntry newEntry = new MimeEntry(type); // REMIND handle embedded ';' and '|' and literal '"' @@ -317,7 +216,7 @@ void parse(String type, String attrs) { add(newEntry); } - void parse(String pair, MimeEntry entry) { + private static void parse(String pair, MimeEntry entry) { // REMIND add exception handling... String name = null; String value = null; @@ -337,7 +236,7 @@ void parse(String pair, MimeEntry entry) { fill(entry, name, value); } - void fill(MimeEntry entry, String name, String value) { + private static void fill(MimeEntry entry, String name, String value) { if ("description".equalsIgnoreCase(name)) { entry.setDescription(value); } @@ -357,7 +256,7 @@ else if ("file_extensions".equalsIgnoreCase(name)) { // else illegal name exception } - int getActionCode(String action) { + private static int getActionCode(String action) { for (int i = 0; i < MimeEntry.actionKeywords.length; i++) { if (action.equalsIgnoreCase(MimeEntry.actionKeywords[i])) { return i; @@ -367,61 +266,4 @@ int getActionCode(String action) { return MimeEntry.UNKNOWN; } - public Properties getAsProperties() { - Properties properties = new Properties(); - Enumeration<MimeEntry> e = elements(); - while (e.hasMoreElements()) { - MimeEntry entry = e.nextElement(); - properties.put(entry.getType(), entry.toProperty()); - } - - return properties; - } - - protected boolean saveAsProperties(File file) { - try (FileOutputStream os = new FileOutputStream(file)) { - Properties properties = getAsProperties(); - properties.put("temp.file.template", tempFileTemplate); - String tag; - String user = StaticProperty.userName(); - if (user != null) { - tag = "; customized for " + user; - properties.store(os, filePreamble + tag); - } - else { - properties.store(os, filePreamble); - } - } - catch (IOException e) { - e.printStackTrace(); - return false; - } - - return true; - } - /* - * Debugging utilities - * - public void list(PrintStream out) { - Enumeration keys = entries.keys(); - while (keys.hasMoreElements()) { - String key = (String)keys.nextElement(); - MimeEntry entry = (MimeEntry)entries.get(key); - out.println(key + ": " + entry); - } - } - - public static void main(String[] args) { - MimeTable testTable = MimeTable.getDefaultTable(); - - Enumeration e = testTable.elements(); - while (e.hasMoreElements()) { - MimeEntry entry = (MimeEntry)e.nextElement(); - System.out.println(entry); - } - - testTable.save(File.separator + "tmp" + - File.separator + "mime_table.save"); - } - */ } From b370ea69ddfe38a4c1ea4139e96ac1a8c7f5bc6c Mon Sep 17 00:00:00 2001 From: Peter Shipton <Peter_Shipton@ca.ibm.com> Date: Thu, 2 Jan 2025 08:29:30 -0500 Subject: [PATCH 23/99] Apply the patch for CVE-2024-56732 From https://github.com/harfbuzz/harfbuzz/commit/1767f99e2e2196c3fcae27db6d8b60098d3f6d26 Signed-off-by: Peter Shipton <Peter_Shipton@ca.ibm.com> --- src/java.desktop/share/native/libharfbuzz/hb-utf.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh index 9175df265b9..7fd3bf8828b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh @@ -458,19 +458,21 @@ struct hb_ascii_t template <typename utf_t> static inline const typename utf_t::codepoint_t * hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start, + const typename utf_t::codepoint_t *text, + unsigned text_len, signed offset) { hb_codepoint_t unicode; while (offset-- > 0) start = utf_t::next (start, - start + utf_t::max_len, + text + text_len, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); while (offset++ < 0) start = utf_t::prev (start, - start - utf_t::max_len, + text, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); From b29f0e4b91d1781abb97d7dc9c8e3dfc1d5a283b Mon Sep 17 00:00:00 2001 From: J9 Build <j9build@ca.ibm.com> Date: Fri, 3 Jan 2025 04:19:48 +0000 Subject: [PATCH 24/99] Update OPENJDK_TAG to merged level jdk-25+4 Signed-off-by: J9 Build <j9build@ca.ibm.com> --- closed/openjdk-tag.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/closed/openjdk-tag.gmk b/closed/openjdk-tag.gmk index ba6b2ecaa38..bdd32e8ba11 100644 --- a/closed/openjdk-tag.gmk +++ b/closed/openjdk-tag.gmk @@ -1 +1 @@ -OPENJDK_TAG := jdk-25+3 +OPENJDK_TAG := jdk-25+4 From c02552bcd9cc2965b2fbd74e60bf20dd2e8dc922 Mon Sep 17 00:00:00 2001 From: Gui Cao <gcao@openjdk.org> Date: Mon, 6 Jan 2025 03:35:46 +0000 Subject: [PATCH 25/99] 8346924: TestVectorizationNegativeScale.java fails without the rvv extension on RISCV fastdebug VM Reviewed-by: fyang, kvn --- .../compiler/vectorization/TestVectorizationNegativeScale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java b/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java index 58464880070..4fc9f7d1ed1 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestVectorizationNegativeScale.java @@ -25,7 +25,7 @@ * @test * @bug 8332827 * @summary [REDO] C2: crash in compiled code because of dependency on removed range check CastIIs - * + * @requires os.arch != "riscv64" | vm.cpu.features ~= ".*rvv.*" * @library /test/lib / * @run driver TestVectorizationNegativeScale * From 837842607c073fff4afabf1e7f21c0ab1eaa68c2 Mon Sep 17 00:00:00 2001 From: Gui Cao <gcao@openjdk.org> Date: Mon, 6 Jan 2025 03:36:00 +0000 Subject: [PATCH 26/99] 8346922: TestVectorReinterpret.java fails without the rvv extension on RISCV fastdebug VM Reviewed-by: fyang, kvn --- .../jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java index 5891033fbd9..7f00fece7e6 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java @@ -39,6 +39,7 @@ * @modules jdk.incubator.vector * @modules java.base/jdk.internal.misc * @summary Test that vector reinterpret intrinsics work as intended. + * @requires os.arch != "riscv64" | vm.cpu.features ~= ".*rvv.*" * @library /test/lib / * @run main compiler.vectorapi.reshape.TestVectorReinterpret */ From fd1ebeb8b369aef896d650728b5cfa7a12724752 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Mon, 6 Jan 2025 06:01:24 +0000 Subject: [PATCH 27/99] 8346260: Test "javax/swing/JOptionPane/bug4174551.java" failed because the font size of message "Hi 24" is not set to 24 in Nimbus LookAndFeel Reviewed-by: aivanov, dnguyen --- .../javax/swing/plaf/synth/SynthDefaultLookup.java | 10 +++++++++- test/jdk/javax/swing/JOptionPane/bug4174551.java | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java index ba1927bb948..ad6b226dd70 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 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 @@ -25,7 +25,9 @@ package javax.swing.plaf.synth; import sun.swing.DefaultLookup; + import javax.swing.JComponent; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; /** @@ -35,6 +37,12 @@ */ class SynthDefaultLookup extends DefaultLookup { public Object getDefault(JComponent c, ComponentUI ui, String key) { + if (ui instanceof SynthOptionPaneUI) { + Object value = super.getDefault(c, ui, key); + if (value != null) { + return value; + } + } if (!(ui instanceof SynthUI)) { Object value = super.getDefault(c, ui, key); return value; diff --git a/test/jdk/javax/swing/JOptionPane/bug4174551.java b/test/jdk/javax/swing/JOptionPane/bug4174551.java index f65f95192b7..dbe6cdffe1a 100644 --- a/test/jdk/javax/swing/JOptionPane/bug4174551.java +++ b/test/jdk/javax/swing/JOptionPane/bug4174551.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4174551 + * @bug 4174551 8346260 * @summary JOptionPane should allow custom buttons * @library /java/awt/regtesthelpers * @build PassFailJFrame From 87751147206c195ba4a87cbc4984dc5117b79178 Mon Sep 17 00:00:00 2001 From: Qizheng Xing <qxing@openjdk.org> Date: Mon, 6 Jan 2025 06:23:53 +0000 Subject: [PATCH 28/99] 8346773: Fix unmatched brackets in some misc files Reviewed-by: kbarrett, alanb, rriggs, dholmes, erikj, liach --- doc/hotspot-unit-tests.html | 2 +- doc/hotspot-unit-tests.md | 2 +- src/java.base/share/man/java.md | 2 +- src/java.base/share/man/keytool.md | 6 +++--- src/jdk.compiler/share/man/javac.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/hotspot-unit-tests.html b/doc/hotspot-unit-tests.html index 556cfecc42d..fcd4a93f8e4 100644 --- a/doc/hotspot-unit-tests.html +++ b/doc/hotspot-unit-tests.html @@ -245,7 +245,7 @@ <h3 id="error-messages">Error messages</h3> <p>All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -<code>ASSERT_TRUE((val1 == val2 &amp;&amp; isFail(foo(8)) || i == 18)</code> +<code>ASSERT_TRUE((val1 == val2 &amp;&amp; isFail(foo(8))) || i == 18)</code> prints only one value. If you use some complex predicates, please consider <code>EXPECT_PRED*</code> or <code>EXPECT_FORMAT_PRED</code> assertions family, they check that a predicate returns true/success and diff --git a/doc/hotspot-unit-tests.md b/doc/hotspot-unit-tests.md index 62ace4ef6ee..e1222baa2e3 100644 --- a/doc/hotspot-unit-tests.md +++ b/doc/hotspot-unit-tests.md @@ -172,7 +172,7 @@ Provide informative, but not too verbose error messages. All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -`ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)` prints only +`ASSERT_TRUE((val1 == val2 && isFail(foo(8))) || i == 18)` prints only one value. If you use some complex predicates, please consider `EXPECT_PRED*` or `EXPECT_FORMAT_PRED` assertions family, they check that a predicate returns true/success and print out all parameters values. diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 01f7b3f7e77..a048d2a6dcf 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -1311,7 +1311,7 @@ These `java` options control the runtime behavior of the Java HotSpot VM. `-XX:+PreserveFramePointer` : Selects between using the RBP register as a general purpose register (`-XX:-PreserveFramePointer`) and using the RBP register to hold the frame - pointer of the currently executing method (`-XX:+PreserveFramePointer` . If + pointer of the currently executing method (`-XX:+PreserveFramePointer`). If the frame pointer is available, then external profiling tools (for example, Linux perf) can construct more accurate stack traces. diff --git a/src/java.base/share/man/keytool.md b/src/java.base/share/man/keytool.md index 22b2877a3e7..8484ec6b5b3 100644 --- a/src/java.base/share/man/keytool.md +++ b/src/java.base/share/man/keytool.md @@ -662,7 +662,7 @@ perform. - {`-noprompt`}: Do not prompt - - {`-addprovider` *name* \[`-providerarg` *arg*\]: Add security provider + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider by name (such as SunPKCS11) with an optional configure argument. - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security @@ -1617,7 +1617,7 @@ name information, the keystore password, and the private key password. The rest of the examples assume that you responded to the prompts with values equal to those specified in the first `-genkeypair` command. For example, a distinguished name of -`cn=`*myname*`, ou=`*mygroup*`, o=`*mycompany*`, c=`*mycountry*). +`cn=`*myname*`, ou=`*mygroup*`, o=`*mycompany*`, c=`*mycountry*. ## Requesting a Signed Certificate from a CA @@ -1914,7 +1914,7 @@ Keystore implementation The `keytool` command works on any file-based keystore implementation. It treats the keystore location that is passed to it at the command line as a file name and converts it to a `FileInputStream`, from which it loads the - keystore information.)The `jarsigner` commands can read a keystore from any + keystore information. The `jarsigner` commands can read a keystore from any location that can be specified with a URL. For `keytool` and `jarsigner`, you can specify a keystore type at the diff --git a/src/jdk.compiler/share/man/javac.md b/src/jdk.compiler/share/man/javac.md index 7761cde2b58..3edbeda6eca 100644 --- a/src/jdk.compiler/share/man/javac.md +++ b/src/jdk.compiler/share/man/javac.md @@ -1667,7 +1667,7 @@ internal and subject to change at any time. public static int m() { try { throw new NullPointerException(); - } catch (NullPointerException(); { + } catch (NullPointerException e) { System.err.println("Caught NullPointerException."); return 1; } finally { From 64a66642d7881cd702d316cda1391a16314b6fee Mon Sep 17 00:00:00 2001 From: Adam Sotona <asotona@openjdk.org> Date: Mon, 6 Jan 2025 14:08:32 +0000 Subject: [PATCH 29/99] 8346981: Remove obsolete java.base exports of jdk.internal.objectweb.asm packages Reviewed-by: liach, alanb --- src/java.base/share/classes/module-info.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 2904f665732..66e6267367c 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,14 +197,6 @@ jdk.jlink; exports jdk.internal.logger to java.logging; - exports jdk.internal.org.objectweb.asm to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.tree to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.util to - jdk.jfr; - exports jdk.internal.org.objectweb.asm.commons to - jdk.jfr; exports jdk.internal.org.xml.sax to jdk.jfr; exports jdk.internal.org.xml.sax.helpers to From 63540fb8248768b13b1ce19f6ffd112c9e19b72b Mon Sep 17 00:00:00 2001 From: Adam Sotona <asotona@openjdk.org> Date: Mon, 6 Jan 2025 14:08:45 +0000 Subject: [PATCH 30/99] 8346983: Remove ASM-based transforms from Class-File API tests Reviewed-by: liach --- test/jdk/jdk/classfile/TEST.properties | 4 +- .../jdk/jdk/classfile/helpers/Transforms.java | 351 +----------------- 2 files changed, 3 insertions(+), 352 deletions(-) diff --git a/test/jdk/jdk/classfile/TEST.properties b/test/jdk/jdk/classfile/TEST.properties index 62414b36eae..2d8d20cf1f4 100644 --- a/test/jdk/jdk/classfile/TEST.properties +++ b/test/jdk/jdk/classfile/TEST.properties @@ -2,6 +2,4 @@ maxOutputSize = 2500000 modules = \ java.base/jdk.internal.classfile.components \ java.base/jdk.internal.classfile.impl \ - java.base/jdk.internal.classfile.impl.verifier \ - java.base/jdk.internal.org.objectweb.asm \ - java.base/jdk.internal.org.objectweb.asm.tree \ No newline at end of file + java.base/jdk.internal.classfile.impl.verifier \ No newline at end of file diff --git a/test/jdk/jdk/classfile/helpers/Transforms.java b/test/jdk/jdk/classfile/helpers/Transforms.java index b0e88bd8212..dba3f21cbd8 100644 --- a/test/jdk/jdk/classfile/helpers/Transforms.java +++ b/test/jdk/jdk/classfile/helpers/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,27 +43,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -128,42 +113,10 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); - // Need ASM, LOW_UNSHARED + // Need LOW_UNSHARED public final UnaryOperator<byte[]> transform; public final boolean shared; @@ -202,12 +155,6 @@ public Optional<ClassRecord> classRecord(byte[] bytes) throws IOException { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -242,13 +189,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -273,20 +213,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -319,277 +245,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } From e10f0a0a165ec4a33f579788e5f63533a0d6e774 Mon Sep 17 00:00:00 2001 From: Adam Sotona <asotona@openjdk.org> Date: Mon, 6 Jan 2025 14:10:19 +0000 Subject: [PATCH 31/99] 8346984: Remove ASM-based benchmarks from Class-File API benchmarks Reviewed-by: liach, redestad, erikj --- make/test/BuildMicrobenchmark.gmk | 4 +- .../classfile/AbstractCorpusBenchmark.java | 4 +- .../bench/jdk/classfile/AdaptNull.java | 6 +- .../openjdk/bench/jdk/classfile/ReadDeep.java | 57 +-- .../bench/jdk/classfile/ReadMetadata.java | 70 +--- .../bench/jdk/classfile/Transforms.java | 349 +----------------- .../openjdk/bench/jdk/classfile/Write.java | 72 +--- 7 files changed, 7 insertions(+), 555 deletions(-) diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1052e422f7b..272cb1af0a6 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -96,8 +96,6 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ --add-exports java.base/jdk.internal.util=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ --add-exports java.base/sun.invoke.util=ALL-UNNAMED \ --add-exports java.base/sun.security.util=ALL-UNNAMED \ diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java index f3c934d9c65..ea361b4975b 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,8 +44,6 @@ @Warmup(iterations = 2) @Measurement(iterations = 4) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) @State(Scope.Benchmark) diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java index 55c33b36805..680d1626b2c 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,10 +35,6 @@ public class AdaptNull extends AbstractCorpusBenchmark { @Param({ // "ARRAYCOPY", - "ASM_1", - "ASM_3", - "ASM_UNSHARED_3", -// "ASM_TREE", "SHARED_1", "SHARED_2", "SHARED_3", diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java index 4165785135c..a134e04bd5a 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,12 +29,6 @@ import java.lang.classfile.CompoundElement; import java.lang.classfile.MethodModel; import java.lang.classfile.instruction.LoadInstruction; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.tree.ClassNode; -import jdk.internal.org.objectweb.asm.tree.MethodNode; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -45,55 +39,6 @@ */ public class ReadDeep extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - var visitor = new ClassVisitor(Opcodes.ASM9) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return mv; - } - }; - cr.accept(visitor, 0); - bh.consume(mv.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (MethodNode mn : node.methods) { - mn.accept(mv); - } - bh.consume(mv.count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkElementsCountLoads(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java index 08b1b6312b1..0a12c5214e7 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,42 +27,11 @@ import java.lang.classfile.ClassModel; import java.lang.classfile.ClassFile; import java.lang.classfile.FieldModel; -import jdk.internal.org.objectweb.asm.*; -import jdk.internal.org.objectweb.asm.tree.*; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; public class ReadMetadata extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - String theName; - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - theName = name; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.theName); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - bh.consume(node.name); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkReadName(Blackhole bh) { @@ -90,43 +59,6 @@ public void jdkReadMemberNames(Blackhole bh) { } } - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - int count; - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - if ((access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - return null; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - int count = 0; - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (FieldNode fn : node.fields) - if ((fn.access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - bh.consume(count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkTreeCountFields(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java index 8af03a8b874..19c87442039 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,27 +41,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -123,38 +108,6 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); @@ -186,12 +139,6 @@ public enum NoOpTransform { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -226,13 +173,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -257,20 +197,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -303,277 +229,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Write.java b/test/micro/org/openjdk/bench/jdk/classfile/Write.java index ffd5b8f1c5e..9317ef78806 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Write.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Write.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ import java.lang.reflect.AccessFlag; import java.lang.classfile.ClassFile; import java.lang.classfile.attribute.SourceFileAttribute; -import jdk.internal.org.objectweb.asm.*; import org.openjdk.jmh.annotations.*; import java.io.FileOutputStream; import static java.lang.classfile.ClassFile.ACC_PUBLIC; @@ -57,8 +56,6 @@ @Warmup(iterations = 3) @Measurement(iterations = 5) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) public class Write { static final int REPEATS = 40; @@ -70,76 +67,9 @@ public class Write { } METHOD_NAMES = names; } - static String checkFileAsm = "/tmp/asw/MyClass.class"; static String checkFileBc = "/tmp/byw/MyClass.class"; - static boolean writeClassAsm = Files.exists(Paths.get(checkFileAsm).getParent()); static boolean writeClassBc = Files.exists(Paths.get(checkFileBc).getParent()); - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public byte[] asmStream() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V12, Opcodes.ACC_PUBLIC, "MyClass", null, "java/lang/Object", null); - cw.visitSource("MyClass.java", null); - - { - MethodVisitor mv = cw.visitMethod(0, INIT_NAME, "()V", null, null); - mv.visitCode(); - Label startLabel = new Label(); - Label endLabel = new Label(); - mv.visitLabel(startLabel); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", INIT_NAME, "()V", false); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(endLabel); - mv.visitLocalVariable("this", "LMyClass;", null, startLabel, endLabel, 1); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - - for (int xi = 0; xi < REPEATS; ++xi) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, METHOD_NAMES[xi], "([Ljava/lang/String;)V", null, null); - mv.visitCode(); - Label loopTop = new Label(); - Label loopEnd = new Label(); - Label startLabel = new Label(); - Label endLabel = new Label(); - Label iStart = new Label(); - mv.visitLabel(startLabel); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitLabel(iStart); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 2); - mv.visitLabel(loopTop); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitIntInsn(Opcodes.BIPUSH, 10); - mv.visitJumpInsn(Opcodes.IF_ICMPGE, loopEnd); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitInsn(Opcodes.IMUL); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitIincInsn(2, 1); - mv.visitJumpInsn(Opcodes.GOTO, loopTop); - mv.visitLabel(loopEnd); - mv.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false); - mv.visitLabel(endLabel); - mv.visitInsn(Opcodes.RETURN); - mv.visitLocalVariable("fac", "I", null, startLabel, endLabel, 1); - mv.visitLocalVariable("i", "I", null, iStart, loopEnd, 2); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - if (writeClassAsm) writeClass(bytes, checkFileAsm); - return bytes; - } - @Benchmark @BenchmarkMode(Mode.Throughput) public byte[] jdkTree() { From ddcd640320473479ec880d25cf656fccb86220d4 Mon Sep 17 00:00:00 2001 From: Adam Sotona <asotona@openjdk.org> Date: Mon, 6 Jan 2025 14:10:34 +0000 Subject: [PATCH 32/99] 8346985: Convert test/jdk/com/sun/jdi/ClassUnloadEventTest.java to Class-File API Reviewed-by: liach --- .../jdk/com/sun/jdi/ClassUnloadEventTest.java | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/test/jdk/com/sun/jdi/ClassUnloadEventTest.java b/test/jdk/com/sun/jdi/ClassUnloadEventTest.java index cf77ba846ae..41b1bff5e42 100644 --- a/test/jdk/com/sun/jdi/ClassUnloadEventTest.java +++ b/test/jdk/com/sun/jdi/ClassUnloadEventTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,18 +24,13 @@ /* * @test * @bug 8256811 - * @modules java.base/jdk.internal.org.objectweb.asm - * java.base/jdk.internal.misc + * @modules java.base/jdk.internal.misc * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm/native ClassUnloadEventTest run */ -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; import jdk.test.lib.classloader.ClassUnloadCommon; import com.sun.jdi.*; @@ -45,6 +40,9 @@ import java.util.*; import java.io.*; +import java.lang.classfile.ClassFile; +import java.lang.constant.ClassDesc; +import java.lang.constant.ConstantDescs; public class ClassUnloadEventTest { static final String CLASS_NAME_PREFIX = "SampleClass__"; @@ -65,18 +63,13 @@ public static void main(String[] args) throws Exception { } } - private static class TestClassLoader extends ClassLoader implements Opcodes { + private static class TestClassLoader extends ClassLoader { private static byte[] generateSampleClass(String name) { - ClassWriter cw = new ClassWriter(0); - - cw.visit(52, ACC_SUPER | ACC_PUBLIC, name, null, "java/lang/Object", null); - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - cw.visitEnd(); - return cw.toByteArray(); + return ClassFile.of().build(ClassDesc.of(name), clb -> + clb.withVersion(52, 0) + .withFlags(ClassFile.ACC_SUPER | ClassFile.ACC_PUBLIC) + .withMethodBody("m", ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC, cob -> + cob.return_())); } @Override From ad66e25bdab3d71945c8760c707c6ee454aee6ab Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Mon, 6 Jan 2025 15:28:36 +0000 Subject: [PATCH 33/99] 8344079: Minor fixes and cleanups to compiler lint-related code Reviewed-by: mcimadamore --- .../com/sun/tools/javac/code/Lint.java | 202 +++++++++--------- .../com/sun/tools/javac/comp/Check.java | 18 +- .../sun/tools/javac/file/BaseFileManager.java | 10 +- .../sun/tools/javac/parser/JavaTokenizer.java | 6 +- .../com/sun/tools/javac/util/Warner.java | 6 +- 5 files changed, 129 insertions(+), 113 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java index e28c0fe60f8..1131800f8ed 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,16 +30,17 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; -import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.LintWarning; -import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Options; -import com.sun.tools.javac.util.Pair; /** * A class for handling -Xlint suboptions and @SuppressWarnings. @@ -49,8 +50,8 @@ * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ -public class Lint -{ +public class Lint { + /** The context key for the root Lint object. */ protected static final Context.Key<Lint> lintKey = new Context.Key<>(); @@ -63,26 +64,35 @@ public static Lint instance(Context context) { } /** - * Returns the result of combining the values in this object with - * the given annotation. + * Obtain an instance with additional warning supression applied from any + * @SuppressWarnings and/or @Deprecated annotations on the given symbol. + * + * <p> + * The returned instance will be different from this instance if and only if + * {@link #suppressionsFrom} returns a non-empty set. + * + * @param sym symbol + * @return lint instance with new warning suppressions applied, or this instance if none */ - public Lint augment(Attribute.Compound attr) { - return augmentor.augment(this, attr); + public Lint augment(Symbol sym) { + EnumSet<LintCategory> suppressions = suppressionsFrom(sym); + if (!suppressions.isEmpty()) { + Lint lint = new Lint(this); + lint.values.removeAll(suppressions); + lint.suppressedValues.addAll(suppressions); + return lint; + } + return this; } - /** - * Returns the result of combining the values in this object with - * the metadata on the given symbol. + * Returns a new Lint that has the given LintCategorys enabled. + * @param lc one or more categories to be enabled */ - public Lint augment(Symbol sym) { - Lint l = augmentor.augment(this, sym.getDeclarationAttributes()); - if (sym.isDeprecated() && sym.isDeprecatableViaAnnotation()) { - if (l == this) - l = new Lint(this); - l.values.remove(LintCategory.DEPRECATION); - l.suppressedValues.add(LintCategory.DEPRECATION); - } + public Lint enable(LintCategory... lc) { + Lint l = new Lint(this); + l.values.addAll(Arrays.asList(lc)); + l.suppressedValues.removeAll(Arrays.asList(lc)); return l; } @@ -97,8 +107,13 @@ public Lint suppress(LintCategory... lc) { return l; } - private final AugmentVisitor augmentor; + private final Context context; + + // These are initialized lazily to avoid dependency loops + private Symtab syms; + private Names names; + // Invariant: it's never the case that a category is in both "values" and "suppressedValues" private final EnumSet<LintCategory> values; private final EnumSet<LintCategory> suppressedValues; @@ -114,10 +129,10 @@ protected Lint(Context context) { values = EnumSet.allOf(LintCategory.class); } else if (options.isSet(Option.XLINT_CUSTOM, "none")) { // if -Xlint:none is given, disable all categories by default - values = EnumSet.noneOf(LintCategory.class); + values = LintCategory.newEmptySet(); } else { // otherwise, enable on-by-default categories - values = EnumSet.noneOf(LintCategory.class); + values = LintCategory.newEmptySet(); Source source = Source.instance(context); if (source.compareTo(Source.JDK9) >= 0) { @@ -146,21 +161,23 @@ protected Lint(Context context) { } } - suppressedValues = EnumSet.noneOf(LintCategory.class); + suppressedValues = LintCategory.newEmptySet(); + this.context = context; context.put(lintKey, this); - augmentor = new AugmentVisitor(context); } protected Lint(Lint other) { - this.augmentor = other.augmentor; + this.context = other.context; + this.syms = other.syms; + this.names = other.names; this.values = other.values.clone(); this.suppressedValues = other.suppressedValues.clone(); } @Override public String toString() { - return "Lint:[values" + values + " suppressedValues" + suppressedValues + "]"; + return "Lint:[enable" + values + ",suppress" + suppressedValues + "]"; } /** @@ -373,6 +390,11 @@ public static Optional<LintCategory> get(String option) { return Optional.ofNullable(map.get(option)); } + public static EnumSet<LintCategory> newEmptySet() { + return EnumSet.noneOf(LintCategory.class); + } + + /** Get the string representing this category in @SuppressAnnotations and -Xlint options. */ public final String option; } @@ -404,82 +426,64 @@ public void logIfEnabled(Log log, DiagnosticPosition pos, LintWarning warning) { } } - protected static class AugmentVisitor implements Attribute.Visitor { - private final Context context; - private Symtab syms; - private Lint parent; - private Lint lint; - - AugmentVisitor(Context context) { - // to break an ugly sequence of initialization dependencies, - // we defer the initialization of syms until it is needed - this.context = context; - } - - Lint augment(Lint parent, Attribute.Compound attr) { - initSyms(); - this.parent = parent; - lint = null; - attr.accept(this); - return (lint == null ? parent : lint); - } - - Lint augment(Lint parent, List<Attribute.Compound> attrs) { - initSyms(); - this.parent = parent; - lint = null; - for (Attribute.Compound a: attrs) { - a.accept(this); - } - return (lint == null ? parent : lint); - } - - private void initSyms() { - if (syms == null) - syms = Symtab.instance(context); - } - - private void suppress(LintCategory lc) { - if (lint == null) - lint = new Lint(parent); - lint.suppressedValues.add(lc); - lint.values.remove(lc); - } - - public void visitConstant(Attribute.Constant value) { - if (value.type.tsym == syms.stringType.tsym) { - LintCategory.get((String)value.value) - .ifPresent(this::suppress); - } - } - - public void visitClass(Attribute.Class clazz) { - } - - // If we find a @SuppressWarnings annotation, then we continue - // walking the tree, in order to suppress the individual warnings - // specified in the @SuppressWarnings annotation. - public void visitCompound(Attribute.Compound compound) { - if (compound.type.tsym == syms.suppressWarningsType.tsym) { - for (List<Pair<MethodSymbol,Attribute>> v = compound.values; - v.nonEmpty(); v = v.tail) { - Pair<MethodSymbol,Attribute> value = v.head; - if (value.fst.name.toString().equals("value")) - value.snd.accept(this); - } + /** + * Obtain the set of recognized lint warning categories suppressed at the given symbol's declaration. + * + * <p> + * This set can be non-empty only if the symbol is annotated with either + * @SuppressWarnings or @Deprecated. + * + * @param symbol symbol corresponding to a possibly-annotated declaration + * @return new warning suppressions applied to sym + */ + public EnumSet<LintCategory> suppressionsFrom(Symbol symbol) { + EnumSet<LintCategory> suppressions = suppressionsFrom(symbol.getDeclarationAttributes().stream()); + if (symbol.isDeprecated() && symbol.isDeprecatableViaAnnotation()) + suppressions.add(LintCategory.DEPRECATION); + return suppressions; + } - } - } + /** + * Retrieve the recognized lint categories suppressed by the given @SuppressWarnings annotation. + * + * @param annotation @SuppressWarnings annotation, or null + * @return set of lint categories, possibly empty but never null + */ + private EnumSet<LintCategory> suppressionsFrom(JCAnnotation annotation) { + initializeIfNeeded(); + if (annotation == null) + return LintCategory.newEmptySet(); + Assert.check(annotation.attribute.type.tsym == syms.suppressWarningsType.tsym); + return suppressionsFrom(Stream.of(annotation).map(anno -> anno.attribute)); + } - public void visitArray(Attribute.Array array) { - for (Attribute value : array.values) - value.accept(this); - } + // Find the @SuppressWarnings annotation in the given stream and extract the recognized suppressions + private EnumSet<LintCategory> suppressionsFrom(Stream<Attribute.Compound> attributes) { + initializeIfNeeded(); + EnumSet<LintCategory> result = LintCategory.newEmptySet(); + attributes + .filter(attribute -> attribute.type.tsym == syms.suppressWarningsType.tsym) + .map(this::suppressionsFrom) + .forEach(result::addAll); + return result; + } - public void visitEnum(Attribute.Enum e) { + // Given a @SuppressWarnings annotation, extract the recognized suppressions + private EnumSet<LintCategory> suppressionsFrom(Attribute.Compound suppressWarnings) { + EnumSet<LintCategory> result = LintCategory.newEmptySet(); + Attribute.Array values = (Attribute.Array)suppressWarnings.member(names.value); + for (Attribute value : values.values) { + Optional.of((String)((Attribute.Constant)value).value) + .flatMap(LintCategory::get) + .ifPresent(result::add); } + return result; + } - public void visitError(Attribute.Error e) { + private void initializeIfNeeded() { + if (syms == null) { + syms = Symtab.instance(context); + names = Names.instance(context); } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index a5b4186659b..a76dab2bb31 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2945,11 +2945,19 @@ boolean potentiallyAmbiguousOverload(Type site, MethodSymbol msym1, MethodSymbol return potentiallyAmbiguous; } + // Apply special flag "-XDwarnOnAccessToMembers" which turns on just this particular warning for all types of access void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) { - if (warnOnAnyAccessToMembers || - (lint.isEnabled(LintCategory.SERIAL) && - !lint.isSuppressed(LintCategory.SERIAL) && - isLambda)) { + final Lint prevLint = setLint(warnOnAnyAccessToMembers ? lint.enable(LintCategory.SERIAL) : lint); + try { + if (warnOnAnyAccessToMembers || isLambda) + checkAccessFromSerializableElementInner(tree, isLambda); + } finally { + setLint(prevLint); + } + } + + private void checkAccessFromSerializableElementInner(final JCTree tree, boolean isLambda) { + if (lint.isEnabled(LintCategory.SERIAL)) { Symbol sym = TreeInfo.symbol(tree); if (!sym.kind.matches(KindSelector.VAL_MTH)) { return; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java index 646db6a6bf3..4a5370f7a14 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,7 @@ import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; +import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.main.Option; import com.sun.tools.javac.main.OptionHelper; import com.sun.tools.javac.main.OptionHelper.GrumpyHelper; @@ -90,10 +91,13 @@ public void setContext(Context context) { classLoaderClass = options.get("procloader"); // Detect Lint options, but use Options.isLintSet() to avoid initializing the Lint class - boolean warn = options.isLintSet("path"); + boolean warn = options.isLintSet(LintCategory.PATH.option); + boolean fileClashOption = options.isLintSet(LintCategory.OUTPUT_FILE_CLASH.option); locations.update(log, warn, FSInfo.instance(context)); + + // Only track file clashes if enabled synchronized (this) { - outputFilesWritten = options.isLintSet("output-file-clash") ? new HashSet<>() : null; + outputFilesWritten = fileClashOption ? new HashSet<>() : null; } // Setting this option is an indication that close() should defer actually closing diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java index b25ca99eb88..2cec3549c7a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,12 +219,12 @@ protected void lexError(DiagnosticFlag flags, int pos, JCDiagnostic.Error key) { } /** - * Report an error at the given position using the provided arguments. + * Report a warning at the given position using the provided arguments. * * @param pos position in input buffer. * @param key error key to report. */ - protected void lexWarning(int pos, JCDiagnostic.Warning key) { + protected void lexWarning(int pos, JCDiagnostic.LintWarning key) { DiagnosticPosition dp = new SimpleDiagnosticPosition(pos) ; log.warning(dp, key); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java index 7b993c1bf16..3da0be49d33 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Warner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,8 @@ public class Warner { private DiagnosticPosition pos = null; protected boolean warned = false; - private EnumSet<LintCategory> nonSilentLintSet = EnumSet.noneOf(LintCategory.class); - private EnumSet<LintCategory> silentLintSet = EnumSet.noneOf(LintCategory.class); + private EnumSet<LintCategory> nonSilentLintSet = LintCategory.newEmptySet(); + private EnumSet<LintCategory> silentLintSet = LintCategory.newEmptySet(); public DiagnosticPosition pos() { return pos; From ead0ec7e836a00b8325192a973e3d0ee12cdd6aa Mon Sep 17 00:00:00 2001 From: Naoto Sato <naoto@openjdk.org> Date: Mon, 6 Jan 2025 17:04:07 +0000 Subject: [PATCH 34/99] 8345668: ZoneOffset.ofTotalSeconds performance regression Reviewed-by: rriggs, aturbanov --- .../share/classes/java/time/ZoneOffset.java | 16 +++++++++++----- .../java/time/format/DateTimeTextProvider.java | 12 ++++++++++-- .../classes/java/time/format/DecimalStyle.java | 12 ++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 14ac5fcfb6b..520a0e0b9a1 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 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 @@ -424,11 +424,17 @@ public static ZoneOffset ofTotalSeconds(int totalSeconds) { throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); } if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { - return SECONDS_CACHE.computeIfAbsent(totalSeconds, totalSecs -> { - ZoneOffset result = new ZoneOffset(totalSecs); + Integer totalSecs = totalSeconds; + ZoneOffset result = SECONDS_CACHE.get(totalSecs); + if (result == null) { + result = new ZoneOffset(totalSeconds); + var existing = SECONDS_CACHE.putIfAbsent(totalSecs, result); + if (existing != null) { + result = existing; + } ID_CACHE.putIfAbsent(result.getId(), result); - return result; - }); + } + return result; } else { return new ZoneOffset(totalSeconds); } diff --git a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java index 5ee4c5c23c8..5be33551c70 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java +++ b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -309,7 +309,15 @@ public Iterator<Entry<String, Long>> getTextIterator(Chronology chrono, Temporal private Object findStore(TemporalField field, Locale locale) { Entry<TemporalField, Locale> key = createEntry(field, locale); - return CACHE.computeIfAbsent(key, e -> createStore(e.getKey(), e.getValue())); + Object store = CACHE.get(key); + if (store == null) { + store = createStore(field, locale); + var existing = CACHE.putIfAbsent(key, store); + if (existing != null) { + store = existing; + } + } + return store; } private static int toWeekDay(int calWeekDay) { diff --git a/src/java.base/share/classes/java/time/format/DecimalStyle.java b/src/java.base/share/classes/java/time/format/DecimalStyle.java index b2513888790..a9ad8a4e273 100644 --- a/src/java.base/share/classes/java/time/format/DecimalStyle.java +++ b/src/java.base/share/classes/java/time/format/DecimalStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -160,7 +160,15 @@ public static DecimalStyle ofDefaultLocale() { */ public static DecimalStyle of(Locale locale) { Objects.requireNonNull(locale, "locale"); - return CACHE.computeIfAbsent(locale, DecimalStyle::create); + DecimalStyle info = CACHE.get(locale); + if (info == null) { + info = create(locale); + var existing = CACHE.putIfAbsent(locale, info); + if (existing != null) { + info = existing; + } + } + return info; } private static DecimalStyle create(Locale locale) { From 25a4536daf21d1e9f44d520f9adf15b100970fd2 Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Mon, 6 Jan 2025 17:24:23 +0000 Subject: [PATCH 35/99] 8346953: Remove unnecessary @SuppressWarnings annotations (client, #2) Reviewed-by: azvegint --- .../com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java | 5 +---- .../unix/classes/sun/awt/X11/XComponentPeer.java | 4 +--- .../unix/classes/sun/awt/X11/XFileDialogPeer.java | 4 +--- src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java | 3 +-- .../unix/classes/sun/awt/X11/XMouseInfoPeer.java | 3 +-- .../unix/classes/sun/awt/X11/XWindowPeer.java | 3 +-- .../sun/java/swing/plaf/windows/WindowsFileChooserUI.java | 8 +------- .../swing/plaf/windows/WindowsInternalFrameTitlePane.java | 3 +-- .../windows/classes/sun/awt/windows/WDialogPeer.java | 3 +-- 9 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java index 79c86de16c6..19d77115025 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -621,7 +621,6 @@ public void installComponents(JFileChooser fc) { fc.add(interior, BorderLayout.CENTER); - @SuppressWarnings("serial") // anonymous class JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0) { public void layoutContainer(Container target) { @@ -733,7 +732,6 @@ public void layoutContainer(Container target) { if (currentDirectory != null) { curDirName = currentDirectory.getPath(); } - @SuppressWarnings("serial") // anonymous class JLabel tmp = new JLabel(curDirName) { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); @@ -748,7 +746,6 @@ public Dimension getMaximumSize() { interior.add(pathFieldPanel); // add the fileName field - @SuppressWarnings("serial") // anonymous class JTextField tmp2 = new JTextField() { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java index 79d6965e05f..42e684bfac7 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,7 +168,6 @@ public boolean isReparentSupported() { return System.getProperty("sun.awt.X11.XComponentPeer.reparentNotSupported", "false").equals("false"); } - @SuppressWarnings("deprecation") public boolean isObscured() { Container container = (target instanceof Container) ? (Container)target : target.getParent(); @@ -244,7 +243,6 @@ static final AWTEvent wrapInSequenced(AWTEvent event) { } // TODO: consider moving it to KeyboardFocusManagerPeerImpl - @SuppressWarnings("deprecation") public final boolean requestFocus(Component lightweightChild, boolean temporary, boolean focusedWindowChangeAllowed, long time, FocusEvent.Cause cause) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java index 98caf9f43cf..5c6fde2251c 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,7 +197,6 @@ private void init(FileDialog target) { // After showing we should display 'user.dir' as current directory // if user didn't set directory programmatically pathField = new TextField(savedDir != null ? savedDir : userDir); - @SuppressWarnings("serial") // Anonymous class Choice tmp = new Choice() { public Dimension getPreferredSize() { return new Dimension(PATH_CHOICE_WIDTH, pathField.getPreferredSize().height); @@ -778,7 +777,6 @@ public void dispose() { } // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg on Xtoolkit - @SuppressWarnings("deprecation") public void setVisible(boolean b){ if (fileDialog == null) { init(target); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java index c7f3ba95bc1..acbe8639702 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,7 +137,6 @@ void setupState(boolean onInit) { setExtendedState(state); } - @SuppressWarnings("deprecation") public void setMenuBar(MenuBar mb) { // state_lock should always be the second after awt_lock XToolkit.awtLock(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java index f4c46c2766d..321cb4fbf1e 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XMouseInfoPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,6 @@ public int fillPointWithCoords(Point point) { return 0; } - @SuppressWarnings("deprecation") public boolean isWindowUnderMouse(Window w) { if (w == null) { return false; diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index a37e82d2273..cda05e0a6c7 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,7 +214,6 @@ protected String getWMName() { private static native String getLocalHostname(); private static native int getJvmPID(); - @SuppressWarnings("deprecation") void postInit(XCreateWindowParams params) { super.postInit(params); diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java index 41fa0c3f048..7065e3db19b 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -273,7 +273,6 @@ public void installComponents(JFileChooser fc) { fc.add(topPanel, BorderLayout.NORTH); // ComboBox Label - @SuppressWarnings("serial") // anonymous class JLabel tmp1 = new JLabel(lookInLabelText, JLabel.TRAILING) { public Dimension getPreferredSize() { return getMinimumSize(); @@ -295,7 +294,6 @@ public Dimension getMinimumSize() { topPanel.add(Box.createRigidArea(new Dimension(8,0))); // CurrentDir ComboBox - @SuppressWarnings("serial") // anonymous class JComboBox<File> tmp2 = new JComboBox<File>() { public Dimension getMinimumSize() { Dimension d = super.getMinimumSize(); @@ -477,7 +475,6 @@ public void propertyChange(PropertyChangeEvent e) { fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS)); - @SuppressWarnings("serial") // anonymous class JTextField tmp3 = new JTextField(35) { public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height); @@ -518,7 +515,6 @@ public void focusGained(FocusEvent e) { // buttons getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS)); - @SuppressWarnings("serial") // anonymous class JButton tmp4 = new JButton(getApproveButtonText(fc)) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? @@ -537,7 +533,6 @@ public Dimension getMaximumSize() { getButtonPanel().add(approveButton); getButtonPanel().add(Box.createRigidArea(vstrut4)); - @SuppressWarnings("serial") // anonymous class JButton tmp5 = new JButton(cancelButtonText) { public Dimension getMaximumSize() { return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? @@ -974,7 +969,6 @@ protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser return new DirectoryComboBoxRenderer(); } - @SuppressWarnings("serial") // anonymous class private static JButton createToolButton(Action a, Icon defaultIcon, String toolTipText, String accessibleName) { final JButton result = new JButton(a); diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java index cd0987a9079..083563b4464 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,7 +289,6 @@ protected void assembleSystemMenu() { systemPopupMenu = new JPopupMenu(); addSystemMenuItems(systemPopupMenu); enableActions(); - @SuppressWarnings("serial") // anonymous class JLabel tmp = new JLabel(frame.getFrameIcon()) { protected void paintComponent(Graphics g) { int x = 0; diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java index 930064d5981..a02bceae7fb 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,6 @@ protected void realShow() { } @Override - @SuppressWarnings("deprecation") void hide() { Dialog dlg = (Dialog)target; if (dlg.getModalityType() != Dialog.ModalityType.MODELESS) { From 22dfbe08f14bbb4a10051a1c55356ab8f1ebfe7d Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Mon, 6 Jan 2025 17:47:10 +0000 Subject: [PATCH 36/99] 8345432: (ch, fs) Replace anonymous Thread with InnocuousThread Reviewed-by: alanb --- .../share/classes/sun/nio/ch/ThreadPool.java | 2 +- .../share/classes/sun/nio/fs/AbstractPoller.java | 9 +++------ .../share/classes/sun/nio/fs/Cancellable.java | 11 ++++++----- .../share/classes/sun/nio/fs/PollingWatchService.java | 3 ++- .../windows/classes/sun/nio/ch/PipeImpl.java | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java index 92aee323823..38a49567c15 100644 --- a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java +++ b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java @@ -70,7 +70,7 @@ int poolSize() { static ThreadFactory defaultThreadFactory() { return (Runnable r) -> { - Thread t = new Thread(r); + Thread t = InnocuousThread.newThread(r); t.setDaemon(true); return t; }; diff --git a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java index e2ac950f01d..29c07223988 100644 --- a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java +++ b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java @@ -25,9 +25,10 @@ package sun.nio.fs; -import java.nio.file.*; import java.io.IOException; +import java.nio.file.*; import java.util.*; +import jdk.internal.misc.InnocuousThread; /** * Base implementation of background poller thread used in watch service @@ -53,11 +54,7 @@ protected AbstractPoller() { * Starts the poller thread */ public void start() { - Thread thr = new Thread(null, - this, - "FileSystemWatchService", - 0, - false); + Thread thr = InnocuousThread.newThread("FileSystemWatchService", this); thr.setDaemon(true); thr.start(); } diff --git a/src/java.base/share/classes/sun/nio/fs/Cancellable.java b/src/java.base/share/classes/sun/nio/fs/Cancellable.java index 5e3ff43a7b0..df3c95abcc9 100644 --- a/src/java.base/share/classes/sun/nio/fs/Cancellable.java +++ b/src/java.base/share/classes/sun/nio/fs/Cancellable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 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 @@ -25,14 +25,15 @@ package sun.nio.fs; -import jdk.internal.misc.Unsafe; import java.util.concurrent.ExecutionException; +import jdk.internal.misc.InnocuousThread; +import jdk.internal.misc.Unsafe; /** * Base implementation of a task (typically native) that polls a memory location * during execution so that it may be aborted/cancelled before completion. The - * task is executed by invoking the {@link runInterruptibly} method defined - * here and cancelled by invoking Thread.interrupt. + * task is executed by invoking the {@linkplain #runInterruptibly} method + * defined here and cancelled by invoking Thread.interrupt. */ abstract class Cancellable implements Runnable { @@ -117,7 +118,7 @@ public final void run() { * thread by writing into the memory location that it polls cooperatively. */ static void runInterruptibly(Cancellable task) throws ExecutionException { - Thread t = new Thread(null, task, "NIO-Task", 0, false); + Thread t = InnocuousThread.newThread("CancellableOp", task); t.start(); boolean cancelledByInterrupt = false; while (t.isAlive()) { diff --git a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java index 0284156ca3b..da486231a1d 100644 --- a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java +++ b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java @@ -47,6 +47,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import jdk.internal.misc.InnocuousThread; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; /** @@ -73,7 +74,7 @@ class PollingWatchService .newSingleThreadScheduledExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { - Thread t = new Thread(null, r, "FileSystemWatcher", 0, false); + Thread t = InnocuousThread.newThread("FileSystemWatcher", r); t.setDaemon(true); return t; }}); diff --git a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java index 7e138a5cc11..1e4b6a05ce1 100644 --- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java @@ -78,7 +78,7 @@ public void init() throws IOException { connector.run(); if (ioe instanceof ClosedByInterruptException) { ioe = null; - Thread connThread = new Thread(connector) { + Thread connThread = new Thread(connector, "LoopbackConnector") { @Override public void interrupt() {} }; From 9fc10eca447bf2215f5fba8b3eea45008f5b830e Mon Sep 17 00:00:00 2001 From: Calvin Cheung <ccheung@openjdk.org> Date: Mon, 6 Jan 2025 17:59:10 +0000 Subject: [PATCH 37/99] 8346457: AOT cache creation crashes with "assert(pair_at(i).match() < pair_at(i+1).match()) failed: unsorted table entries" Reviewed-by: iklam, dholmes --- .../cds/appcds/CreateAOTCacheVerifyError.java | 49 ++++++++ .../appcds/test-classes/BadLookupSwitch.jcod | 118 ++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod diff --git a/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java b/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java new file mode 100644 index 00000000000..c478fad7cc2 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/CreateAOTCacheVerifyError.java @@ -0,0 +1,49 @@ +/* + * 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 8346457 + * @summary VM should not crash during AOT cache creation when encountering a + * class with VerifyError. + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @compile test-classes/BadLookupSwitch.jcod + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar badlookupswitch.jar BadLookupSwitch + * @run driver CreateAOTCacheVerifyError + */ + +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class CreateAOTCacheVerifyError { + + public static void main(String[] args) throws Exception { + String appJar = ClassFileInstaller.getJarPath("badlookupswitch.jar"); + String classList[] = { BadLookupSwitch.class.getName() }; + OutputAnalyzer out = TestCommon.testDump(appJar, classList); + out.shouldContain("Preload Warning: Verification failed for BadLookupSwitch"); + out.shouldHaveExitValue(0); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod new file mode 100644 index 00000000000..4912479a8aa --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/BadLookupSwitch.jcod @@ -0,0 +1,118 @@ +/* + * 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. + * + */ + +class BadLookupSwitch { + 0xCAFEBABE; + 0; + 50; + [] { // Constant Pool + ; // first element is empty + class #12; // #1 at 0x0A + class #15; // #2 at 0x0D + Method #2 #4; // #3 at 0x10 + NameAndType #6 #5; // #4 at 0x15 + Utf8 "()V"; // #5 at 0x1A + Utf8 "<init>"; // #6 at 0x20 + Utf8 "Code"; // #7 at 0x29 + Utf8 "ConstantValue"; // #8 at 0x30 + Utf8 "Exceptions"; // #9 at 0x40 + Utf8 "LineNumberTable"; // #10 at 0x4D + Utf8 "LocalVariables"; // #11 at 0x5F + Utf8 "BadLookupSwitch"; // #12 at 0x70 + Utf8 "SourceFile"; // #13 at 0x76 + Utf8 "f.java"; // #14 at 0x83 + Utf8 "java/lang/Object"; // #15 at 0x8C + Utf8 "m"; // #16 at 0x9F + Utf8 "StackMapTable"; // #17 + } // Constant Pool + + 0x0020; // access + #1;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [2] { // methods + { // Member at 0xAF + 0x0001; // access + #16; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#7) { // Code at 0xB7 + 1; // max_stack + 1; // max_locals + Bytes[29] { + 0x04AB00000000001B; // iconst_1; +/* right: + 0x0000000200000001; // lookupswitch 27 2 1 27 2 27; + 0x0000001B00000002; + 0x0000001B; +end right */ +// wrong: + 0x0000000200000002; // lookupswitch 27 2 2 27 1 27; + 0x0000001B00000001; + 0x0000001B; +// end wrong + 0xB1; // return + }; + [0] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // StackMap + [] { // + 255b, 28, []{O,1}, []{}; + } + } // end StackMap + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0xD6 + 0x0000; // access + #6; // name_cpx + #5; // sig_cpx + [1] { // Attributes + Attr(#7) { // Code at 0xDE + 1; // max_stack + 1; // max_locals + Bytes[5] { + 0x2AB70003B1; + }; + [0] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class From 26cc96167672e009b068e2521e0ec331a00aa98e Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Mon, 6 Jan 2025 18:37:19 +0000 Subject: [PATCH 38/99] 8344148: Add an explicit compiler phase for warning generation Reviewed-by: vromero --- .../sun/tools/javac/comp/CompileStates.java | 13 ++-- .../com/sun/tools/javac/comp/Flow.java | 3 +- .../tools/javac/comp/ThisEscapeAnalyzer.java | 57 ++++++++++++--- .../com/sun/tools/javac/comp/TransTypes.java | 8 +-- .../sun/tools/javac/comp/WarningAnalyzer.java | 63 ++++++++++++++++ .../sun/tools/javac/main/JavaCompiler.java | 71 +++++++++++++++++-- .../tools/javac/6734819/T6734819a.out | 3 + .../tools/javac/6734819/T6734819b.out | 2 + .../tools/javac/6734819/T6734819c.out | 2 + .../SkipAttrFlowGenForImplicits.out | 1 + .../tools/javac/policy/test1/byfile.ABD.out | 3 + .../tools/javac/policy/test1/byfile.ACD.out | 3 + .../tools/javac/policy/test1/bytodo.ABD.out | 4 ++ .../tools/javac/policy/test1/bytodo.ACD.out | 4 ++ .../tools/javac/policy/test2/byfile.AB.out | 2 + .../tools/javac/policy/test2/byfile.BA.out | 2 + .../tools/javac/policy/test2/bytodo.AB.out | 2 + .../tools/javac/policy/test2/bytodo.BA.out | 2 + .../tools/javac/recovery/AttrRecovery.java | 4 +- 19 files changed, 219 insertions(+), 30 deletions(-) create mode 100644 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java index b9cab47d8ab..4896ecbe728 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,11 +58,12 @@ public enum CompileState { PROCESS(3), ATTR(4), FLOW(5), - TRANSTYPES(6), - TRANSPATTERNS(7), - LOWER(8), - UNLAMBDA(9), - GENERATE(10); + WARN(6), + TRANSTYPES(7), + TRANSPATTERNS(8), + LOWER(9), + UNLAMBDA(10), + GENERATE(11); CompileState(int value) { this.value = value; 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 175cceeeb7f..b0b79104def 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -229,7 +229,6 @@ public void analyzeTree(Env<AttrContext> env, TreeMaker make) { new AssignAnalyzer().analyzeTree(env, make); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); - new ThisEscapeAnalyzer(names, syms, types, rs, log, lint).analyzeTree(env); } public void analyzeLambda(Env<AttrContext> env, JCLambda that, TreeMaker make, boolean speculative) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index e1bf92a7f7b..77ddd5c6583 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,7 @@ import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; @@ -140,8 +141,17 @@ * <li>We assume that native methods do not leak. * <li>We don't try to follow {@code super()} invocations; that's for the superclass analysis to handle. * </ul> + * + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> */ -class ThisEscapeAnalyzer extends TreeScanner { +public class ThisEscapeAnalyzer extends TreeScanner { + + protected static final Context.Key<ThisEscapeAnalyzer> contextKey = new Context.Key<>(); + +// Other singletons we utilize private final Names names; private final Symtab syms; @@ -211,15 +221,24 @@ class ThisEscapeAnalyzer extends TreeScanner { */ private RefSet<Ref> refs; -// Constructor +// Access - ThisEscapeAnalyzer(Names names, Symtab syms, Types types, Resolve rs, Log log, Lint lint) { - this.names = names; - this.syms = syms; - this.types = types; - this.rs = rs; - this.log = log; - this.lint = lint; + public static ThisEscapeAnalyzer instance(Context context) { + ThisEscapeAnalyzer instance = context.get(contextKey); + if (instance == null) + instance = new ThisEscapeAnalyzer(context); + return instance; + } + + @SuppressWarnings("this-escape") + protected ThisEscapeAnalyzer(Context context) { + context.put(contextKey, this); + names = Names.instance(context); + log = Log.instance(context); + syms = Symtab.instance(context); + types = Types.instance(context); + rs = Resolve.instance(context); + lint = Lint.instance(context); } // @@ -227,6 +246,24 @@ class ThisEscapeAnalyzer extends TreeScanner { // public void analyzeTree(Env<AttrContext> env) { + try { + doAnalyzeTree(env); + } finally { + attrEnv = null; + methodMap.clear(); + nonPublicOuters.clear(); + targetClass = null; + warningList.clear(); + methodClass = null; + callStack.clear(); + invocations.clear(); + pendingWarning = null; + depth = -1; + refs = null; + } + } + + private void doAnalyzeTree(Env<AttrContext> env) { // Sanity check Assert.check(checkInvariants(false, false)); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java index a0b1ef27255..fe4d3d62f3b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1168,7 +1168,7 @@ private Type erasure(Type t) { private Env<AttrContext> env; private static final String statePreviousToFlowAssertMsg = - "The current compile state [%s] of class %s is previous to FLOW"; + "The current compile state [%s] of class %s is previous to WARN"; void translateClass(ClassSymbol c) { Type st = types.supertype(c.type); @@ -1189,7 +1189,7 @@ void translateClass(ClassSymbol c) { * 1) has no compile state being it the most outer class. * We accept this condition for inner classes. * - * 2) has a compile state which is previous to Flow state. + * 2) has a compile state which is previous to WARN state. */ boolean envHasCompState = compileStates.get(myEnv) != null; if (!envHasCompState && c.outermostClass() == c) { @@ -1197,7 +1197,7 @@ void translateClass(ClassSymbol c) { } if (envHasCompState && - CompileState.FLOW.isAfter(compileStates.get(myEnv))) { + CompileState.WARN.isAfter(compileStates.get(myEnv))) { Assert.error(String.format(statePreviousToFlowAssertMsg, compileStates.get(myEnv), myEnv.enclClass.sym)); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java new file mode 100644 index 00000000000..00d1de386db --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/WarningAnalyzer.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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 com.sun.tools.javac.comp; + +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; + +/** This pass checks for various things to warn about. + * It runs after attribution and flow analysis. + * + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ +public class WarningAnalyzer { + + protected static final Context.Key<WarningAnalyzer> contextKey = new Context.Key<>(); + + private final Log log; + private final ThisEscapeAnalyzer thisEscapeAnalyzer; + + public static WarningAnalyzer instance(Context context) { + WarningAnalyzer instance = context.get(contextKey); + if (instance == null) + instance = new WarningAnalyzer(context); + return instance; + } + + @SuppressWarnings("this-escape") + protected WarningAnalyzer(Context context) { + context.put(contextKey, this); + log = Log.instance(context); + thisEscapeAnalyzer = ThisEscapeAnalyzer.instance(context); + } + + public void analyzeTree(Env<AttrContext> env) { + thisEscapeAnalyzer.analyzeTree(env); + } +} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 96cf4049533..05efcf7c041 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -306,6 +306,10 @@ else if (option.equals("class")) */ protected Flow flow; + /** The warning analyzer. + */ + protected WarningAnalyzer warningAnalyzer; + /** The modules visitor */ protected Modules modules; @@ -419,6 +423,7 @@ public JavaCompiler(Context context) { chk = Check.instance(context); gen = Gen.instance(context); flow = Flow.instance(context); + warningAnalyzer = WarningAnalyzer.instance(context); transTypes = TransTypes.instance(context); lower = Lower.instance(context); annotate = Annotate.instance(context); @@ -962,20 +967,20 @@ public void compile(Collection<JavaFileObject> sourceFileObjects, if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) { switch (compilePolicy) { case SIMPLE: - generate(desugar(flow(attribute(todo)))); + generate(desugar(warn(flow(attribute(todo))))); break; case BY_FILE: { Queue<Queue<Env<AttrContext>>> q = todo.groupByFile(); while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) { - generate(desugar(flow(attribute(q.remove())))); + generate(desugar(warn(flow(attribute(q.remove()))))); } } break; case BY_TODO: while (!todo.isEmpty()) - generate(desugar(flow(attribute(todo.remove())))); + generate(desugar(warn(flow(attribute(todo.remove()))))); break; default: @@ -1435,6 +1440,56 @@ protected void flow(Env<AttrContext> env, Queue<Env<AttrContext>> results) { } } + /** + * Check for various things to warn about. + * + * @return the list of attributed parse trees + */ + public Queue<Env<AttrContext>> warn(Queue<Env<AttrContext>> envs) { + ListBuffer<Env<AttrContext>> results = new ListBuffer<>(); + for (Env<AttrContext> env: envs) { + warn(env, results); + } + return stopIfError(CompileState.WARN, results); + } + + /** + * Check for various things to warn about in an attributed parse tree. + */ + public Queue<Env<AttrContext>> warn(Env<AttrContext> env) { + ListBuffer<Env<AttrContext>> results = new ListBuffer<>(); + warn(env, results); + return stopIfError(CompileState.WARN, results); + } + + /** + * Check for various things to warn about in an attributed parse tree. + */ + protected void warn(Env<AttrContext> env, Queue<Env<AttrContext>> results) { + if (compileStates.isDone(env, CompileState.WARN)) { + results.add(env); + return; + } + + if (shouldStop(CompileState.WARN)) + return; + + if (verboseCompilePolicy) + printNote("[warn " + env.enclClass.sym + "]"); + JavaFileObject prev = log.useSource( + env.enclClass.sym.sourcefile != null ? + env.enclClass.sym.sourcefile : + env.toplevel.sourcefile); + try { + warningAnalyzer.analyzeTree(env); + compileStates.put(env, CompileState.WARN); + results.add(env); + } + finally { + log.useSource(prev); + } + } + private TaskEvent newAnalyzeTaskEvent(Env<AttrContext> env) { JCCompilationUnit toplevel = env.toplevel; ClassSymbol sym; @@ -1493,6 +1548,10 @@ protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, return; } + // Ensure the file has reached the WARN state + if (!compileStates.isDone(env, CompileState.WARN)) + warn(env); + /** * Ensure that superclasses of C are desugared before C itself. This is * required for two reasons: (i) as erasure (TransTypes) destroys @@ -1576,8 +1635,8 @@ public void visitSwitchExpression(JCSwitchExpression tree) { ScanNested scanner = new ScanNested(); scanner.scan(env.tree); for (Env<AttrContext> dep: scanner.dependencies) { - if (!compileStates.isDone(dep, CompileState.FLOW)) - desugaredEnvs.put(dep, desugar(flow(attribute(dep)))); + if (!compileStates.isDone(dep, CompileState.WARN)) + desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep))))); } //We need to check for error another time as more classes might diff --git a/test/langtools/tools/javac/6734819/T6734819a.out b/test/langtools/tools/javac/6734819/T6734819a.out index a3ccb07e67e..c29dbde637b 100644 --- a/test/langtools/tools/javac/6734819/T6734819a.out +++ b/test/langtools/tools/javac/6734819/T6734819a.out @@ -1,9 +1,12 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] +[warn Z] [desugar Z] [desugar W] [desugar Y] diff --git a/test/langtools/tools/javac/6734819/T6734819b.out b/test/langtools/tools/javac/6734819/T6734819b.out index 0c9629006df..61c1f31f179 100644 --- a/test/langtools/tools/javac/6734819/T6734819b.out +++ b/test/langtools/tools/javac/6734819/T6734819b.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A] diff --git a/test/langtools/tools/javac/6734819/T6734819c.out b/test/langtools/tools/javac/6734819/T6734819c.out index 1d4cff3212f..6ae56176acb 100644 --- a/test/langtools/tools/javac/6734819/T6734819c.out +++ b/test/langtools/tools/javac/6734819/T6734819c.out @@ -1,7 +1,9 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] T6734819c.java:15:11: compiler.err.unreachable.stmt diff --git a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out index 11cc81304f0..e240208da72 100644 --- a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out +++ b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out @@ -1,4 +1,5 @@ [attribute Explicit] [flow Explicit] +[warn Explicit] [desugar Explicit] [generate code Explicit] diff --git a/test/langtools/tools/javac/policy/test1/byfile.ABD.out b/test/langtools/tools/javac/policy/test1/byfile.ABD.out index dfa86a44132..0710de49c86 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ABD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ABD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/byfile.ACD.out b/test/langtools/tools/javac/policy/test1/byfile.ACD.out index 66534ce00c5..70cc4856557 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ACD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ACD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out index 5b3b8faace7..3296547f0ff 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute B] [flow B] +[warn B] [desugar B] [generate code B] [attribute B1] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out index a29c0880de9..767a9912a05 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute C] [flow C] +[warn C] [desugar C] [generate code C] [attribute C1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.AB.out b/test/langtools/tools/javac/policy/test2/byfile.AB.out index 6d152c873aa..63a51108f36 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.AB.out +++ b/test/langtools/tools/javac/policy/test2/byfile.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.BA.out b/test/langtools/tools/javac/policy/test2/byfile.BA.out index 565ad138615..3c3567043a0 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.BA.out +++ b/test/langtools/tools/javac/policy/test2/byfile.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.AB.out b/test/langtools/tools/javac/policy/test2/bytodo.AB.out index 6d152c873aa..63a51108f36 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.AB.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.BA.out b/test/langtools/tools/javac/policy/test2/bytodo.BA.out index 565ad138615..3c3567043a0 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.BA.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index db679915e08..c5d393a23b3 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public void overridable(C c) {} Path curPath = Path.of("."); List<String> actual = new JavacTask(tb) .options("-XDrawDiagnostics", "-XDdev", - "-XDshould-stop.at=FLOW", "-Xlint:this-escape") + "-XDshould-stop.at=WARN", "-Xlint:this-escape") .sources(code) .outdir(curPath) .run(Expect.FAIL) From f07877c4bfcbb9371f128a458f552aa646babb35 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Tue, 7 Jan 2025 03:39:50 +0000 Subject: [PATCH 39/99] 8346832: runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java fails on RISC-V Reviewed-by: stuefe, fjiang --- .../CompressedCPUSpecificClassSpaceReservation.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java index 574a680aceb..48fc6699fa2 100644 --- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java +++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java @@ -85,15 +85,8 @@ private static void do_test(boolean CDS) throws IOException { output.shouldContain(tryReserveFor16bitMoveIntoQ3); } else if (Platform.isRISCV64()) { output.shouldContain(tryReserveForUnscaled); // unconditionally - if (CDS) { - output.shouldNotContain(tryReserveForZeroBased); - // bits 32..44 - output.shouldContain("reserve_between (range [0x0000000100000000-0x0000100000000000)"); - } else { - output.shouldContain(tryReserveForZeroBased); - // bits 32..44, but not lower than zero-based limit - output.shouldContain("reserve_between (range [0x0000000800000000-0x0000100000000000)"); - } + // bits 32..44 + output.shouldContain("reserve_between (range [0x0000000100000000-0x0000100000000000)"); // bits 44..64 output.shouldContain("reserve_between (range [0x0000100000000000-0xffffffffffffffff)"); } else if (Platform.isS390x()) { From e233465592a5b793e9bbdd323bad78f578fc0a90 Mon Sep 17 00:00:00 2001 From: Matthias Baesken <mbaesken@openjdk.org> Date: Tue, 7 Jan 2025 08:15:12 +0000 Subject: [PATCH 40/99] 8345676: [ubsan] ProcessImpl_md.c:561:40: runtime error: applying zero offset to null pointer on macOS aarch64 Reviewed-by: rriggs --- src/java.base/unix/native/libjava/ProcessImpl_md.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.base/unix/native/libjava/ProcessImpl_md.c b/src/java.base/unix/native/libjava/ProcessImpl_md.c index 506b33aae96..5a3a5cd088a 100644 --- a/src/java.base/unix/native/libjava/ProcessImpl_md.c +++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c @@ -558,7 +558,9 @@ spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) return -1; } offset = copystrings(buf, 0, &c->argv[0]); - offset = copystrings(buf, offset, &c->envv[0]); + if (c->envv != NULL) { + offset = copystrings(buf, offset, &c->envv[0]); + } if (c->pdir != NULL) { if (sp.dirlen > 0) { memcpy(buf+offset, c->pdir, sp.dirlen); From 355190bdd8601dc85c2be0ff50c5447b8b054e38 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Tue, 7 Jan 2025 10:34:18 +0000 Subject: [PATCH 41/99] 8346573: Can't use custom default file system provider with custom system class loader Reviewed-by: mkartashev, bpb --- .../classes/java/nio/file/FileSystems.java | 27 +++++++------ .../nio/file/spi/CustomSystemClassLoader.java | 40 +++++++++++++++++++ .../java/nio/file/spi/SetDefaultProvider.java | 17 +++++++- 3 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 test/jdk/java/nio/file/spi/CustomSystemClassLoader.java diff --git a/src/java.base/share/classes/java/nio/file/FileSystems.java b/src/java.base/share/classes/java/nio/file/FileSystems.java index ab0538a1d41..f60f798c6e2 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystems.java +++ b/src/java.base/share/classes/java/nio/file/FileSystems.java @@ -34,6 +34,7 @@ import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import jdk.internal.loader.ClassLoaders; import jdk.internal.misc.VM; import sun.nio.fs.DefaultFileSystemProvider; @@ -112,11 +113,9 @@ private static FileSystemProvider getDefaultProvider() { if (propValue != null) { for (String cn: propValue.split(",")) { try { - Class<?> c = Class - .forName(cn, true, ClassLoader.getSystemClassLoader()); - Constructor<?> ctor = c - .getDeclaredConstructor(FileSystemProvider.class); - provider = (FileSystemProvider)ctor.newInstance(provider); + Class<?> c = Class.forName(cn, true, ClassLoaders.appClassLoader()); + Constructor<?> ctor = c.getDeclaredConstructor(FileSystemProvider.class); + provider = (FileSystemProvider) ctor.newInstance(provider); // must be "file" if (!provider.getScheme().equals("file")) @@ -146,13 +145,17 @@ private static FileSystemProvider getDefaultProvider() { * is invoked to create the default file system. * * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider} - * is defined then it is taken to be a list of one or more fully-qualified - * names of concrete provider classes identified by the URI scheme - * {@code "file"}. Where the property is a list of more than one name then - * the names are separated by a comma. Each class is loaded, using the system - * class loader, and instantiated by invoking a one argument constructor - * whose formal parameter type is {@code FileSystemProvider}. The providers - * are loaded and instantiated in the order they are listed in the property. + * is defined then it is taken to be a list of one or more fully-qualified names + * of concrete provider classes identified by the URI scheme {@code "file"}. + * If the property is a list of more than one name then the names are separated + * by a comma character. Each provider class is a {@code public} class with a + * {@code public} constructor that has one formal parameter of type {@code + * FileSystemProvider}. If the provider class is in a named module then the module + * exports the package containing the provider class to at least {@code java.base}. + * Each provider class is loaded, using the + * {@linkplain ClassLoader#getSystemClassLoader() default system class loader}, + * and instantiated by invoking the constructor. The providers are loaded and + * instantiated in the order they are listed in the property. * If this process fails or a provider's scheme is not equal to {@code "file"} * then an unspecified error is thrown. URI schemes are normally compared * without regard to case but for the default provider, the scheme is diff --git a/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java new file mode 100644 index 00000000000..8ad9a41c5fd --- /dev/null +++ b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; + +/** + * Use by tests in SetDefaultProvider to test startup with a custom default file system + * provider and a custom system class loader. + */ + +public class CustomSystemClassLoader extends ClassLoader { + public CustomSystemClassLoader(ClassLoader parent) { + super(parent); + + // use default file system + FileSystem fs = FileSystems.getDefault(); + var path = fs.getPath("foo"); + } +} \ No newline at end of file diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index ea154b5952e..f4486885b6a 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -23,10 +23,10 @@ /* * @test - * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 8346573 * @modules jdk.jartool jdk.jlink * @library /test/lib - * @build testfsp/* testapp/* + * @build testfsp/* testapp/* CustomSystemClassLoader * @run junit SetDefaultProvider * @summary Runs tests with -Djava.nio.file.spi.DefaultFileSystemProvider set on * the command line to override the default file system provider @@ -204,6 +204,19 @@ void testPatchedAppOnModulePath2() throws Exception { "-m", TESTAPP + "/" + TESTAPP_MAIN); } + /** + * Test file system provider on class path in conjunction with a custom system + * class loader that uses the file system API during its initialization. + */ + @Test + void testCustomSystemClassLoader() throws Exception { + String testClasses = System.getProperty("test.classes"); + exec(SET_DEFAULT_FSP, + "-Djava.system.class.loader=CustomSystemClassLoader", + "-cp", ofClasspath(testClasses, TESTFSP_CLASSES, TESTAPP_CLASSES), + TESTAPP_MAIN); + } + /** * Returns the directory containing the classes for the given module. */ From 648a4ab4a187d957293c5cc0cad2d98fce5ac0a3 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Tue, 7 Jan 2025 10:54:52 +0000 Subject: [PATCH 42/99] 8346868: RISC-V: compiler/sharedstubs tests fail after JDK-8332689 Reviewed-by: rehn, mli --- .../jtreg/compiler/sharedstubs/SharedTrampolineTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java index f1e4d18b93a..0ce62954db7 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedTrampolineTest.java @@ -30,7 +30,7 @@ * * @requires vm.compiler2.enabled * @requires vm.opt.TieredCompilation == null - * @requires os.arch=="aarch64" | os.arch=="riscv64" + * @requires os.arch=="aarch64" * @requires vm.debug * * @run driver compiler.sharedstubs.SharedTrampolineTest -XX:-TieredCompilation From 99a094f68a455f76dd5905e5d45acb446ed6d47a Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Tue, 7 Jan 2025 12:32:31 +0000 Subject: [PATCH 43/99] 8347000: Bug in com/sun/net/httpserver/bugs/B6361557.java test Reviewed-by: msheppar, michaelm --- test/jdk/com/sun/net/httpserver/bugs/B6361557.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java index 57e831ec693..66094230d69 100644 --- a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java +++ b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public void handle (HttpExchange t) } final static String request = "GET /test/foo.html HTTP/1.1\r\nContent-length: 0\r\n\r\n"; - final static ByteBuffer requestBuf = ByteBuffer.allocate(64).put(request.getBytes()); + final static ByteBuffer requestBuf = ByteBuffer.wrap(request.getBytes()); public static void main (String[] args) throws Exception { Handler handler = new Handler(); From d13e495263c49d8d4ebdce78395d973980519ea9 Mon Sep 17 00:00:00 2001 From: Joachim Kern <jkern@openjdk.org> Date: Tue, 7 Jan 2025 13:54:09 +0000 Subject: [PATCH 44/99] 8211851: (ch) java/nio/channels/AsynchronousSocketChannel/StressLoopback.java times out (aix) Reviewed-by: mdoerr, varadam --- .../aix/classes/sun/nio/ch/AixPollPort.java | 71 ++++++++++--------- test/jdk/ProblemList.txt | 2 - 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java b/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java index 4f5bda557c6..b8610655b6c 100644 --- a/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java +++ b/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 SAP SE. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. 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 @@ -26,15 +26,17 @@ package sun.nio.ch; -import java.nio.channels.spi.AsynchronousChannelProvider; -import sun.nio.ch.Pollset; +import java.io.FileDescriptor; import java.io.IOException; -import java.util.HashSet; -import java.util.Iterator; +import java.nio.channels.spi.AsynchronousChannelProvider; import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.RejectedExecutionException; +import java.util.HashSet; +import java.util.Iterator; +import sun.nio.ch.IOUtil; +import sun.nio.ch.Pollset; /** * AsynchronousChannelGroup implementation based on the AIX pollset framework. @@ -141,6 +143,8 @@ static class ControlEvent { sv = new int[2]; try { Pollset.socketpair(sv); + // make the reading part of the socket nonblocking, so the drain (drain_all) method works + IOUtil.configureBlocking(IOUtil.newFD(sv[0]), false); // register one end with pollset Pollset.pollsetCtl(pollset, Pollset.PS_ADD, sv[0], Net.POLLIN); } catch (IOException x) { @@ -271,23 +275,21 @@ private void queueControlEvent(ControlEvent ev) { // Process all events currently stored in the control queue. private void processControlQueue() { - synchronized (controlQueue) { - // On Aix it is only possible to set the event - // bits on the first call of pollsetCtl. Later - // calls only add bits, but cannot remove them. - // Therefore, we always remove the file - // descriptor ignoring the error and then add it. - Iterator<ControlEvent> iter = controlQueue.iterator(); - while (iter.hasNext()) { - ControlEvent ev = iter.next(); - Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, ev.fd(), 0); - if (!ev.removeOnly()) { - ev.setError(Pollset.pollsetCtl(pollset, Pollset.PS_MOD, ev.fd(), ev.events())); - } - iter.remove(); + // On Aix it is only possible to set the event + // bits on the first call of pollsetCtl. Later + // calls only add bits, but cannot remove them. + // Therefore, we always remove the file + // descriptor ignoring the error and then add it. + Iterator<ControlEvent> iter = controlQueue.iterator(); + while (iter.hasNext()) { + ControlEvent ev = iter.next(); + Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, ev.fd(), 0); + if (!ev.removeOnly()) { + ev.setError(Pollset.pollsetCtl(pollset, Pollset.PS_MOD, ev.fd(), ev.events())); } - controlQueue.notifyAll(); + iter.remove(); } + controlQueue.notifyAll(); } /* @@ -306,8 +308,21 @@ private Event poll() throws IOException { int n; controlLock.lock(); try { - n = Pollset.pollsetPoll(pollset, address, + int m; + m = n = Pollset.pollsetPoll(pollset, address, MAX_EVENTS_TO_POLL, Pollset.PS_NO_TIMEOUT); + while (m-- > 0) { + long eventAddress = Pollset.getEvent(address, m); + int fd = Pollset.getDescriptor(eventAddress); + + // To emulate one shot semantic we need to remove + // the file descriptor here. + if (fd != sp[0] && fd != ctlSp[0]) { + synchronized (controlQueue) { + Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, fd, 0); + } + } + } } finally { controlLock.unlock(); } @@ -323,14 +338,6 @@ private Event poll() throws IOException { long eventAddress = Pollset.getEvent(address, n); int fd = Pollset.getDescriptor(eventAddress); - // To emulate one shot semantic we need to remove - // the file descriptor here. - if (fd != sp[0] && fd != ctlSp[0]) { - synchronized (controlQueue) { - Pollset.pollsetCtl(pollset, Pollset.PS_DELETE, fd, 0); - } - } - // wakeup if (fd == sp[0]) { if (wakeupCount.decrementAndGet() == 0) { @@ -350,7 +357,7 @@ private Event poll() throws IOException { // wakeup to process control event if (fd == ctlSp[0]) { synchronized (controlQueue) { - Pollset.drain1(ctlSp[0]); + IOUtil.drain(ctlSp[0]); processControlQueue(); } if (n > 0) { diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index e9d7c769523..6a2ab0d1e04 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -583,8 +583,6 @@ java/net/Socket/asyncClose/Race.java 8317801 aix-ppc6 # jdk_nio -java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64 - java/nio/channels/Channels/SocketChannelStreams.java 8317838 aix-ppc64 java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8308807,8144003 aix-ppc64,macosx-all From 2111269171b1ccf3224027f524e1e91cd5045693 Mon Sep 17 00:00:00 2001 From: Tobias Holenstein <tholenstein@openjdk.org> Date: Tue, 7 Jan 2025 14:30:05 +0000 Subject: [PATCH 45/99] 8345041: IGV: Free Placement Mode in IGV Layout Reviewed-by: chagedorn, epeter, rcastanedalo --- .../FreeInteractiveLayoutManager.java | 384 ++++++++++++++++++ .../HierarchicalLayoutManager.java | 5 + .../igv/hierarchicallayout/LayoutGraph.java | 61 ++- .../igv/hierarchicallayout/LayoutMover.java | 2 + .../igv/hierarchicallayout/LayoutNode.java | 16 +- .../sun/hotspot/igv/settings/Settings.java | 1 + .../sun/hotspot/igv/view/DiagramScene.java | 108 ++++- .../hotspot/igv/view/DiagramViewModel.java | 15 +- .../hotspot/igv/view/EditorTopComponent.java | 5 + .../view/actions/EnableFreeLayoutAction.java | 49 +++ .../hotspot/igv/view/widgets/LineWidget.java | 52 ++- .../sun/hotspot/igv/view/images/dynamic.png | Bin 0 -> 2218 bytes 12 files changed, 670 insertions(+), 28 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java new file mode 100644 index 00000000000..7aec57ec2a0 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/FreeInteractiveLayoutManager.java @@ -0,0 +1,384 @@ +/* + * 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 com.sun.hotspot.igv.hierarchicallayout; + +import static com.sun.hotspot.igv.hierarchicallayout.LayoutNode.LAYOUT_NODE_DEGREE_COMPARATOR; +import com.sun.hotspot.igv.layout.Link; +import com.sun.hotspot.igv.layout.Vertex; +import java.awt.Point; +import java.util.*; + +public class FreeInteractiveLayoutManager extends LayoutManager implements LayoutMover { + + private boolean cutEdges = false; + + private static final int LINE_OFFSET = 10; + + private Map<Vertex, LayoutNode> layoutNodes; + + private LayoutGraph prevGraph; + + private final Random random = new Random(42); + + // Constants for offsets and displacements + private static final int MAX_OFFSET_AROUND_NEIGHBOR = 200; // Max offset for random positioning around a neighbor + private static final int MAX_OFFSET_AROUND_ORIGIN = 200; // Max offset for random positioning around origin + private static final int DISPLACEMENT_RANGE_BARYCENTER = 100; // Displacement range for barycenter calculation + private static final int DISPLACEMENT_RANGE_SINGLE = 200; + + // Create a comparator to sort nodes by the number of unassigned neighbors + private final Comparator<LayoutNode> LeastUnassignedNeighborsComparator = Comparator.comparingInt(node -> { + Vertex vertex = node.getVertex(); + int unassignedNeighbors = 0; + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (!layoutNodes.containsKey(neighborVertex)) { + unassignedNeighbors++; + } + } + return unassignedNeighbors; + }); + + public FreeInteractiveLayoutManager() { + this.cutEdges = false; + this.layoutNodes = new HashMap<>(); + this.prevGraph = null; + } + + @Override + public void moveLink(Point linkPos, int shiftX) {} + + @Override + public void moveVertices(Set<? extends Vertex> movedVertices) { + for (Vertex v : movedVertices) { + moveVertex(v); + } + } + + @Override + public void moveVertex(Vertex vertex) { + assert prevGraph.containsVertex(vertex); + LayoutNode layoutNode = layoutNodes.get(vertex); + layoutNode.setX(vertex.getPosition().x); + layoutNode.setY(vertex.getPosition().y); + for (Link link : prevGraph.getAllLinks(vertex)) { + setLinkControlPoints(link); + } + } + + @Override + public boolean isFreeForm() { + return true; + } + + public void setCutEdges(boolean enable) { + this.cutEdges = enable; + } + + @Override + public void doLayout(LayoutGraph graph) { + prevGraph = graph; + if (layoutNodes.isEmpty()) { + HierarchicalLayoutManager manager = new HierarchicalLayoutManager(); + manager.doLayout(graph); + for (LayoutNode node : graph.getLayoutNodes()) { + node.initSize(); + layoutNodes.put(node.getVertex(), node); + } + graph.clearLayout(); + } else { + // add new vertices to layoutNodes, x/y from barycenter + List<LayoutNode> newLayoutNodes = new ArrayList<>(); + + // Set up layout nodes for each vertex + for (Vertex vertex : prevGraph.getVertices()) { + if (!layoutNodes.containsKey(vertex)) { + LayoutNode addedNode = new LayoutNode(vertex); + addedNode.initSize(); + newLayoutNodes.add(addedNode); + } + } + + positionNewLayoutNodes(newLayoutNodes); + } + + // Write back vertices + for (Vertex vertex : prevGraph.getVertices()) { + LayoutNode layoutNode = layoutNodes.get(vertex); + layoutNode.setVertex(vertex); + vertex.setPosition(new Point(layoutNode.getLeft(), layoutNode.getTop())); + } + + // Write back links + for (Link link : prevGraph.getLinks()) { + setLinkControlPoints(link); + } + } + + public void positionNewLayoutNodes(List<LayoutNode> newLayoutNodes) { + // First pass: Initial positioning based on unassigned neighbors + newLayoutNodes.sort(LeastUnassignedNeighborsComparator); + + for (LayoutNode node : newLayoutNodes) { + Vertex vertex = node.getVertex(); + + // Gather assigned neighbors + List<LayoutNode> assignedNeighbors = new ArrayList<>(); + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (layoutNodes.containsKey(neighborVertex)) { + assignedNeighbors.add(layoutNodes.get(neighborVertex)); + } + } + + if (!assignedNeighbors.isEmpty()) { + if (assignedNeighbors.size() == 1) { + // Single neighbor: position around the neighbor + setPositionAroundSingleNode(node, assignedNeighbors.get(0), DISPLACEMENT_RANGE_SINGLE); + } else { + // Multiple neighbors: Calculate barycenter with displacement + calculateBarycenterWithDisplacement(node, assignedNeighbors, DISPLACEMENT_RANGE_BARYCENTER); + } + } else { + // No neighbors: Position randomly around (0, 0) + setRandomPositionAroundOrigin(node, random); + } + + // Add the new node to the layout + layoutNodes.put(vertex, node); + } + + // Second pass: Refine positions based on neighbor degree + newLayoutNodes.sort(LAYOUT_NODE_DEGREE_COMPARATOR.reversed()); + + // Collect all nodes (existing and new) + Collection<LayoutNode> allNodes = layoutNodes.values(); + + for (LayoutNode node : newLayoutNodes) { + Vertex vertex = node.getVertex(); + + // Gather assigned neighbors + List<LayoutNode> assignedNeighbors = new ArrayList<>(); + for (Vertex neighborVertex : prevGraph.getNeighborVertices(vertex)) { + if (layoutNodes.containsKey(neighborVertex)) { + assignedNeighbors.add(layoutNodes.get(neighborVertex)); + } + } + + if (!assignedNeighbors.isEmpty()) { + // Refine position based on force-based method + applyForceBasedAdjustment(node, assignedNeighbors, allNodes); + } + + // Ensure node's position remains updated in the layout + layoutNodes.put(vertex, node); + } + } + + /** + * Applies a force-based adjustment to the position of a given layout node + * based on repulsive forces from all other nodes and attractive forces from its assigned neighbors. + * <p> + * This method simulates a physical system where nodes repel each other to maintain spacing + * and are pulled towards their neighbors to maintain connectivity. The forces are calculated + * using Coulomb's law for repulsion and Hooke's law for attraction. The system iterates for + * a fixed number of iterations to stabilize the position of the node. + * + * @param node The node whose position is being adjusted. + * @param assignedNeighbors A list of neighboring nodes that attract this node. + * @param allNodes A collection of all nodes in the layout, used for repulsive forces. + */ + private void applyForceBasedAdjustment(LayoutNode node, List<LayoutNode> assignedNeighbors, Collection<LayoutNode> allNodes) { + // Constants for force-based adjustment + final int ITERATIONS = 50; // Number of simulation iterations + final double REPULSION_CONSTANT = 1000; // Magnitude of repulsive forces (Coulomb's law) + final double SPRING_CONSTANT = 0.2; // Strength of attractive forces to neighbors (Hooke's law) + final double DAMPING = 0.8; // Factor to reduce displacement and ensure stability + final double IDEAL_LENGTH = 100; // Desired distance between a node and its neighbors + final double MAX_FORCE = 1000; // Upper limit for the magnitude of applied forces + final double CONVERGENCE_THRESHOLD = 0.01; // Force threshold for stopping early + + double posX = node.getX(); + double posY = node.getY(); + double dx = 0, dy = 0; // Displacement + + for (int i = 0; i < ITERATIONS; i++) { + double netForceX = 0; + double netForceY = 0; + + // Repulsive forces from all other nodes + for (LayoutNode otherNode : allNodes) { + if (otherNode == node) continue; // Skip self + + double deltaX = posX - otherNode.getX(); + double deltaY = posY - otherNode.getY(); + double distanceSquared = deltaX * deltaX + deltaY * deltaY; + double distance = Math.sqrt(distanceSquared); + + // Avoid division by zero by introducing a minimum distance + if (distance < 1e-6) { + deltaX = random.nextDouble() * 0.1 - 0.05; + deltaY = random.nextDouble() * 0.1 - 0.05; + distanceSquared = deltaX * deltaX + deltaY * deltaY; + distance = Math.sqrt(distanceSquared); + } + + // Repulsive force (Coulomb's law) + double repulsiveForce = REPULSION_CONSTANT / distanceSquared; + + // Normalize force to prevent large displacements + if (repulsiveForce > MAX_FORCE) repulsiveForce = MAX_FORCE; + + netForceX += (deltaX / distance) * repulsiveForce; + netForceY += (deltaY / distance) * repulsiveForce; + } + + // Attractive forces to assigned neighbors + for (LayoutNode neighbor : assignedNeighbors) { + double deltaX = neighbor.getX() - posX; + double deltaY = neighbor.getY() - posY; + double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + + if (distance < 1e-6) { + deltaX = random.nextDouble() * 0.1 - 0.05; + deltaY = random.nextDouble() * 0.1 - 0.05; + distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + } + + // Attractive force (Hooke's law) + double displacement = distance - IDEAL_LENGTH; + double attractiveForce = SPRING_CONSTANT * displacement; + + if (attractiveForce > MAX_FORCE) attractiveForce = MAX_FORCE; + + netForceX += (deltaX / distance) * attractiveForce; + netForceY += (deltaY / distance) * attractiveForce; + } + + // Apply damping and update displacement + dx = (dx + netForceX) * DAMPING; + dy = (dy + netForceY) * DAMPING; + + // Scale displacement if it's too large + double displacementMagnitude = Math.sqrt(dx * dx + dy * dy); + if (displacementMagnitude > MAX_FORCE) { + dx *= MAX_FORCE / displacementMagnitude; + dy *= MAX_FORCE / displacementMagnitude; + } + + // Update position + posX += dx; + posY += dy; + + // Stop early if the net force is negligible + if (Math.abs(netForceX) < CONVERGENCE_THRESHOLD && Math.abs(netForceY) < CONVERGENCE_THRESHOLD) { + break; + } + + // Validate position to avoid invalid or extreme values + if (Double.isNaN(posX) || Double.isInfinite(posX) || Double.isNaN(posY) || Double.isInfinite(posY)) { + posX = node.getX(); // Reset to original position + posY = node.getY(); + break; + } + } + + // Set final position + node.setX((int) Math.round(posX)); + node.setY((int) Math.round(posY)); + } + + // Utility method: position around a given node + private void setPositionAroundSingleNode(LayoutNode node, LayoutNode neighbor, int displacement) { + boolean neighborIsPredecessor = prevGraph.isPredecessorVertex(node.getVertex(), neighbor.getVertex()); + boolean neighborIsSuccessor = prevGraph.isSuccessorVertex(node.getVertex(), neighbor.getVertex()); + + int shiftY = 0; + if (neighborIsPredecessor) { + shiftY = displacement; + } else if (neighborIsSuccessor) { + shiftY = -displacement; + } + assert shiftY != 0; + + int randomY = neighbor.getY() + random.nextInt(MAX_OFFSET_AROUND_NEIGHBOR + 1) + shiftY; + int randomX = neighbor.getX() + random.nextInt(MAX_OFFSET_AROUND_NEIGHBOR + 1); + node.setX(randomX); + node.setY(randomY); + } + + // Utility method: Random position around origin + private void setRandomPositionAroundOrigin(LayoutNode node, Random random) { + int randomX = random.nextInt(MAX_OFFSET_AROUND_ORIGIN + 1); + int randomY = random.nextInt(MAX_OFFSET_AROUND_ORIGIN + 1); + node.setX(randomX); + node.setY(randomY); + } + + // Utility method: Calculate barycenter with displacement + private void calculateBarycenterWithDisplacement(LayoutNode node, List<LayoutNode> neighbors, int displacementRange) { + double barycenterX = 0, barycenterY = 0; + for (LayoutNode neighbor : neighbors) { + barycenterX += neighbor.getX(); + barycenterY += neighbor.getY(); + } + barycenterX /= neighbors.size(); + barycenterY /= neighbors.size(); + + // Add random displacement for slight separation + int displacementX = random.nextInt(displacementRange + 1); + int displacementY = random.nextInt(displacementRange + 1); + node.setX((int) barycenterX + displacementX); + node.setY((int) barycenterY + displacementY); + } + + /** + * Sets control points for a given link based on its start and end layout nodes. + * <p> + * Calculates the start and end points, applies offsets for curvature, and updates + * the link's control points. + * + * @param link The link to process. + */ + private void setLinkControlPoints(Link link) { + if (link.getFrom().getVertex() == link.getTo().getVertex()) return; // Skip self-links + + LayoutNode from = layoutNodes.get(link.getFrom().getVertex()); + from.setVertex(link.getFrom().getVertex()); + from.updateSize(); + + LayoutNode to = layoutNodes.get(link.getTo().getVertex()); + to.setVertex(link.getTo().getVertex()); + to.updateSize(); + + Point startPoint = new Point(from.getLeft() + link.getFrom().getRelativePosition().x, from.getBottom()); + Point endPoint = new Point(to.getLeft() + link.getTo().getRelativePosition().x, to.getTop()); + + List<Point> controlPoints = new ArrayList<>(); + controlPoints.add(startPoint); + controlPoints.add(new Point(startPoint.x, startPoint.y + LINE_OFFSET)); + controlPoints.add(new Point(endPoint.x, endPoint.y - LINE_OFFSET)); + controlPoints.add(endPoint); + + link.setControlPoints(controlPoints); + } +} diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java index e2d6bf18039..cb9487ae828 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java @@ -53,6 +53,11 @@ public void setCutEdges(boolean enable) { maxLayerLength = enable ? 10 : -1; } + @Override + public boolean isFreeForm() { + return false; + } + @Override public void doLayout(LayoutGraph layoutGraph) { layoutGraph.initializeLayout(); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java index 64d96412467..956d72924b9 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 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 @@ -169,7 +169,7 @@ public Collection<LayoutNode> getLayoutNodes() { * Retrieves a combined list of all nodes in the graph, * including both layout nodes and dummy nodes. * - * @return An unmodifiable list containing all nodes in the graph. + * @return An unmodifiable list containing all nodes in the graph */ public List<LayoutNode> getAllNodes() { List<LayoutNode> allNodes = new ArrayList<>(); @@ -447,6 +447,63 @@ public List<Link> getOutputLinks(Vertex vertex) { return outputLinks; } + /** + * Checks if the given predecessorVertex is a direct predecessor of the specified vertex. + * + * @param vertex The vertex to check for predecessors. + * @param predecessorVertex The vertex to verify as a predecessor of the given vertex. + * @return true if predecessorVertex is a direct predecessor of vertex, false otherwise. + */ + public boolean isPredecessorVertex(Vertex vertex, Vertex predecessorVertex) { + for (Port inputPort : inputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link inputLink : portLinks.getOrDefault(inputPort, Collections.emptySet())) { + Vertex fromVertex = inputLink.getFrom().getVertex(); + if (fromVertex.equals(predecessorVertex)) { + return true; + } + } + } + return false; + } + + /** + * Checks if the given successorVertex is a direct successor of the specified vertex. + * + * @param vertex The vertex to check for successors. + * @param successorVertex The vertex to verify as a successor of the given vertex. + * @return true if successorVertex is a direct successor of vertex, false otherwise. + */ + public boolean isSuccessorVertex(Vertex vertex, Vertex successorVertex) { + for (Port outputPort : outputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link outputLink : portLinks.getOrDefault(outputPort, Collections.emptySet())) { + Vertex toVertex = outputLink.getTo().getVertex(); + if (toVertex.equals(successorVertex)) { + return true; + } + } + } + return false; + } + + public List<Vertex> getNeighborVertices(Vertex vertex) { + List<Vertex> neighborVertices = new ArrayList<>(); + for (Port inputPort : inputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link inputLink : portLinks.getOrDefault(inputPort, Collections.emptySet())) { + Vertex fromVertex = inputLink.getFrom().getVertex(); + assert fromVertex != null; + neighborVertices.add(fromVertex); + } + } + for (Port outputPort : outputPorts.getOrDefault(vertex, Collections.emptySet())) { + for (Link outputLink : portLinks.getOrDefault(outputPort, Collections.emptySet())) { + Vertex toVertex = outputLink.getTo().getVertex(); + assert toVertex != null; + neighborVertices.add(toVertex); + } + } + return neighborVertices; + } + public List<Link> getAllLinks(Vertex vertex) { List<Link> allLinks = new ArrayList<>(); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java index 19f24f1f7e6..48599d78d75 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutMover.java @@ -49,5 +49,7 @@ public interface LayoutMover { * @param movedVertex The vertex to be moved. */ void moveVertex(Vertex movedVertex); + + boolean isFreeForm(); } diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java index 9ad0c70b912..2816115080e 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutNode.java @@ -107,12 +107,7 @@ public LayoutNode() { this(null); } - /** - * Initializes the size and margins of the node. - * If the node represents a real vertex, it uses the vertex's size. - * Dummy nodes use default dimensions. - */ - public void initSize() { + public void updateSize() { if (vertex == null) { height = DUMMY_HEIGHT; width = DUMMY_WIDTH; @@ -121,6 +116,15 @@ public void initSize() { height = size.height; width = size.width; } + } + + /** + * Initializes the size and margins of the node. + * If the node represents a real vertex, it uses the vertex's size. + * Dummy nodes use default dimensions. + */ + public void initSize() { + updateSize(); topMargin = 0; bottomMargin = 0; leftMargin = 0; diff --git a/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java b/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java index 41af4a1d262..480fb43ea5b 100644 --- a/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java +++ b/src/utils/IdealGraphVisualizer/Settings/src/main/java/com/sun/hotspot/igv/settings/Settings.java @@ -37,6 +37,7 @@ public static class DefaultView { public static final int CLUSTERED_SEA_OF_NODES = 1; public static final int CONTROL_FLOW_GRAPH = 2; public static final int STABLE_SEA_OF_NODES = 3; + public static final int INTERACTIVE_FREE_NODES = 4; } public static final String NODE_TEXT = "nodeText"; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 90d5e0ac424..99ae3380bb3 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -89,6 +89,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl private final Map<OutputSlot, Set<LineWidget>> outputSlotToLineWidget = new HashMap<>(); private final Map<InputSlot, Set<LineWidget>> inputSlotToLineWidget = new HashMap<>(); + private final FreeInteractiveLayoutManager freeInteractiveLayoutManager; private final HierarchicalStableLayoutManager hierarchicalStableLayoutManager; private HierarchicalLayoutManager seaLayoutManager; private LayoutMover layoutMover; @@ -511,6 +512,7 @@ public void ancestorResized(HierarchyEvent e) { } }); + freeInteractiveLayoutManager = new FreeInteractiveLayoutManager(); hierarchicalStableLayoutManager = new HierarchicalStableLayoutManager(); seaLayoutManager = new HierarchicalLayoutManager(); @@ -643,6 +645,8 @@ public void movementStarted(Widget widget) { widget.bringToFront(); startLayerY = widget.getLocation().y; hasMoved = false; // Reset the movement flag + if (layoutMover.isFreeForm()) return; + Set<Figure> selectedFigures = model.getSelectedFigures(); if (selectedFigures.size() == 1) { Figure selectedFigure = selectedFigures.iterator().next(); @@ -702,8 +706,12 @@ public void setNewLocation(Widget widget, Point location) { hasMoved = true; // Mark that a movement occurred int shiftX = location.x - widget.getLocation().x; - int shiftY = magnetToStartLayerY(widget, location); - + int shiftY; + if (layoutMover.isFreeForm()) { + shiftY = location.y - widget.getLocation().y; + } else { + shiftY = magnetToStartLayerY(widget, location); + } List<Figure> selectedFigures = new ArrayList<>( model.getSelectedFigures()); selectedFigures.sort(Comparator.comparingInt(f -> f.getPosition().x)); for (Figure figure : selectedFigures) { @@ -713,12 +721,15 @@ public void setNewLocation(Widget widget, Point location) { if (inputSlotToLineWidget.containsKey(inputSlot)) { for (LineWidget lw : inputSlotToLineWidget.get(inputSlot)) { assert lw != null; - Point toPt = lw.getTo(); Point fromPt = lw.getFrom(); - if (toPt != null && fromPt != null) { - int xTo = toPt.x + shiftX; - int yTo = toPt.y + shiftY; - lw.setTo(new Point(xTo, yTo)); + Point toPt = lw.getTo(); + if (toPt == null || fromPt == null) { + continue; + } + int xTo = toPt.x + shiftX; + int yTo = toPt.y + shiftY; + lw.setTo(new Point(xTo, yTo)); + if (!layoutMover.isFreeForm()) { lw.setFrom(new Point(fromPt.x + shiftX, fromPt.y)); LineWidget pred = lw.getPredecessor(); pred.setTo(new Point(pred.getTo().x + shiftX, pred.getTo().y)); @@ -735,10 +746,13 @@ public void setNewLocation(Widget widget, Point location) { assert lw != null; Point fromPt = lw.getFrom(); Point toPt = lw.getTo(); - if (toPt != null && fromPt != null) { - int xFrom = fromPt.x + shiftX; - int yFrom = fromPt.y + shiftY; - lw.setFrom(new Point(xFrom, yFrom)); + if (toPt == null || fromPt == null) { + continue; + } + int xFrom = fromPt.x + shiftX; + int yFrom = fromPt.y + shiftY; + lw.setFrom(new Point(xFrom, yFrom)); + if (!layoutMover.isFreeForm()) { lw.setTo(new Point(toPt.x + shiftX, toPt.y)); for (LineWidget succ : lw.getSuccessors()) { succ.setFrom(new Point(succ.getFrom().x + shiftX, succ.getFrom().y)); @@ -753,10 +767,12 @@ public void setNewLocation(Widget widget, Point location) { ActionFactory.createDefaultMoveProvider().setNewLocation(fw, newLocation); } - FigureWidget fw = getWidget(selectedFigures.iterator().next()); - pointerWidget.setVisible(true); - Point newLocation = new Point(fw.getLocation().x + shiftX -3, fw.getLocation().y + shiftY); - ActionFactory.createDefaultMoveProvider().setNewLocation(pointerWidget, newLocation); + if (selectedFigures.size() == 1 && !layoutMover.isFreeForm()) { + FigureWidget fw = getWidget(selectedFigures.iterator().next()); + pointerWidget.setVisible(true); + Point newLocation = new Point(fw.getLocation().x + shiftX -3, fw.getLocation().y + shiftY); + ActionFactory.createDefaultMoveProvider().setNewLocation(pointerWidget, newLocation); + } connectionLayer.revalidate(); connectionLayer.repaint(); } @@ -834,7 +850,9 @@ private void relayout() { Set<Figure> visibleFigures = getVisibleFigures(); Set<Connection> visibleConnections = getVisibleConnections(); - if (getModel().getShowStableSea()) { + if (getModel().getShowFreeInteractive()) { + doFreeInteractiveLayout(visibleFigures, visibleConnections); + } else if (getModel().getShowStableSea()) { doStableSeaLayout(visibleFigures, visibleConnections); } else if (getModel().getShowSea()) { doSeaLayout(visibleFigures, visibleConnections); @@ -904,6 +922,12 @@ private boolean isVisibleFigureConnection(FigureConnection figureConnection) { return w1.isVisible() && w2.isVisible(); } + private void doFreeInteractiveLayout(Set<Figure> visibleFigures, Set<Connection> visibleConnections) { + layoutMover = freeInteractiveLayoutManager; + freeInteractiveLayoutManager.setCutEdges(model.getCutEdges()); + freeInteractiveLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures)); + } + private void doStableSeaLayout(Set<Figure> visibleFigures, Set<Connection> visibleConnections) { layoutMover = null; boolean enable = model.getCutEdges(); @@ -1108,6 +1132,52 @@ private void processOutputSlot(OutputSlot outputSlot, List<FigureConnection> con } } + private void processFreeForm(OutputSlot outputSlot, List<FigureConnection> connections) { + for (FigureConnection connection : connections) { + if (isVisibleFigureConnection(connection)) { + boolean isBold = false; + boolean isDashed = true; + boolean isVisible = true; + if (connection.getStyle() == Connection.ConnectionStyle.BOLD) { + isBold = true; + } else if (connection.getStyle() == Connection.ConnectionStyle.INVISIBLE) { + isVisible = false; + } + if (connection.getStyle() != Connection.ConnectionStyle.DASHED) { + isDashed = false; + } + + + List<Point> controlPoints = connection.getControlPoints(); + if (controlPoints.size() <= 2) continue; + Point firstPoint = controlPoints.get(0); // First point + Point lastPoint = controlPoints.get(controlPoints.size() - 1); // Last point + List<FigureConnection> connectionList = new ArrayList<>(Collections.singleton(connection)); + LineWidget line = new LineWidget(this, outputSlot, connectionList, firstPoint, lastPoint, null, isBold, isDashed); + line.setFromControlYOffset(50); + line.setToControlYOffset(-50); + line.setVisible(isVisible); + connectionLayer.addChild(line); + + addObject(new ConnectionSet(connectionList), line); + line.getActions().addAction(hoverAction); + + if (outputSlotToLineWidget.containsKey(outputSlot)) { + outputSlotToLineWidget.get(outputSlot).add(line); + } else { + outputSlotToLineWidget.put(outputSlot, new HashSet<>(Collections.singleton(line))); + } + + InputSlot inputSlot = connection.getInputSlot(); + if (inputSlotToLineWidget.containsKey(inputSlot)) { + inputSlotToLineWidget.get(inputSlot).add(line); + } else { + inputSlotToLineWidget.put(inputSlot, new HashSet<>(Collections.singleton(line))); + } + } + } + } + private void processBlockConnection(BlockConnection blockConnection) { boolean isDashed = blockConnection.getStyle() == Connection.ConnectionStyle.DASHED; boolean isBold = blockConnection.getStyle() == Connection.ConnectionStyle.BOLD; @@ -1281,7 +1351,11 @@ private void rebuildConnectionLayer() { for (Figure figure : getModel().getDiagram().getFigures()) { for (OutputSlot outputSlot : figure.getOutputSlots()) { List<FigureConnection> connectionList = new ArrayList<>(outputSlot.getConnections()); - processOutputSlot(outputSlot, connectionList, 0, null, null); + if (layoutMover != null && layoutMover.isFreeForm()) { + processFreeForm(outputSlot, connectionList); + } else { + processOutputSlot(outputSlot, connectionList, 0, null, null); + } } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index e6cdbebbe52..710c5c125f6 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -63,6 +63,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private final ChangedEvent<DiagramViewModel> selectedNodesChangedEvent = new ChangedEvent<>(this); private final ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent = new ChangedEvent<>(this); private ChangedListener<InputGraph> titleChangedListener = g -> {}; + private boolean showFreeInteractive; private boolean showStableSea; private boolean showSea; private boolean showBlocks; @@ -104,6 +105,17 @@ public void setGlobalSelection(boolean enable, boolean fire) { } } + public boolean getShowFreeInteractive() { + return showFreeInteractive; + } + + public void setShowFreeInteractive(boolean enable) { + showFreeInteractive = enable; + if (enable) { + diagramChangedEvent.fire(); + } + } + public boolean getShowStableSea() { return showStableSea; } @@ -224,6 +236,7 @@ public DiagramViewModel(InputGraph graph) { globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected(); + showFreeInteractive = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.INTERACTIVE_FREE_NODES; showStableSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.STABLE_SEA_OF_NODES; showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES; showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES; @@ -266,7 +279,7 @@ public void setSelectedNodes(Set<Integer> nodes) { for (String ignored : getPositions()) { colors.add(Color.black); } - if (nodes.size() >= 1) { + if (!nodes.isEmpty()) { for (Integer id : nodes) { if (id < 0) { id = -id; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index d067925fb87..ff51b8928f6 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -176,6 +176,11 @@ public void mouseMoved(MouseEvent e) {} toolBar.addSeparator(); ButtonGroup layoutButtons = new ButtonGroup(); + JToggleButton freeInteractiveLayoutButton = new JToggleButton(new EnableFreeLayoutAction(this)); + freeInteractiveLayoutButton.setSelected(diagramViewModel.getShowFreeInteractive()); + layoutButtons.add(freeInteractiveLayoutButton); + toolBar.add(freeInteractiveLayoutButton); + JToggleButton stableSeaLayoutButton = new JToggleButton(new EnableStableSeaLayoutAction(this)); stableSeaLayoutButton.setSelected(diagramViewModel.getShowStableSea()); layoutButtons.add(stableSeaLayoutButton); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java new file mode 100644 index 00000000000..201fc51e15e --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/EnableFreeLayoutAction.java @@ -0,0 +1,49 @@ +/* + * 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 com.sun.hotspot.igv.view.actions; + +import com.sun.hotspot.igv.view.EditorTopComponent; +import java.beans.PropertyChangeEvent; + +public class EnableFreeLayoutAction extends EnableLayoutAction { + + public EnableFreeLayoutAction(EditorTopComponent etc) { + super(etc); + } + + @Override + protected String iconResource() { + return "com/sun/hotspot/igv/view/images/dynamic.png"; + } + + @Override + protected String getDescription() { + return "Show dynamic free layout"; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + editor.getModel().setShowFreeInteractive(this.isSelected()); + } +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java index 93d16d35914..01ebb8ed9e3 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LineWidget.java @@ -30,14 +30,16 @@ import com.sun.hotspot.igv.layout.Vertex; import com.sun.hotspot.igv.util.StringUtils; import com.sun.hotspot.igv.view.DiagramScene; -import com.sun.hotspot.igv.view.actions.CustomSelectAction; import java.awt.*; +import java.awt.geom.CubicCurve2D; import java.awt.geom.Line2D; import java.util.*; import java.util.List; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; + +import com.sun.hotspot.igv.view.actions.CustomSelectAction; import org.netbeans.api.visual.action.ActionFactory; import org.netbeans.api.visual.action.PopupMenuProvider; import org.netbeans.api.visual.action.SelectProvider; @@ -70,6 +72,8 @@ public class LineWidget extends Widget implements PopupMenuProvider { private final boolean isBold; private final boolean isDashed; private boolean needToInitToolTipText = true; + private int fromControlYOffset; + private int toControlYOffset; public LineWidget(DiagramScene scene, OutputSlot s, List<? extends Connection> connections, Point from, Point to, LineWidget predecessor, boolean isBold, boolean isDashed) { super(scene); @@ -172,6 +176,16 @@ public void setTo(Point to) { computeClientArea(); } + public void setFromControlYOffset(int fromControlYOffset) { + this.fromControlYOffset = fromControlYOffset; + computeClientArea(); + } + + public void setToControlYOffset(int toControlYOffset) { + this.toControlYOffset = toControlYOffset; + computeClientArea(); + } + public Point getFrom() { return from; } @@ -225,7 +239,41 @@ protected void paintWidget() { g.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)); } - g.drawLine(from.x, from.y, to.x, to.y); + // Define S-shaped curve with control points + if (fromControlYOffset != 0 && toControlYOffset != 0) { + if (from.y < to.y) { // non-reversed edges + if (Math.abs(from.x - to.x) > 10) { + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x, from.y + fromControlYOffset, + to.x, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } else { + g.drawLine(from.x, from.y, to.x, to.y); + } + } else { // reverse edges + if (from.x - to.x > 0) { + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x - 150, from.y + fromControlYOffset, + to.x + 150, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } else { + // add x offset + CubicCurve2D.Float sShape = new CubicCurve2D.Float(); + sShape.setCurve(from.x, from.y, + from.x + 150, from.y + fromControlYOffset, + to.x - 150, to.y + toControlYOffset, + to.x, to.y); + g.draw(sShape); + } + } + } else { + // Fallback to straight line if control points are not set + g.drawLine(from.x, from.y, to.x, to.y); + } boolean sameFrom = false; boolean sameTo = successors.isEmpty(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/dynamic.png new file mode 100644 index 0000000000000000000000000000000000000000..781b98176f8657d705976bf1ceb15e78a07f8098 GIT binary patch literal 2218 zcmZ{l4Ny}@5P&a${A2)8X;r8a!>EXmmmfh0Nh&4^!GZx|8`Nq;^1xR@UM6{w0OBu- z$oPj+9I^N}PKAzCDB@s6l&X*sDdJci1Vqpxh1LQirJ&M#Awob%a=Fd!e!I7KZ!ejW zh!7{L8x;WHBn}lt!P$iz_O|fbqi<La0Oc|!6iUQGAx)yi<1iHpfY;Hqqx{efk*?J{ z?j8vCz2p5T__<TDw0>rkUA0>V&3oULTR+{(%|#X@Z`wq^P+wes$<|dgyVCY?L}G@s zbJ5<FXUn9gR&A6LOL|k(`PmnrSZ55i57!Mh_0>&#HaohYdk^hJ_wHF)=?8l<#pnBv zq~wQg?X4~CEkxYrt!x{-K6m!#1q~gC)y-XN+hd0mLG`SF-si6p?o}C^2i<#^M{74o zQ2WZ#<IyhpGY;Kgc-{Bdn>TN6nBgm3WBcZl?ejfyzr7p#uJs|`X{lmSy8buD()JhW zZ<=<A7-#h_i!UXMb=Rx%idr{rZMk+bdRQ)O*zQ-@weabF=1pd#V_Pj}&39JK+QxG) zGL8TK!+)QjU3ogt71!K8w#ZYxM-X|O2%}C9U7XcHIAqv|^}o7WUeQ<Lf7Q97L-Msx zLJvCdcK-SuxmRww@lxzgZ_VjEv9Mr$LvGlu&N80SW?5RswSsMbuByqqvB1&Kt|;|) z%9Sil4AETaUX)tC<d3u`#TER`Z(<Xs-)*U?UoMN;`vX?48_Z7|STi&*T=zC7XxL8u za=UTi-~&25!hTdHjtdV5-cYs&_7rDe1*MsAs3|jnHJmB%4JdA4nn?y=C&hhK-cRu| z`#?_$%fvcCzatd3Np^*Deg+0?%xnpqfl!Oe2~<f-!iX)j5OKH!fL(u8n>@@jsid(P zEGB~$005iGW^q~Y!=yoh!{qw00I<&92kam-7mlVgR-+kQ&RCDh&<28|g<>(BKhEk9 zw(SHoIA}s+bhCycZjyuI;gi}8fX!)4DkEg!UvL$8B15jkV^M}7QA5T9JOdYsi6|kb z84^`$9oN98n>@HsCe;X?W^y4C_;eX8M2Krqnm>cdVA2It8jZ%&D&x3OqSa;`{^HZO z5QK({AW2C{j3f>N*Ty5Pz`#I+$wt_0U+CehOI8zdgRffWITGYU91*HhXfX|e;c6Ng zS00P&2|k@pCK`Q>tP?e0W0}-Cb6K!JgtQ<m1{0YKgT;=nZyaTiYo>$<EN+Tiq-9D> zsTfVA(Q8$vjZi8ORD~v@YC;D&7BX5tERRR7oGZjtxHeiNSD*qG&s2=1YHTM)yd{_c zRmnscjHrXVCSduSnTdu;!I-H)3&TWkoetFs@kFu&!AFmwIk}~e1rIl$YeI0X6vtHp z%g*2-6Ri`#a9oMSC5vFQ3CJGuWx)?q`k{wLa0?#`nmi<K6sp5jdh*Fyr^W~Yhlfn2 zo=C0LVz5p*iIJyaLM(L?{bgfm1RRbZo8uo~rYtQJshBA#ON#}iRB)AJtzzoK(e^Mk zWUz`DuO%NZvZGWO*{EEVTpiD+8+?^$oLsLW=#!n~i2L|3JcQJakIq9TU(SfHMN5y| z7p4gC!Vpm5nSHo?1k{=Xxkh*&^@&Bn(tsH`Q9;gCOh>)T;#S*FGIr*CwvVGp-;{a5 z#}SQNA&o7ZQy@E$wR!hLuaar9lGy+Hy5p-4`Y4T^E}lOg%n7yu>l$rqBIWMqtV3BX zO<%4c08#e~b-z_>>(36`57$OhKP~Iubwzimu#oEAQ`B|wbt?T(<Wm=8?5|RGTfB<l zcKC6Jp}aCX<+bN7deZ8Kz>u7>#;m%UJEa?g9%|qB#<=!(gq)#xOIk9+<lOU`_GS4i z9_^HzdcyN$%qYG*U}SW@E42m`(Xmbs<%5#*uJ`gTM1gv%wpnh%iu+yJ-!Gb@)@u(G f%l^K-?Ah`)Cke6h{6_fa0DyQ^gs5ocH@p7_s-*SA literal 0 HcmV?d00001 From e97aeec5ff665410954655ad98d491bc7f76223b Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Tue, 7 Jan 2025 15:07:00 +0000 Subject: [PATCH 46/99] 8346965: Multiple compiler/ciReplay test fails with -XX:+SegmentedCodeCache Reviewed-by: kvn --- test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index a974a09d615..017242c6d9e 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,7 @@ public abstract class CiReplayBase { "-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", // extra profile data as a stress test "-XX:+CICountNative", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError", + "-XX:-SegmentedCodeCache", REPLAY_FILE_OPTION}; private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", From bd004b26a588a221911e45873227a1534413e932 Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Tue, 7 Jan 2025 15:08:24 +0000 Subject: [PATCH 47/99] 8347038: [JMH] jdk.incubator.vector.SpiltReplicate fails NoClassDefFoundError Reviewed-by: psandoz --- .../openjdk/bench/jdk/incubator/vector/SpiltReplicate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java index 9f717908569..447eab012de 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(1) +@Fork(value=1, jvmArgs={"--add-modules=jdk.incubator.vector"}) public class SpiltReplicate { @CompilerControl(CompilerControl.Mode.DONT_INLINE) public long broadcastInt() { From ff783101ea0008a75431c809c71b1e0e16b1a8c4 Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Tue, 7 Jan 2025 15:18:02 +0000 Subject: [PATCH 48/99] 8346609: Improve MemorySegment.toString Reviewed-by: mcimadamore --- .../foreign/AbstractMemorySegmentImpl.java | 17 +++++++++++++---- test/jdk/java/foreign/TestByteBuffer.java | 3 ++- test/jdk/java/foreign/TestSegments.java | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index a52881b047b..e51e158c93c 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -486,9 +486,18 @@ public int characteristics() { @Override public String toString() { - return "MemorySegment{ " + - heapBase().map(hb -> "heapBase: " + hb + ", ").orElse("") + - "address: " + Utils.toHexString(address()) + + final String kind; + if (this instanceof HeapMemorySegmentImpl) { + kind = "heap"; + } else if (this instanceof MappedMemorySegmentImpl) { + kind = "mapped"; + } else { + kind = "native"; + } + return "MemorySegment{ kind: " + + kind + + heapBase().map(hb -> ", heapBase: " + hb).orElse("") + + ", address: " + Utils.toHexString(address()) + ", byteSize: " + length + " }"; } diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index a77f97018ca..3a5d1ef7c97 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -260,6 +260,7 @@ public void testMappedSegmentOperations(MappedSegmentOp mappedBufferOp) throws T try (FileChannel fileChannel = FileChannel.open(f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE)) { MemorySegment segment = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0L, 8L, arena); assertTrue(segment.isMapped()); + assertTrue(segment.toString().contains("mapped")); arena.close(); mappedBufferOp.apply(segment); } diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java index a76bc69fbd8..af639596734 100644 --- a/test/jdk/java/foreign/TestSegments.java +++ b/test/jdk/java/foreign/TestSegments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -234,8 +234,10 @@ public void testToString(Supplier<MemorySegment> segmentSupplier) { assertTrue(s.contains("byteSize: ")); if (segment.heapBase().isPresent()) { assertTrue(s.contains("heapBase: [")); + assertFalse(s.contains("native")); } else { assertFalse(s.contains("heapBase: ")); + assertTrue(s.contains("native")); } assertFalse(s.contains("Optional")); } From 605f740eb82acb8c435d978919099a7131d12984 Mon Sep 17 00:00:00 2001 From: Renjith Kannath Pariyangad <rkannathpari@openjdk.org> Date: Tue, 7 Jan 2025 16:54:04 +0000 Subject: [PATCH 49/99] 8334644: Automate javax/print/attribute/PageRangesException.java Reviewed-by: aivanov, abhiscxk, azvegint --- .../print/attribute/PageRangesException.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/jdk/javax/print/attribute/PageRangesException.java diff --git a/test/jdk/javax/print/attribute/PageRangesException.java b/test/jdk/javax/print/attribute/PageRangesException.java new file mode 100644 index 00000000000..81f9eb1a592 --- /dev/null +++ b/test/jdk/javax/print/attribute/PageRangesException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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.print.attribute.standard.PageRanges; + +/* + * @test + * @bug 4433126 4433096 + * @key printer + * @summary The line "ERROR: <message>" should NOT appear. + * @run main PageRangesException + */ + +public class PageRangesException { + public static void main(String[] args) throws Exception { + // test 4433126 + try { + PageRanges pr = new PageRanges("0:22"); + throw new RuntimeException("ERROR: no exceptions"); + } catch (IllegalArgumentException ie) { + System.out.println("OKAY: IllegalArgumentException " + ie); + } + + // test 4433096 + try { + int[][] m = null; + PageRanges pr = new PageRanges(m); + throw new RuntimeException("ERROR: NullPointerException expected"); + } catch (IllegalArgumentException ie) { + throw new RuntimeException("ERROR: IllegalArgumentException", ie); + } catch (NullPointerException e) { + System.out.println("OKAY: NullPointerException"); + } + } +} From 067c023d1586dbd0265111dd873fceb5f910cf9e Mon Sep 17 00:00:00 2001 From: Babneet Singh <sbabneet@ca.ibm.com> Date: Tue, 7 Jan 2025 09:15:13 -0800 Subject: [PATCH 50/99] Reduce available slots to match the upper limit supported by OpenJ9 Related: https://github.com/eclipse-openj9/openj9/issues/20355 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com> --- test/jdk/java/foreign/largestub/TestLargeStub.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/foreign/largestub/TestLargeStub.java b/test/jdk/java/foreign/largestub/TestLargeStub.java index 13b635c7343..d432d8f4148 100644 --- a/test/jdk/java/foreign/largestub/TestLargeStub.java +++ b/test/jdk/java/foreign/largestub/TestLargeStub.java @@ -21,6 +21,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2025, 2025 All Rights Reserved + * =========================================================================== + */ + /* * @test * @library ../ @@ -47,8 +53,8 @@ public class TestLargeStub extends NativeTestHelper { - private static final int DOWNCALL_AVAILABLE_SLOTS = 248; - private static final int UPCALL_AVAILABLE_SLOTS = 250; + private static final int DOWNCALL_AVAILABLE_SLOTS = 125; + private static final int UPCALL_AVAILABLE_SLOTS = 125; MemoryLayout STRUCT_LL = MemoryLayout.structLayout( C_LONG_LONG, From 392e981939fad6e988fe0b34b510cf004b43b081 Mon Sep 17 00:00:00 2001 From: Naoto Sato <naoto@openjdk.org> Date: Tue, 7 Jan 2025 17:40:01 +0000 Subject: [PATCH 51/99] 8175709: DateTimeFormatterBuilder.appendZoneId() has misleading JavaDoc Reviewed-by: rriggs --- .../time/format/DateTimeFormatterBuilder.java | 69 +++++++++---------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index 33dea914b66..7c83de46c52 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -1097,14 +1097,14 @@ public DateTimeFormatterBuilder appendLocalizedOffset(TextStyle style) { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1118,9 +1118,9 @@ public DateTimeFormatterBuilder appendLocalizedOffset(TextStyle style) { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("+01:30") - * "UTC+01:30" -- ZoneOffset.of("+01:30") - * "GMT+01:30" -- ZoneOffset.of("+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * </pre> * * @return this, for chaining, not null @@ -1135,8 +1135,7 @@ public DateTimeFormatterBuilder appendZoneId() { * Appends the time-zone region ID, such as 'Europe/Paris', to the formatter, * rejecting the zone ID if it is a {@code ZoneOffset}. * <p> - * This appends an instruction to format/parse the zone ID to the builder - * only if it is a region-based ID. + * This appends an instruction to format only region-based zone IDs to the builder. * <p> * During formatting, the zone is obtained using a mechanism equivalent * to querying the temporal with {@link TemporalQueries#zoneId()}. @@ -1148,14 +1147,14 @@ public DateTimeFormatterBuilder appendZoneId() { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1169,9 +1168,9 @@ public DateTimeFormatterBuilder appendZoneId() { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("+01:30") - * "UTC+01:30" -- ZoneOffset.of("+01:30") - * "GMT+01:30" -- ZoneOffset.of("+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * </pre> * <p> * Note that this method is identical to {@code appendZoneId()} except @@ -1206,14 +1205,14 @@ public DateTimeFormatterBuilder appendZoneRegionId() { * During parsing, the text must match a known zone or offset. * There are two types of zone ID, offset-based, such as '+01:30' and * region-based, such as 'Europe/London'. These are parsed differently. - * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser - * expects an offset-based zone and will not match region-based zones. - * The offset ID, such as '+02:30', may be at the start of the parse, - * or prefixed by 'UT', 'UTC' or 'GMT'. The offset ID parsing is - * equivalent to using {@link #appendOffset(String, String)} using the - * arguments 'HH:MM:ss' and the no offset string '0'. - * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot - * match a following offset ID, then {@link ZoneOffset#UTC} is selected. + * If the parse starts with '+' or '-', then the parser expects an + * offset-based zone and will not match region-based zones. The offset + * ID parsing is equivalent to using {@link #appendOffset(String, String)} + * using the arguments 'HH:MM:ss' and the no offset string '0'. + * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser can + * match a following offset, then a region-based zone with the parsed + * offset will be returned, or else if the parser cannot match a following + * offset, then {@link ZoneOffset#UTC} is selected. * In all other cases, the list of known region-based zones is used to * find the longest available match. If no match is found, and the parse * starts with 'Z', then {@code ZoneOffset.UTC} is selected. @@ -1227,9 +1226,9 @@ public DateTimeFormatterBuilder appendZoneRegionId() { * "UTC" -- ZoneId.of("UTC") * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("UT+01:30") - * "UTC+01:30" -- ZoneOffset.of("UTC+01:30") - * "GMT+01:30" -- ZoneOffset.of("GMT+01:30") + * "UT+01:30" -- ZoneId.of("UT+01:30") + * "UTC+01:30" -- ZoneId.of("UTC+01:30") + * "GMT+01:30" -- ZoneId.of("GMT+01:30") * </pre> * <p> * Note that this method is identical to {@code appendZoneId()} except From 4e7c2b760832f29c9e5dedfb1c1619464fd897a6 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Tue, 7 Jan 2025 19:34:12 +0000 Subject: [PATCH 52/99] 8347127: CTW fails to build after JDK-8334733 Reviewed-by: kvn, epeter --- test/hotspot/jtreg/testlibrary/ctw/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/testlibrary/ctw/Makefile b/test/hotspot/jtreg/testlibrary/ctw/Makefile index 5c64c67d828..ea133f97621 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/Makefile +++ b/test/hotspot/jtreg/testlibrary/ctw/Makefile @@ -53,6 +53,7 @@ WB_CLASS_FILES := $(subst $(TESTLIBRARY_DIR)/,,$(WB_SRC_FILES)) WB_CLASS_FILES := $(patsubst %.java,%.class,$(WB_CLASS_FILES)) EXPORTS=--add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.module=ALL-UNNAMED \ --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED \ --add-exports java.base/jdk.internal.access=ALL-UNNAMED From fbebe6e0282f895653085dd4a12ec86a644932b4 Mon Sep 17 00:00:00 2001 From: Anna Babu Palathingal <148897727+annaibm@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:02:35 -0500 Subject: [PATCH 53/99] Exclude openjdk subtests for FIPS strict profile - Exclude openjdk subtests for FIPS140_3_OpenJCEPlusFIPS.FIPS140-3 related: https://github.ibm.com/runtimes/automation/issues/170 Signed-off-by: anna.bp <anna.bp@ibm.com> --- ...st-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt index c33fcf54c59..eccbdbf3ff7 100644 --- a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt +++ b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt @@ -1,5 +1,5 @@ # =========================================================================== -# (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved +# (c) Copyright IBM Corp. 2024, 2025 All Rights Reserved # =========================================================================== # 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 @@ -164,6 +164,7 @@ com/sun/crypto/provider/TLS/TestPremaster.java https://github.com/eclipse-openj9 com/sun/org/apache/xml/internal/security/ShortECDSA.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/org/apache/xml/internal/security/SignatureKeyInfo.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/org/apache/xml/internal/security/TruncateHMAC.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +java/security/AccessController/DoPrivAccompliceTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all java/security/AsymmetricKey/GetParams.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/BasicPermission/PermClass.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/BasicPermission/SerialVersion.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -441,8 +442,12 @@ sun/security/krb5/runNameEquals.sh https://github.com/eclipse-openj9/openj9/issu # # Exclude tests list from extended.openjdk # +com/sun/jndi/dns/ConfigTests/TcpTimeout.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/jndi/ldap/LdapCBPropertiesTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +com/sun/jndi/ldap/LdapPoolTimeoutTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +com/sun/jndi/ldap/LdapTimeoutTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/jndi/rmi/registry/objects/RmiFactoriesFilterTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -533,6 +538,7 @@ java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java https://githu java/sql/testng/test/sql/SQLTransientExceptionTests.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/sql/testng/test/sql/SQLWarningTests.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/naming/module/RunBasic.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +javax/naming/spi/FactoryCacheTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all javax/net/ssl/ALPN/SSLEngineAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ALPN/SSLSocketAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -688,6 +694,7 @@ javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java https://github.com/eclipse-openj9/op javax/net/ssl/TLSv13/HRRKeyShares.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ciphersuites/DisabledAlgorithms.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ciphersuites/ECCurvesconstraints.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java#Client https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ciphersuites/TLSWontNegotiateDisabledCipherAlgos.java#Server https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/compatibility/ClientHelloProcessing.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -707,6 +714,8 @@ javax/security/auth/Subject/Compat.java https://github.com/eclipse-openj9/openj9 javax/security/auth/Subject/SubjectNullTests.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/security/auth/login/Configuration/GetInstance.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/security/auth/login/Configuration/GetInstanceSecurity.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +javax/security/auth/login/modules/JaasModularClientTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all javax/security/sasl/Sasl/ClientServerTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/security/sasl/Sasl/DisabledMechanisms.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/smartcardio/Serialize.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -733,7 +742,10 @@ jdk/security/jarsigner/Function.java https://github.com/eclipse-openj9/openj9/is jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/security/jarsigner/Properties.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/security/jarsigner/Spec.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +jdk/security/logging/TestSecurityPropertyModificationLog.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all jdk/security/logging/TestTLSHandshakeLog.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +jdk/security/logging/TestX509CertificateLog.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +jdk/security/logging/TestX509ValidationLog.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/rmi/log/ReliableLog/LogAlignmentTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/rmi/runtime/Log/4504153/Test4504153.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/rmi/runtime/Log/6409194/NoConsoleOutput.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -783,9 +795,11 @@ sun/security/pkcs/pkcs7/PKCS7VerifyTest.java https://github.com/eclipse-openj9/o sun/security/pkcs/pkcs7/SignerOrder.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs8/PKCS8Test.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs8/TestLeadingZeros.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/pkcs/pkcs9/PKCS9AttrTypeTests.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/security/pkcs/pkcs9/UnstructuredName.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs11/Cipher/TestCipherTextStealingMultipart.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs11/Cipher/TestRSACipherWrap.java https://github.com/eclipse-openj9/openj9/issues/20343 linux-s390x +sun/security/pkcs11/Config/ReadConfInUTF16Env.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/security/pkcs11/KeyStore/ClientAuth.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs11/Provider/Absolute.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs11/Provider/CheckRegistration.java https://github.com/eclipse-openj9/openj9/issues/20343 linux-s390x @@ -1052,9 +1066,15 @@ sun/security/tools/keytool/fakecacerts/TrustedCert.java https://github.com/eclip sun/security/tools/keytool/fakegen/DefaultSignatureAlgorithm.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/tools/keytool/fakegen/PSS.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/util/Debug/DebugOptions.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/util/DerInputBuffer/PaddedBitString.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +sun/security/util/DerValue/DeepOctets.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +sun/security/util/DerValue/Indefinite.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +sun/security/util/DerValue/WideTag.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/security/util/HostnameChecker/NullHostnameCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/util/HostnameMatcher/NullHostnameCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/util/InternalPrivateKey/Correctness.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/util/Oid/S11N.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/util/Resources/early/EarlyResources.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/security/validator/EndEntityExtensionCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/validator/PKIXValAndRevCheckTests.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/validator/certreplace.sh https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -1069,6 +1089,7 @@ sun/security/x509/URICertStore/AIACertTimeout.java https://github.com/eclipse-op sun/security/x509/URICertStore/CRLReadTimeout.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/URICertStore/ExtensionsWithLDAP.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/X509CRLImpl/OrderAndDup.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/x509/X509CRLImpl/UnexpectedNPE.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all sun/security/x509/X509CRLImpl/Verify.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/X509CertImpl/V3Certificate.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/X509CertImpl/Verify.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all From ee1237a8a569066b824a871285ca822bf9ed8a9c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Tue, 7 Jan 2025 23:14:04 +0000 Subject: [PATCH 54/99] 8329549: Remove FORMAT64_MODIFIER Reviewed-by: dholmes, kbarrett --- test/hotspot/gtest/utilities/test_globalDefinitions.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp index 5dc43fb543f..9cadc91aeb9 100644 --- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp +++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,4 +289,7 @@ TEST(globalDefinitions, format_specifiers) { check_format(INTPTR_FORMAT, (intptr_t)0x123, "0x" LP64_ONLY("00000000") "00000123"); check_format(PTR_FORMAT, (uintptr_t)0x123, "0x" LP64_ONLY("00000000") "00000123"); + + // Check all platforms print this compatibly without leading 0x. + check_format(UINT64_FORMAT_0, (u8)0x123, "0000000000000123"); } From 1ac3064e3d183c013f4f01cec2e7eb837322c626 Mon Sep 17 00:00:00 2001 From: Taizo Kurashige <taizousum11@gmail.com> Date: Wed, 8 Jan 2025 01:15:44 +0000 Subject: [PATCH 55/99] 8343342: java/io/File/GetXSpace.java fails on Windows with CD-ROM drive Reviewed-by: bpb, aturbanov --- test/jdk/java/io/File/GetXSpace.java | 56 ++++++++++++++++++++++++++-- test/jdk/java/io/File/libGetXSpace.c | 29 +++++++++++++- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/io/File/GetXSpace.java b/test/jdk/java/io/File/GetXSpace.java index d76000dbef5..512ea51780b 100644 --- a/test/jdk/java/io/File/GetXSpace.java +++ b/test/jdk/java/io/File/GetXSpace.java @@ -54,6 +54,8 @@ public class GetXSpace { System.loadLibrary("GetXSpace"); } + private static final Pattern DF_PATTERN = Pattern.compile("([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+\\d+%\\s+([^\\s].*)\n"); + private static int fail = 0; private static int pass = 0; private static Throwable first; @@ -104,8 +106,17 @@ private static class Space { Space(String name) { this.name = name; long[] sizes = new long[4]; - if (getSpace0(name, sizes)) - System.err.println("WARNING: total space is estimated"); + if (Platform.isWindows() & isCDDrive(name)) { + try { + getCDDriveSpace(name, sizes); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("can't get CDDrive sizes"); + } + } else { + if (getSpace0(name, sizes)) + System.err.println("WARNING: total space is estimated"); + } this.size = sizes[0]; this.total = sizes[1]; this.free = sizes[2]; @@ -167,7 +178,8 @@ private static void compare(Space s) { out.format("%s (%d):%n", s.name(), s.size()); String fmt = " %-4s total = %12d free = %12d usable = %12d%n"; - out.format(fmt, "getSpace0", s.total(), s.free(), s.available()); + String method = Platform.isWindows() & isCDDrive(s.name()) ? "getCDDriveSpace" : "getSpace0"; + out.format(fmt, method, s.total(), s.free(), s.available()); out.format(fmt, "getXSpace", ts, fs, us); // If the file system can dynamically change size, this check will fail. @@ -324,7 +336,7 @@ private static int testFile(Path dir) { private static int testVolumes() { out.println("--- Testing volumes"); // Find all of the partitions on the machine and verify that the sizes - // returned by File::getXSpace are equivalent to those from getSpace0 + // returned by File::getXSpace are equivalent to those from getSpace0 or getCDDriveSpace ArrayList<String> l; try { l = paths(); @@ -397,4 +409,40 @@ public static void main(String[] args) throws Exception { // size[3] usable space: number of bytes available to the caller // private static native boolean getSpace0(String root, long[] space); + + private static native boolean isCDDrive(String root); + + private static void getCDDriveSpace(String root, long[] sizes) + throws IOException { + String[] cmd = new String[] {"df", "-k", "-P", root}; + Process p = Runtime.getRuntime().exec(cmd); + StringBuilder sb = new StringBuilder(); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) { + String s; + int i = 0; + while ((s = in.readLine()) != null) { + // skip header + if (i++ == 0) continue; + sb.append(s).append("\n"); + } + } + out.println(sb); + + Matcher m = DF_PATTERN.matcher(sb); + int j = 0; + while (j < sb.length()) { + if (m.find(j)) { + sizes[0] = Long.parseLong(m.group(2)) * 1024; + sizes[1] = Long.parseLong(m.group(3)) * 1024; + sizes[2] = sizes[0] - sizes[1]; + sizes[3] = Long.parseLong(m.group(4)) * 1024; + j = m.end(); + } else { + throw new RuntimeException("unrecognized df output format: " + + "charAt(" + j + ") = '" + + sb.charAt(j) + "'"); + } + } + } } diff --git a/test/jdk/java/io/File/libGetXSpace.c b/test/jdk/java/io/File/libGetXSpace.c index a4e36bd2431..c45aea14691 100644 --- a/test/jdk/java/io/File/libGetXSpace.c +++ b/test/jdk/java/io/File/libGetXSpace.c @@ -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 @@ -159,6 +159,33 @@ Java_GetXSpace_getSpace0 (*env)->SetLongArrayRegion(env, sizes, 0, 4, array); return totalSpaceIsEstimated; } + +JNIEXPORT jboolean JNICALL +Java_GetXSpace_isCDDrive + (JNIEnv *env, jclass cls, jstring root) +{ +#ifdef WINDOWS + const jchar* strchars = (*env)->GetStringChars(env, root, NULL); + if (strchars == NULL) { + JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", + "GetStringChars"); + return JNI_FALSE; + } + + LPCWSTR path = (LPCWSTR)strchars; + UINT driveType = GetDriveTypeW(path); + + (*env)->ReleaseStringChars(env, root, strchars); + + if (driveType != DRIVE_CDROM) { + return JNI_FALSE; + } + + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} #ifdef __cplusplus } #endif From de30fb024a16c5e464365141200742de394bcb97 Mon Sep 17 00:00:00 2001 From: Chen Liang <liach@openjdk.org> Date: Wed, 8 Jan 2025 03:37:28 +0000 Subject: [PATCH 56/99] 8342468: Improve API documentation for java.lang.classfile.constantpool Reviewed-by: asotona --- .../lang/classfile/BootstrapMethodEntry.java | 30 +- .../java/lang/classfile/ClassFile.java | 53 ++- .../AnnotationConstantValueEntry.java | 16 +- .../classfile/constantpool/ClassEntry.java | 63 ++- .../constantpool/ConstantDynamicEntry.java | 56 ++- .../classfile/constantpool/ConstantPool.java | 32 +- .../constantpool/ConstantPoolBuilder.java | 444 ++++++++++-------- .../constantpool/ConstantPoolException.java | 28 +- .../constantpool/ConstantValueEntry.java | 13 +- .../classfile/constantpool/DoubleEntry.java | 26 +- .../DynamicConstantPoolEntry.java | 55 ++- .../classfile/constantpool/FieldRefEntry.java | 24 +- .../classfile/constantpool/FloatEntry.java | 23 +- .../classfile/constantpool/IntegerEntry.java | 20 +- .../constantpool/InterfaceMethodRefEntry.java | 26 +- .../constantpool/InvokeDynamicEntry.java | 43 +- .../constantpool/LoadableConstantEntry.java | 24 +- .../classfile/constantpool/LongEntry.java | 21 +- .../constantpool/MemberRefEntry.java | 40 +- .../constantpool/MethodHandleEntry.java | 44 +- .../constantpool/MethodRefEntry.java | 24 +- .../constantpool/MethodTypeEntry.java | 30 +- .../classfile/constantpool/ModuleEntry.java | 23 +- .../constantpool/NameAndTypeEntry.java | 36 +- .../classfile/constantpool/PackageEntry.java | 26 +- .../classfile/constantpool/PoolEntry.java | 52 +- .../classfile/constantpool/StringEntry.java | 22 +- .../classfile/constantpool/Utf8Entry.java | 44 +- .../classfile/constantpool/package-info.java | 54 ++- .../snippet-files/PackageSnippets.java | 43 ++ test/jdk/jdk/classfile/SnippetsTest.java | 6 +- 31 files changed, 1070 insertions(+), 371 deletions(-) create mode 100644 src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java diff --git a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java index 1608e77bee6..ab246a8653b 100644 --- a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,9 @@ package java.lang.classfile; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.LoadableConstantEntry; import java.lang.classfile.constantpool.MethodHandleEntry; import java.util.List; @@ -34,10 +36,20 @@ /** * Models an entry in the bootstrap method table. The bootstrap method table - * is stored in the {@code BootstrapMethods} attribute, but is modeled by - * the {@link ConstantPool}, since the bootstrap method table is logically - * part of the constant pool. + * is stored in the {@link BootstrapMethodsAttribute BootstrapMethods} + * attribute, but is modeled by the {@link ConstantPool}, since the bootstrap + * method table is logically part of the constant pool. + * <p> + * A bootstrap method entry is composite: + * {@snippet lang=text : + * // @link substring="BootstrapMethodEntry" target="ConstantPoolBuilder#bsmEntry(MethodHandleEntry, List)" : + * BootstrapMethodEntry( + * MethodHandleEntry bootstrapMethod, // @link substring="bootstrapMethod" target="#bootstrapMethod" + * List<LoadableConstantEntry> arguments // @link substring="arguments" target="#arguments()" + * ) + * } * + * @see ConstantPoolBuilder#bsmEntry ConstantPoolBuilder::bsmEntry * @since 24 */ public sealed interface BootstrapMethodEntry @@ -45,11 +57,19 @@ public sealed interface BootstrapMethodEntry /** * {@return the constant pool associated with this entry} + * + * @apiNote + * Given a {@link ConstantPoolBuilder} {@code builder} and a {@code + * BootstrapMethodEntry} {@code entry}, use {@link + * ConstantPoolBuilder#canWriteDirect + * builder.canWriteDirect(entry.constantPool())} instead of object equality + * of the constant pool to determine if an entry is compatible. */ ConstantPool constantPool(); /** - * {@return the index into the bootstrap method table corresponding to this entry} + * {@return the index into the bootstrap method table corresponding to this + * entry} */ int bsmIndex(); diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFile.java b/src/java.base/share/classes/java/lang/classfile/ClassFile.java index c98991ecf7a..43fb1927b38 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFile.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -140,21 +140,56 @@ static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyReso /** * Option describing whether to preserve the original constant pool when - * transforming a classfile. Reusing the constant pool enables significant - * optimizations in processing time and minimizes differences between the - * original and transformed classfile, but may result in a bigger classfile - * when a classfile is significantly transformed. - * Default is {@code SHARED_POOL} to preserve the original constant - * pool. + * transforming a {@code class} file. Reusing the constant pool enables + * significant optimizations in processing time and minimizes differences + * between the original and transformed {@code class} files, but may result + * in a bigger transformed {@code class} file when many elements of the + * original {@code class} file are dropped and many original constant + * pool entries become unused. Default is {@link #SHARED_POOL} to preserve + * the original constant pool. * + * @see ConstantPoolBuilder + * @see #build(ClassEntry, ConstantPoolBuilder, Consumer) + * @see #transformClass(ClassModel, ClassTransform) * @since 24 */ enum ConstantPoolSharingOption implements Option { - /** Preserves the original constant pool when transforming classfile */ + /** + * Preserves the original constant pool when transforming the {@code + * class} file. + * <p> + * These two transformations below are equivalent: + * {@snippet lang=java : + * ClassModel originalClass = null; // @replace substring=null; replacement=... + * ClassDesc resultClassName = null; // @replace substring=null; replacement=... + * ClassTransform classTransform = null; // @replace substring=null; replacement=... + * var resultOne = ClassFile.of(ConstantPoolSharingOption.SHARED_POOL) + * .transformClass(originalClass, resultClassName, classTransform); + * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(originalClass), + * clb -> clb.transform(originalClass, classTransform)); + * } + * + * @see ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel) + */ SHARED_POOL, - /** Creates a new constant pool when transforming classfile */ + /** + * Creates a new constant pool when transforming the {@code class} file. + * <p> + * These two transformations below are equivalent: + * {@snippet lang=java : + * ClassModel originalClass = null; // @replace substring=null; replacement=... + * ClassDesc resultClassName = null; // @replace substring=null; replacement=... + * ClassTransform classTransform = null; // @replace substring=null; replacement=... + * var resultOne = ClassFile.of(ConstantPoolSharingOption.NEW_POOL) + * .transformClass(originalClass, resultClassName, classTransform); + * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(), + * clb -> clb.transform(originalClass, classTransform)); + * } + * + * @see ConstantPoolBuilder#of() ConstantPoolBuilder::of() + */ NEW_POOL } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java index 5255ceb1ef7..c4b6546fe20 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,9 @@ import java.lang.constant.ConstantDesc; /** - * A constant pool entry that may be used by annotation constant values, - * which includes the four kinds of primitive constants and UTF8 constants. - * These entries are also the only entries that do not refer to other - * constant pool entries. + * Marker interface for constant pool entries that can represent constant values + * associated with elements of annotations. They are also the only entries that + * do not refer to other constant pool entries. * * @apiNote * An annotation constant value entry alone is not sufficient to determine @@ -40,6 +39,7 @@ * in {@link AnnotationValue.OfInt}. * * @see AnnotationValue.OfConstant + * @jvms 4.7.16.1 The {@code element_value} structure * @sealedGraph * @since 24 */ @@ -47,9 +47,9 @@ public sealed interface AnnotationConstantValueEntry extends PoolEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, Utf8Entry { /** - * {@return the constant value} The constant value will be an {@link Integer}, - * {@link Long}, {@link Float}, {@link Double} for the primitive constants, - * or {@link String} for UTF8 constants. + * {@return the constant value} The constant value will be an {@link + * Integer}, {@link Long}, {@link Float}, {@link Double} for the primitive + * constants, or {@link String} for UTF8 constants. */ ConstantDesc constantValue(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java index 2a3bd95da22..5017838d68e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,33 +30,82 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Class_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.1 The CONSTANT_Class_info Structure + * Models a {@code CONSTANT_Class_info} structure, representing a reference + * type, in the constant pool of a {@code class} file. + * <p> + * The use of a {@code ClassEntry} is modeled by a {@link ClassDesc} that is not + * primitive. Conversions are through {@link ConstantPoolBuilder#classEntry( + * ClassDesc)} and {@link #asSymbol()}. + * <p> + * A {@code ClassEntry} is composite: + * {@snippet lang=text : + * // @link substring="ClassEntry" target="ConstantPoolBuilder#classEntry(Utf8Entry)" : + * ClassEntry(Utf8Entry name) // @link substring="name" target="#name" + * } + * where {@code name} represents: + * <ul> + * <li>The internal form of a binary name (JVMS {@jvms 4.2.1}), if and only if + * this {@code ClassEntry} represents a class or interface, such as {@code + * java/lang/String} for the {@link String} class. + * <li>A field descriptor string (JVMS {@jvms 4.3.2}) representing an array type, + * if and only if this {@code ClassEntry} represents an array type, such as + * {@code [I} for the {@code int[]} type, or {@code [Ljava/lang/String;} for the + * {@code String[]} type. + * </ul> + * A field descriptor string for an array type can be distinguished by its + * leading {@code '['} character. * + * @apiNote + * The internal form of a binary name, where all occurrences of {@code .} in the + * name are replaced by {@code /}, is informally known as an <dfn>{@index + * "internal name"}</dfn>. This concept also applies to package names in + * addition to class and interface names. + * + * @see ConstantPoolBuilder#classEntry ConstantPoolBuilder::classEntry + * @see ClassDesc + * @jvms 4.4.1 The {@code CONSTANT_Class_info} Structure * @since 24 */ public sealed interface ClassEntry extends LoadableConstantEntry permits AbstractPoolEntry.ClassEntryImpl { + /** + * {@inheritDoc} + * <p> + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the UTF8 constant pool entry for the class name} + * {@return the {@code Utf8Entry} referred by this structure} If the + * value of the UTF8 starts with a {@code [}, this represents an array type + * and the value is a descriptor string; otherwise, this represents a class + * or interface and the value is the {@linkplain ##internalname internal + * form} of a binary name. + * + * @see ConstantPoolBuilder#classEntry(Utf8Entry) + * ConstantPoolBuilder::classEntry(Utf8Entry) */ Utf8Entry name(); /** - * {@return the class name, as an internal binary name} + * {@return the represented reference type, as the {@linkplain + * ##internalname internal form} of a binary name or an array descriptor + * string} This is a shortcut for {@link #name() name().stringValue()}. */ String asInternalName(); /** - * {@return the class name, as a symbolic descriptor} + * {@return the represented reference type, as a symbolic descriptor} The + * returned descriptor is never {@linkplain ClassDesc#isPrimitive() + * primitive}. + * + * @see ConstantPoolBuilder#classEntry(ClassDesc) + * ConstantPoolBuilder::classEntry(ClassDesc) */ ClassDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java index 72050cd9b8f..bbd03c88292 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,36 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_Dynamic_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Models a {@code CONSTANT_Dynamic_info} structure, representing a <dfn>{@index + * "dynamically-computed constant"}</dfn>, in the constant pool of a {@code + * class} file. + * <p> + * The use of a {@code ConstantDynamicEntry} is modeled by a {@link + * DynamicConstantDesc}. Conversions are through {@link #asSymbol()} and {@link + * ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc)}. + * <p> + * A dynamic constant entry is composite: + * {@snippet lang=text : + * // @link substring="ConstantDynamicEntry" target="ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)" : + * ConstantDynamicEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where {@link #type() nameAndType.type()} is a {@linkplain #typeSymbol() + * field descriptor} string. * + * @apiNote + * A dynamically-computed constant is frequently called a <dfn>{@index "dynamic + * constant"}</dfn>, or a <dfn>{@index "condy"}</dfn>, from the abbreviation of + * "constant dynamic". + * + * @see ConstantPoolBuilder#constantDynamicEntry + * ConstantPoolBuilder::constantDynamicEntry + * @see DynamicConstantDesc + * @see java.lang.invoke##condycon Dynamically-computed constants + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures * @since 24 */ public sealed interface ConstantDynamicEntry @@ -44,19 +70,28 @@ public sealed interface ConstantDynamicEntry permits AbstractPoolEntry.ConstantDynamicEntryImpl { /** - * {@return a symbolic descriptor for the dynamic constant's type} + * {@return a symbolic descriptor for the {@linkplain #type() field type} of + * this dynamically-computed constant} */ default ClassDesc typeSymbol() { return Util.fieldTypeSymbol(type()); } + /** + * {@inheritDoc} + * <p> + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the symbolic descriptor for the {@code invokedynamic} constant} + * {@return a symbolic descriptor for this dynamically-computed constant} + * + * @see ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc) + * ConstantPoolBuilder::constantDynamicEntry(DynamicConstantDesc) */ default DynamicConstantDesc<?> asSymbol() { return DynamicConstantDesc.ofNamed(bootstrap().bootstrapMethod().asSymbol(), @@ -68,10 +103,15 @@ default DynamicConstantDesc<?> asSymbol() { } /** - * {@return the type of the constant} + * {@inheritDoc} + * + * @apiNote + * The data type of a dynamically-computed constant depends on its + * {@linkplain #type() descriptor}, while the data type of all other + * constants can be determined by their {@linkplain #tag() constant type}. */ @Override default TypeKind typeKind() { - return TypeKind.fromDescriptor(type().stringValue()); + return TypeKind.fromDescriptor(type()); } } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java index 91dc8906b7b..6fed8dad8b7 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,22 @@ import java.lang.classfile.BootstrapMethodEntry; import java.lang.classfile.ClassReader; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; import java.util.Iterator; import java.util.NoSuchElementException; /** - * Provides read access to the constant pool and bootstrap method table of a - * classfile. - * @jvms 4.4 The Constant Pool + * Provides read access to the constant pool and the bootstrap method table of a + * {@code class} file. + * + * <h2 id="index">Index in the Constant Pool</h2> + * The constant pool entries are accessed by index. A valid index is in the + * range of {@link #size() [1, size())}. It is {@linkplain PoolEntry#width() + * unusable} if a {@link LongEntry} or {@link DoubleEntry} is at its previous + * index. * + * @see BootstrapMethodsAttribute + * @jvms 4.4 The Constant Pool * @sealedGraph * @since 24 */ @@ -46,7 +54,7 @@ public sealed interface ConstantPool extends Iterable<PoolEntry> * * @apiNote * If only a particular type of entry is expected, use {@link #entryByIndex( - * int, Class) entryByIndex(int, Class)}. + * int, Class)}. * * @param index the index within the pool of the desired entry * @throws ConstantPoolException if the index is out of range of the @@ -55,7 +63,11 @@ public sealed interface ConstantPool extends Iterable<PoolEntry> PoolEntry entryByIndex(int index); /** - * {@return the size of the constant pool} + * {@return the exclusive upper bound of the valid indices of this constant + * pool} The actual number of entries is lower because {@code 0}, {@code + * size()} are not valid, and a valid index may be unusable. + * + * @see ##index Index in the Constant Pool */ int size(); @@ -66,12 +78,17 @@ public sealed interface ConstantPool extends Iterable<PoolEntry> * @param index the index within the pool of the desired entry * @param cls the entry type * @throws ConstantPoolException if the index is out of range of the - * constant pool, or the entry is not of the given type + * constant pool or considered unusable, or the entry is not + * of the given type */ <T extends PoolEntry> T entryByIndex(int index, Class<T> cls); /** * {@return an iterator over pool entries} + * + * @apiNote + * This skips any unusable index and is less error-prone than iterating by + * raw index. See <em>{@linkplain ##index Index in the Constant Pool}</em>. */ @Override default Iterator<PoolEntry> iterator() { @@ -93,7 +110,6 @@ public PoolEntry next() { }; } - /** * {@return the {@link BootstrapMethodEntry} at the specified index within * the bootstrap method table} diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java index 2dc2a390bd1..e1518ab6a02 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,16 @@ package java.lang.classfile.constantpool; import java.lang.classfile.BootstrapMethodEntry; -import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileBuilder; import java.lang.classfile.ClassModel; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.attribute.ConstantValueAttribute; +import java.lang.classfile.instruction.ConstantInstruction; import java.lang.constant.*; +import java.lang.invoke.MethodHandleInfo; import java.util.List; +import java.util.function.Consumer; import jdk.internal.classfile.impl.AbstractPoolEntry.ClassEntryImpl; import jdk.internal.classfile.impl.ClassReaderImpl; @@ -39,14 +45,45 @@ import static java.util.Objects.requireNonNull; /** - * Builder for the constant pool of a classfile. Provides read and write access - * to the constant pool that is being built. Writing is append-only and idempotent - * (entry-bearing methods will return an existing entry if there is one). + * Builder for the constant pool of a {@code class} file. Provides read and + * write access to the constant pool that is {@linkplain ClassFileBuilder#constantPool() + * being built}. Writing is append-only (the index of new entries monotonically + * increase) and idempotent (entry-bearing methods will return an existing entry + * if there is a suitable one). + * <p> + * For {@code class} file building, an overload of {@link ClassFile#build( + * ClassEntry, ConstantPoolBuilder, Consumer) ClassFile::build} takes a + * {@code ConstantPoolBuilder}. For {@code class} file transformations via + * {@link ClassFile#transformClass ClassFile::transformClass}, the {@link + * ClassFile.ConstantPoolSharingOption} controls how the constant pool builder + * of the resulting {@code class} is created. * - * A {@linkplain ConstantPoolBuilder} is associated with a {@link ClassBuilder}. - * The {@linkplain ConstantPoolBuilder} also provides access to some of the - * state of the {@linkplain ClassBuilder}, such as classfile processing options. + * <h2 id="alien">Alien Constant Pool Entries</h2> + * In {@code class} file building and constant pool building, some constant pool + * entries supplied may be {@linkplain #canWriteDirect(ConstantPool) alien} + * to this constant pool builder of the active class file builder. For example, + * {@link #classEntry(Utf8Entry) classEntry(Utf8Entry)} may be called with an + * alien UTF8 entry. Alien entries will be converted to a pool entry in + * this constant pool builder, reusing equivalent entries or adding new entries + * if there is none. As a result, all pool entries returned by entry-bearing + * methods in this constant pool builder belong to this constant pool. + * <p> + * Some {@link ClassFileBuilder} methods may have their outputs adjusted if they + * receive pool entries alien to {@linkplain ClassFileBuilder#constantPool + * their constant pools}. For example, if an {@link ConstantInstruction#ofLoad + * ldc_w} instruction with an alien entry is written to a {@link CodeBuilder}, + * the {@code CodeBuilder} may emit a functionally equivalent {@code ldc} + * instruction instead, if the converted entry can be encoded in such an + * instruction. + * <p> + * To avoid the conversion of alien constant pool entries, such as for the + * accuracy of the generated {@code class} file, users can always supply + * constant pool entries obtained by calling the constant pool builder + * entry-bearing methods of the constant pools associated with the {@code + * ClassFileBuilder}. Otherwise, the conversions have no impact on the + * behaviors of the generated {@code class} files. * + * @see ClassFileBuilder#constantPool() * @since 24 */ public sealed interface ConstantPoolBuilder @@ -55,10 +92,14 @@ public sealed interface ConstantPoolBuilder /** * {@return a new constant pool builder} The new constant pool builder will - * be pre-populated with the contents of the constant pool associated with - * the class reader. + * be pre-populated with the contents of the constant pool {@linkplain + * ClassModel#constantPool() associated with} the given class model. The + * index of new entries will start from the {@link ConstantPool#size() + * size()} of the source pool. * * @param classModel the class to copy from + * @see ClassFile#build(ClassEntry, ConstantPoolBuilder, Consumer) + * @see ClassFile.ConstantPoolSharingOption#SHARED_POOL */ static ConstantPoolBuilder of(ClassModel classModel) { return new SplitConstantPool((ClassReaderImpl) classModel.constantPool()); @@ -66,35 +107,47 @@ static ConstantPoolBuilder of(ClassModel classModel) { /** * {@return a new constant pool builder} The new constant pool builder - * will be empty. + * will be empty. The index of new entries will start from {@code 1}. + * + * @see ClassFile.ConstantPoolSharingOption#NEW_POOL */ static ConstantPoolBuilder of() { return new SplitConstantPool(); } /** - * {@return whether the provided constant pool is index-compatible with this - * one} This may be because they are the same constant pool, or because this - * constant pool was copied from the other. + * {@return {@code true} if the index of any entry in the given constant + * pool refers to the same entry in this builder} This may be because they + * are the same builder, or because this builder was {@linkplain + * #of(ClassModel) pre-populated} from the given constant pool. + * <p> + * If the constant pool of an entry is not directly writable to this pool, + * it is alien to this pool, and a {@link ClassFileBuilder} associated + * with this constant pool will convert that alien constant pool entry. * - * @param constantPool the other constant pool + * @param constantPool the given constant pool + * @see ClassFileBuilder#constantPool() ClassFileBuilder::constantPool + * @see ##alien Alien Constant Pool Entries */ boolean canWriteDirect(ConstantPool constantPool); /** - * {@return A {@link Utf8Entry} describing the provided {@linkplain String}} - * If a UTF8 entry in the pool already describes this string, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the provided {@link String}} * * @param s the string + * @see Utf8Entry#stringValue() Utf8Entry::stringValue */ Utf8Entry utf8Entry(String s); /** - * {@return A {@link Utf8Entry} describing the field descriptor of the provided - * {@linkplain ClassDesc}} - * If a UTF8 entry in the pool already describes this field descriptor, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the {@linkplain + * ClassDesc#descriptorString() field descriptor string} of the provided + * {@link ClassDesc}} + * + * @apiNote + * The resulting {@code Utf8Entry} is usually not {@linkplain + * #classEntry(Utf8Entry) referable by} a {@link ClassEntry}, which uses + * internal form of binary names. * * @param desc the symbolic descriptor for the class */ @@ -103,10 +156,9 @@ default Utf8Entry utf8Entry(ClassDesc desc) { } /** - * {@return A {@link Utf8Entry} describing the method descriptor of the provided - * {@linkplain MethodTypeDesc}} - * If a UTF8 entry in the pool already describes this field descriptor, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link Utf8Entry} describing the {@linkplain + * MethodTypeDesc#descriptorString() method descriptor string} of the + * provided {@link MethodTypeDesc}} * * @param desc the symbolic descriptor for the method type */ @@ -115,25 +167,24 @@ default Utf8Entry utf8Entry(MethodTypeDesc desc) { } /** - * {@return A {@link ClassEntry} describing the class whose internal name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a Class entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ClassEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the internal form + * of the binary name of a class or interface or the field descriptor + * string of an array type. * - * @param ne the constant pool entry describing the internal name of the class + * @param ne the {@code Utf8Entry} + * @see ClassEntry#name() ClassEntry::name */ ClassEntry classEntry(Utf8Entry ne); /** - * {@return A {@link ClassEntry} describing the class described by - * provided {@linkplain ClassDesc}} - * If a Class entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ClassEntry} describing the same reference type + * as the provided {@link ClassDesc}} * - * @param classDesc the symbolic descriptor for the class - * @throws IllegalArgumentException if {@code classDesc} represents a primitive type + * @param classDesc the symbolic descriptor for the reference type + * @throws IllegalArgumentException if {@code classDesc} represents a + * primitive type + * @see ClassEntry#asSymbol() ClassEntry::asSymbol */ default ClassEntry classEntry(ClassDesc classDesc) { if (requireNonNull(classDesc).isPrimitive()) { @@ -145,196 +196,191 @@ default ClassEntry classEntry(ClassDesc classDesc) { } /** - * {@return A {@link PackageEntry} describing the class whose internal name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a Package entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link PackageEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the internal form + * of the name of a package. * - * @param nameEntry the constant pool entry describing the internal name of - * the package + * @param nameEntry the {@code Utf8Entry} + * @see PackageEntry#name() PackageEntry::name */ PackageEntry packageEntry(Utf8Entry nameEntry); /** - * {@return A {@link PackageEntry} describing the class described by - * provided {@linkplain PackageDesc}} - * If a Package entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link PackageEntry} describing the same package as the + * provided {@link PackageDesc}} * - * @param packageDesc the symbolic descriptor for the class + * @param packageDesc the symbolic descriptor for the package + * @see PackageEntry#asSymbol() PackageEntry::asSymbol */ default PackageEntry packageEntry(PackageDesc packageDesc) { return packageEntry(utf8Entry(packageDesc.internalName())); } /** - * {@return A {@link ModuleEntry} describing the module whose name - * is encoded in the provided {@linkplain Utf8Entry}} - * If a module entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ModuleEntry} referring to the provided {@link + * Utf8Entry}} The {@code Utf8Entry} describes the module name. * * @param moduleName the constant pool entry describing the module name + * @see ModuleEntry#name() ModuleEntry::name */ ModuleEntry moduleEntry(Utf8Entry moduleName); /** - * {@return A {@link ModuleEntry} describing the module described by - * provided {@linkplain ModuleDesc}} - * If a module entry in the pool already describes this class, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ModuleEntry} describing the same module as the provided + * {@link ModuleDesc}} * - * @param moduleDesc the symbolic descriptor for the class + * @param moduleDesc the symbolic descriptor for the module + * @see ModuleEntry#asSymbol() ModuleEntry::asSymbol */ default ModuleEntry moduleEntry(ModuleDesc moduleDesc) { return moduleEntry(utf8Entry(moduleDesc.name())); } /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} referring to the provided name and + * type {@link Utf8Entry}} The name {@code Utf8Entry} describes an + * unqualified name or the special name {@value ConstantDescs#INIT_NAME}, + * and the type {@code Utf8Entry} describes a field or method descriptor + * string. * - * @param nameEntry the member name - * @param typeEntry the member field or method descriptor + * @param nameEntry the name {@code Utf8Entry} + * @param typeEntry the type {@code Utf8Entry} + * @see NameAndTypeEntry#name() NameAndTypeEntry::name + * @see NameAndTypeEntry#type() NameAndTypeEntry::type */ NameAndTypeEntry nameAndTypeEntry(Utf8Entry nameEntry, Utf8Entry typeEntry); /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} describing the provided unqualified + * name and field descriptor} * - * @param name the member name - * @param type the symbolic descriptor for a field type + * @param name the unqualified name + * @param type the field descriptor */ default NameAndTypeEntry nameAndTypeEntry(String name, ClassDesc type) { return nameAndTypeEntry(utf8Entry(name), utf8Entry(type)); } /** - * {@return A {@link NameAndTypeEntry} describing the provided name and type} - * If a NameAndType entry in the pool already describes this name and type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link NameAndTypeEntry} describing the provided name and + * method descriptor} The name can be an unqualified name or the + * special name {@value ConstantDescs#INIT_NAME}. * - * @param name the member name - * @param type the symbolic descriptor for a method type + * @param name the unqualified name, or {@value ConstantDescs#INIT_NAME} + * @param type the method descriptor */ default NameAndTypeEntry nameAndTypeEntry(String name, MethodTypeDesc type) { return nameAndTypeEntry(utf8Entry(name), utf8Entry(type)); } /** - * {@return A {@link FieldRefEntry} describing a field of a class} - * If a FieldRef entry in the pool already describes this field, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link FieldRefEntry} referring to a {@link ClassEntry} and a + * {@link NameAndTypeEntry}} The {@code ClassEntry} describes a class or + * interface that has this field as a member, and the {@code + * NameAndTypeEntry} describes the unqualified name and the field descriptor + * for this field. * - * @param owner the class the field is a member of - * @param nameAndType the name and type of the field + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see FieldRefEntry#owner() FieldRefEntry::owner + * @see FieldRefEntry#nameAndType() FieldRefEntry::nameAndType */ FieldRefEntry fieldRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link FieldRefEntry} describing a field of a class} - * If a FieldRef entry in the pool already describes this field, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link FieldRefEntry} describing a field of a class} * - * @param owner the class the field is a member of - * @param name the name of the field - * @param type the type of the field + * @param owner the class or interface the field is a member of + * @param name the unqualified name of the field + * @param type the field descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see FieldRefEntry#typeSymbol() FieldRefEntry::typeSymbol */ default FieldRefEntry fieldRefEntry(ClassDesc owner, String name, ClassDesc type) { return fieldRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link MethodRefEntry} describing a method of a class} - * If a MethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodRefEntry} referring to a {@link ClassEntry} and a + * {@link NameAndTypeEntry}} The {@code ClassEntry} describes a class that + * has this method as a member, and the {@code NameAndTypeEntry} describes + * the unqualified name or the special name {@value ConstantDescs#INIT_NAME} + * and the method descriptor for this method. * - * @param owner the class the method is a member of - * @param nameAndType the name and type of the method + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see MethodRefEntry#owner() MethodRefEntry::owner + * @see MethodRefEntry#nameAndType() MethodRefEntry::nameAndType */ MethodRefEntry methodRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link MethodRefEntry} describing a method of a class} - * If a MethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodRefEntry} describing a method of a class} * * @param owner the class the method is a member of - * @param name the name of the method - * @param type the type of the method + * @param name the unqualified name, or special name {@value + * ConstantDescs#INIT_NAME}, of the method + * @param type the method descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see MethodRefEntry#typeSymbol() MethodRefEntry::typeSymbol */ default MethodRefEntry methodRefEntry(ClassDesc owner, String name, MethodTypeDesc type) { return methodRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link InterfaceMethodRefEntry} describing a method of a class} - * If a InterfaceMethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InterfaceMethodRefEntry} referring to a {@link + * ClassEntry} and a {@link NameAndTypeEntry}} The {@code ClassEntry} + * describes an interface that has this method as a member, and the {@code + * NameAndTypeEntry} describes the unqualified name and the method + * descriptor for this method. * - * @param owner the class the method is a member of - * @param nameAndType the name and type of the method + * @param owner the {@code ClassEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see InterfaceMethodRefEntry#owner() InterfaceMethodRefEntry::owner + * @see InterfaceMethodRefEntry#nameAndType() + * InterfaceMethodRefEntry::nameAndType */ InterfaceMethodRefEntry interfaceMethodRefEntry(ClassEntry owner, NameAndTypeEntry nameAndType); /** - * {@return A {@link InterfaceMethodRefEntry} describing a method of a class} - * If a InterfaceMethodRefEntry entry in the pool already describes this method, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InterfaceMethodRefEntry} describing a method of an + * interface} * - * @param owner the class the method is a member of - * @param name the name of the method - * @param type the type of the method + * @param owner the interface the method is a member of + * @param name the unqualified name of the method + * @param type the method descriptor * @throws IllegalArgumentException if {@code owner} represents a primitive type + * @see InterfaceMethodRefEntry#typeSymbol() InterfaceMethodRefEntry::typeSymbol */ default InterfaceMethodRefEntry interfaceMethodRefEntry(ClassDesc owner, String name, MethodTypeDesc type) { return interfaceMethodRefEntry(classEntry(owner), nameAndTypeEntry(name, type)); } /** - * {@return A {@link MethodTypeEntry} describing a method type} - * If a MethodType entry in the pool already describes this method type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodTypeEntry} describing the same method type as + * the provided {@link MethodTypeDesc}} * * @param descriptor the symbolic descriptor of the method type + * @see MethodTypeEntry#asSymbol() MethodTypeEntry::asSymbol */ MethodTypeEntry methodTypeEntry(MethodTypeDesc descriptor); /** - * {@return A {@link MethodTypeEntry} describing a method type} - * If a MethodType entry in the pool already describes this method type, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodTypeEntry} referring to a {@link Utf8Entry}} + * The {@code Utf8Entry} represents a method descriptor string. * - * @param descriptor the constant pool entry for the method type descriptor + * @param descriptor the {@code Utf8Entry} + * @see MethodTypeEntry#descriptor() MethodTypeEntry::descriptor */ MethodTypeEntry methodTypeEntry(Utf8Entry descriptor); /** - * {@return A {@link MethodHandleEntry} describing a direct method handle} - * If a MethodHandle entry in the pool already describes this method handle, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodHandleEntry} describing the same method handle as + * the given {@link DirectMethodHandleDesc}} * * @param descriptor the symbolic descriptor of the method handle + * @see MethodHandleEntry#asSymbol() MethodHandleEntry::asSymbol */ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { var owner = classEntry(descriptor.owner()); @@ -347,125 +393,133 @@ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { } /** - * {@return A {@link MethodHandleEntry} describing a field accessor or method} - * If a MethodHandle entry in the pool already describes this method handle, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link MethodHandleEntry} encoding a reference kind and + * referring to a {@link MemberRefEntry}} The reference kind must be + * in {@code [1, 9]}, and the {@code MemberRefEntry} is subject to + * various restrictions based on the reference kind (JVMS {@jvms 4.4.8}). * - * @param refKind the reference kind of the method handle (JVMS {@jvms 4.4.8}) - * @param reference the constant pool entry describing the field or method + * @param refKind the reference kind of the method handle + * @param reference the {@code MemberRefEntry} + * @see MethodHandleInfo##refKinds Reference kinds + * @see MethodHandleEntry#kind() MethodHandleEntry::kind + * @see MethodHandleEntry#reference() MethodHandleEntry::reference */ MethodHandleEntry methodHandleEntry(int refKind, MemberRefEntry reference); /** - * {@return An {@link InvokeDynamicEntry} describing a dynamic call site} - * If an InvokeDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InvokeDynamicEntry} describing the same dynamic call + * site as the provided {@link DynamicCallSiteDesc}} * - * @param dcsd the symbolic descriptor of the method handle + * @param dcsd the symbolic descriptor of the dynamic call site + * @see InvokeDynamicEntry#asSymbol() InvokeDynamicEntry::asSymbol */ default InvokeDynamicEntry invokeDynamicEntry(DynamicCallSiteDesc dcsd) { return invokeDynamicEntry(bsmEntry((DirectMethodHandleDesc)dcsd.bootstrapMethod(), List.of(dcsd.bootstrapArgs())), nameAndTypeEntry(dcsd.invocationName(), dcsd.invocationType())); } /** - * {@return An {@link InvokeDynamicEntry} describing a dynamic call site} - * If an InvokeDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return an {@link InvokeDynamicEntry} referring to a {@link + * BootstrapMethodEntry} and a {@link NameAndTypeEntry}} + * The {@code BootstrapMethodEntry} describes the bootstrap method + * and its invocation arguments in addition to the name and type, + * and the {@code NameAndTypeEntry} a name and a method descriptor. * - * @param bootstrapMethodEntry the entry in the bootstrap method table - * @param nameAndType the invocation name and type + * @param bootstrapMethodEntry the {@code BootstrapMethodEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see InvokeDynamicEntry#bootstrap() InvokeDynamicEntry::bootstrap + * @see InvokeDynamicEntry#nameAndType() InvokeDynamicEntry::nameAndType */ InvokeDynamicEntry invokeDynamicEntry(BootstrapMethodEntry bootstrapMethodEntry, NameAndTypeEntry nameAndType); /** - * {@return A {@link ConstantDynamicEntry} describing a dynamic constant} - * If a ConstantDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ConstantDynamicEntry} describing the dynamic constant + * as the provided {@link DynamicConstantDesc}} * * @param dcd the symbolic descriptor of the constant + * @see ConstantDynamicEntry#asSymbol() ConstantDynamicEntry::asSymbol */ default ConstantDynamicEntry constantDynamicEntry(DynamicConstantDesc<?> dcd) { return constantDynamicEntry(bsmEntry(dcd.bootstrapMethod(), List.of(dcd.bootstrapArgs())), nameAndTypeEntry(dcd.constantName(), dcd.constantType())); } /** - * {@return A {@link ConstantDynamicEntry} describing a dynamic constant} - * If a ConstantDynamic entry in the pool already describes this site, - * it is returned; otherwise, a new entry is added and the new entry is - * returned. + * {@return a {@link ConstantDynamicEntry} referring to a {@link + * BootstrapMethodEntry} and a {@link NameAndTypeEntry}} + * The {@code BootstrapMethodEntry} describes the bootstrap method + * and its invocation arguments in addition to the name and type, + * and the {@code NameAndTypeEntry} a name and a field descriptor. * - * @param bootstrapMethodEntry the entry in the bootstrap method table - * @param nameAndType the invocation name and type + * @param bootstrapMethodEntry the {@code BootstrapMethodEntry} + * @param nameAndType the {@code NameAndTypeEntry} + * @see ConstantDynamicEntry#bootstrap() ConstantDynamicEntry::bootstrap + * @see ConstantDynamicEntry#nameAndType() ConstantDynamicEntry::nameAndType */ ConstantDynamicEntry constantDynamicEntry(BootstrapMethodEntry bootstrapMethodEntry, NameAndTypeEntry nameAndType); /** - * {@return An {@link IntegerEntry} describing the provided value} - * If an integer entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return an {@link IntegerEntry} describing the provided value} * * @param value the value + * @see IntegerEntry#intValue() IntegerEntry::intValue */ IntegerEntry intEntry(int value); /** - * {@return A {@link FloatEntry} describing the provided value} - * If a float entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link FloatEntry} describing the provided value} * * @param value the value + * @see FloatEntry#floatValue() FloatEntry::floatValue */ FloatEntry floatEntry(float value); /** - * {@return A {@link LongEntry} describing the provided value} - * If a long entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link LongEntry} describing the provided value} * * @param value the value + * @see LongEntry#longValue() LongEntry::longValue */ LongEntry longEntry(long value); /** - * {@return A {@link DoubleEntry} describing the provided value} - * If a double entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link DoubleEntry} describing the provided value} * * @param value the value + * @see DoubleEntry#doubleValue() DoubleEntry::doubleValue */ DoubleEntry doubleEntry(double value); /** - * {@return A {@link StringEntry} referencing the provided UTF8 entry} - * If a String entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link StringEntry} referring to a {@link Utf8Entry}} + * The {@code Utf8Entry} describes the string value. * - * @param utf8 the UTF8 entry describing the string + * @param utf8 the {@code Utf8Entry} + * @see StringEntry#utf8() StringEntry::utf8 */ StringEntry stringEntry(Utf8Entry utf8); /** - * {@return A {@link StringEntry} describing the provided value} - * If a string entry in the pool already describes this value, it is returned; - * otherwise, a new entry is added and the new entry is returned. + * {@return a {@link StringEntry} describing the provided value} * * @param value the value + * @see StringEntry#stringValue() StringEntry::stringValue */ default StringEntry stringEntry(String value) { return stringEntry(utf8Entry(value)); } /** - * {@return A {@link ConstantValueEntry} describing the provided - * Integer, Long, Float, Double, or String constant} + * {@return a {@link ConstantValueEntry} describing the provided constant + * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, or {@link + * String} value} * - * @param c the constant - * @see ConstantValueEntry#constantValue() + * @param c the provided constant value + * @throws IllegalArgumentException if the value is not one of {@code + * Integer}, {@code Long}, {@code Float}, {@code Double}, or {@code + * String} + * @see ConstantValueEntry#constantValue() ConstantValueEntry::constantValue + * @see ConstantValueAttribute#of(ConstantDesc) + * ConstantValueAttribute::of(ConstantDesc) */ default ConstantValueEntry constantValueEntry(ConstantDesc c) { if (c instanceof Integer i) return intEntry(i); @@ -477,13 +531,10 @@ default ConstantValueEntry constantValueEntry(ConstantDesc c) { } /** - * {@return A {@link LoadableConstantEntry} describing the provided - * constant} The constant should be an Integer, String, Long, Float, - * Double, ClassDesc (for a Class constant), MethodTypeDesc (for a MethodType - * constant), DirectMethodHandleDesc (for a MethodHandle constant), or - * a DynamicConstantDesc (for a dynamic constant.) + * {@return a {@link LoadableConstantEntry} describing the provided constant + * value} * - * @param c the constant + * @param c the nominal descriptor for the constant */ default LoadableConstantEntry loadableConstantEntry(ConstantDesc c) { if (c instanceof Integer i) return intEntry(i); @@ -500,10 +551,10 @@ default LoadableConstantEntry loadableConstantEntry(ConstantDesc c) { /** * {@return a {@link BootstrapMethodEntry} describing the provided - * bootstrap method and static arguments} + * bootstrap method and arguments} * * @param methodReference the bootstrap method - * @param arguments the bootstrap arguments + * @param arguments the arguments */ default BootstrapMethodEntry bsmEntry(DirectMethodHandleDesc methodReference, List<ConstantDesc> arguments) { @@ -512,11 +563,16 @@ default BootstrapMethodEntry bsmEntry(DirectMethodHandleDesc methodReference, } /** - * {@return a {@link BootstrapMethodEntry} describing the provided - * bootstrap method and static arguments} + * {@return a {@link BootstrapMethodEntry} referring to a {@link + * MethodHandleEntry} and a list of {@link LoadableConstantEntry}} + * The {@code MethodHandleEntry} is the bootstrap method, and the + * list of {@code LoadableConstantEntry} is the arguments. * - * @param methodReference the bootstrap method - * @param arguments the bootstrap arguments + * @param methodReference the {@code MethodHandleEntry} + * @param arguments the list of {@code LoadableConstantEntry} + * @see BootstrapMethodEntry#bootstrapMethod() + * BootstrapMethodEntry::bootstrapMethod + * @see BootstrapMethodEntry#arguments() BootstrapMethodEntry::arguments */ BootstrapMethodEntry bsmEntry(MethodHandleEntry methodReference, List<LoadableConstantEntry> arguments); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java index ce5ed26c4c9..bb3b33ba21c 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,9 @@ /** * Thrown to indicate that requested entry cannot be obtained from the constant - * pool. + * pool or the bootstrap method table. This is also thrown when the lazy + * evaluation of constant pool or bootstrap method table entries encounter + * format errors. * * @since 24 */ @@ -47,7 +49,8 @@ public ConstantPoolException() { * Constructs a {@code ConstantPoolException} with the specified detail * message. * - * @param message the detail message. + * @param message the detail message, may be {@code null} for no detail + * message */ public ConstantPoolException(String message) { super(message); @@ -55,11 +58,10 @@ public ConstantPoolException(String message) { /** * Constructs a {@code ConstantPoolException} with the specified cause and - * a detail message of {@code (cause==null ? null : cause.toString())}. - * @param cause the cause (which is saved for later retrieval by the - * {@link Throwable#getCause()} method). (A {@code null} value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) + * a detail message of {@code cause == null ? null : cause.toString()}. + * + * @param cause the cause, may be {@code null} for nonexistent or unknown + * cause */ public ConstantPoolException(Throwable cause) { super(cause); @@ -69,12 +71,10 @@ public ConstantPoolException(Throwable cause) { * Constructs a {@code ConstantPoolException} with the specified detail * message and cause. * - * @param message the detail message (which is saved for later retrieval - * by the {@link Throwable#getMessage()} method). - * @param cause the cause (which is saved for later retrieval by the - * {@link Throwable#getCause()} method). (A {@code null} value - * is permitted, and indicates that the cause is nonexistent or - * unknown.) + * @param message the detail message, may be {@code null} for no detail + * message + * @param cause the cause, may be {@code null} for nonexistent or unknown + * cause */ public ConstantPoolException(String message, Throwable cause) { super(message, cause); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java index ae746042aa4..8613fdd2cb9 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,11 @@ import java.lang.constant.ConstantDesc; /** - * Models a constant pool entry that can be used as the constant in a - * {@link Attributes#constantValue() ConstantValue} attribute; this includes the four - * primitive constant types and {@linkplain String} constants. + * Marker interface for constant pool entries that can represent constant values + * in the {@link Attributes#constantValue() ConstantValue} attribute. * + * @see ConstantPoolBuilder#constantValueEntry + * ConstantPoolBuilder::constantValueEntry * @sealedGraph * @since 24 */ @@ -39,8 +40,8 @@ public sealed interface ConstantValueEntry extends LoadableConstantEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, StringEntry { /** - * {@return the constant value} The constant value will be an {@link Integer}, - * {@link Long}, {@link Float}, {@link Double}, or {@link String}. + * {@return the constant value} The constant value will be an {@link + * Integer}, {@link Long}, {@link Float}, {@link Double}, or {@link String}. * * @see ConstantPoolBuilder#constantValueEntry(ConstantDesc) */ diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java index ebc3a837bb0..bc6956b5bf5 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,20 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Double_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures + * Models a {@code CONSTANT_Double_info} structure, representing a {@code + * double} constant, in the constant pool of a {@code class} file. + * <p> + * The use of a {@code DoubleEntry} is modeled by a {@code double}. Conversions + * are through {@link ConstantPoolBuilder#doubleEntry} and {@link #doubleValue()}. + * In the conversions, all NaN values of the {@code double} may be collapsed + * into a single {@linkplain Double#NaN "canonical" NaN value}. + * <p> + * A double entry has a {@linkplain #width() width} of {@code 2}, making its + * subsequent constant pool index valid and unusable. * + * @see ConstantPoolBuilder#doubleEntry ConstantPoolBuilder::doubleEntry + * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} + * Structures * @since 24 */ public sealed interface DoubleEntry @@ -40,13 +50,13 @@ public sealed interface DoubleEntry permits AbstractPoolEntry.DoubleEntryImpl { /** - * {@return the double value} + * {@return the {@code double} value} + * + * @see ConstantPoolBuilder#doubleEntry(double) + * ConstantPoolBuilder::doubleEntry(double) */ double doubleValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.DOUBLE; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java index 3ec4fbbdbee..b72424db44e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,27 @@ import java.lang.classfile.BootstrapMethodEntry; /** - * Models a dynamic constant pool entry, which is either {@link ConstantDynamicEntry} - * or {@link InvokeDynamicEntry}. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Superinterface modeling dynamically-computed constant pool entries, which + * include {@link ConstantDynamicEntry} and {@link InvokeDynamicEntry}, in the + * constant pool of a {@code class} file. + * <p> + * Different types of dynamically-computed constant pool entries bear structural + * similarities, but they appear in distinct locations. As a result, their uses + * are represented by different symbolic descriptors, specific to each subtype. + * <p> + * A dynamic constant entry is composite: + * {@snippet lang=text : + * DynamicConstantPoolEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } * + * @see java.lang.invoke##jvm_mods Dynamic resolution of call sites and + * constants + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures + * @jvms 5.4.3.6 Dynamically-Computed Constant and Call Site Resolution * @sealedGraph * @since 24 */ @@ -39,28 +56,50 @@ public sealed interface DynamicConstantPoolEntry extends PoolEntry /** * {@return the entry in the bootstrap method table for this constant} + * + * @see java.lang.invoke##bsm Execution of bootstrap methods + * @see ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * @see ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) */ BootstrapMethodEntry bootstrap(); /** - * {@return index of the entry in the bootstrap method table for this constant} + * {@return index of the entry in the bootstrap method table for this + * constant} The return value is equivalent to {@code + * bootstrap().bsmIndex()}. */ int bootstrapMethodIndex(); /** - * {@return the invocation name and type} + * {@return the name and the descriptor string indicated by this symbolic + * reference} + * + * @see java.lang.invoke##bsm Execution of bootstrap methods + * @see ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * @see ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) + * ConstantPoolBuilder::invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) */ NameAndTypeEntry nameAndType(); /** - * {@return the invocation name} + * {@return the name indicated by this symbolic reference} */ default Utf8Entry name() { return nameAndType().name(); } /** - * {@return the invocation type} + * {@return the descriptor string indicated by this symbolic reference} + * This is a field descriptor string if this entry is a {@link + * ConstantDynamicEntry}, or a method descriptor string if this entry is a + * {@link InvokeDynamicEntry}. + * + * @apiNote + * Each subinterface has its specific accessor named {@code typeSymbol} for + * the symbolic descriptor derived from this descriptor string. */ default Utf8Entry type() { return nameAndType().type(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java index 47f5b6710d8..9f984acd7ba 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,17 +30,31 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_Fieldref_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_Fieldref_info} structure, or a symbolic reference + * to a field, in the constant pool of a {@code class} file. + * <p> + * A field reference constant pool entry is composite: + * {@snippet lang=text : + * // @link substring="FieldRefEntry" target="ConstantPoolBuilder#fieldRefEntry(ClassEntry, NameAndTypeEntry)" : + * FieldRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() nameAndType.type()} represents a {@linkplain + * #typeSymbol() field descriptor} string. * + * @see ConstantPoolBuilder#fieldRefEntry ConstantPoolBuilder::fieldRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface FieldRefEntry extends MemberRefEntry permits AbstractPoolEntry.FieldRefEntryImpl { /** - * {@return a symbolic descriptor for the field's type} + * {@return a symbolic descriptor for the {@linkplain #type() field type}} */ default ClassDesc typeSymbol() { return Util.fieldTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java index eeb44e92b7c..2ccf3fb94e4 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,17 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Float_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures + * Models a {@code CONSTANT_Float_info} structure, or a {@code float} constant, + * in the constant pool of a {@code class} file. + * <p> + * The use of a {@code FloatEntry} is modeled by a {@code float}. Conversions + * are through {@link ConstantPoolBuilder#floatEntry} and {@link #floatValue()}. + * In the conversions, all NaN values of the {@code float} may be collapsed into + * a single {@linkplain Float#NaN "canonical" NaN value}. * + * @see ConstantPoolBuilder#floatEntry ConstantPoolBuilder::floatEntry + * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} + * Structures * @since 24 */ public sealed interface FloatEntry @@ -40,14 +47,12 @@ public sealed interface FloatEntry permits AbstractPoolEntry.FloatEntryImpl { /** - * {@return the float value} + * {@return the {@code float} value} + * + * @see ConstantPoolBuilder#floatEntry(float) */ - float floatValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.FLOAT; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java index 908f17d1cb7..d6d2c28ed57 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,15 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Integer_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures + * Models a {@code CONSTANT_Integer_info} structure, or an {@code int} constant, + * in the constant pool of a {@code class} file. + * <p> + * The use of a {@code IntegerEntry} is modeled by an {@code int}. Conversions + * are through {@link ConstantPoolBuilder#intEntry(int)} and {@link #intValue()}. * + * @see ConstantPoolBuilder#intEntry ConstantPoolBuilder::intEntry + * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} + * Structures * @since 24 */ public sealed interface IntegerEntry @@ -40,13 +45,12 @@ public sealed interface IntegerEntry permits AbstractPoolEntry.IntegerEntryImpl { /** - * {@return the integer value} + * {@return the {@code int} value} + * + * @see ConstantPoolBuilder#intEntry(int) */ int intValue(); - /** - * {@return the type of the constant} - */ @Override default TypeKind typeKind() { return TypeKind.INT; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java index 7b1a94f123a..e29c9f5b6f9 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,10 +30,26 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_InterfaceMethodRef_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_InterfaceMethodRef_info} structure, or a symbolic + * reference to an interface method, in the constant pool of a {@code class} + * file. + * <p> + * An interface method reference entry is composite: + * {@snippet lang=text : + * // @link substring="InterfaceMethodRefEntry" target="ConstantPoolBuilder#interfaceMethodRefEntry(ClassEntry, NameAndTypeEntry)" : + * InterfaceMethodRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() type} in the {@code nameAndType} is a {@linkplain + * #typeSymbol() method descriptor} string. * + * @see ConstantPoolBuilder#interfaceMethodRefEntry + * ConstantPoolBuilder::interfaceMethodRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface InterfaceMethodRefEntry @@ -41,7 +57,7 @@ public sealed interface InterfaceMethodRefEntry permits AbstractPoolEntry.InterfaceMethodRefEntryImpl { /** - * {@return a symbolic descriptor for the interface method's type} + * {@return a symbolic descriptor for the {@linkplain #type() method type}} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java index 0cc8b6823df..02c2fce2e02 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,38 @@ import jdk.internal.classfile.impl.Util; /** - * Models a constant pool entry for a dynamic call site. - * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures + * Models a {@code CONSTANT_InvokeDynamic_info} structure, or the symbolic + * reference to a <dfn>{@index "dynamically-computed call site"}</dfn>, in the + * constant pool of a {@code class} file. + * <p> + * The use of a {@code InvokeDynamicEntry} is modeled by a {@link + * DynamicCallSiteDesc} symbolic descriptor. It can be obtained from {@link + * #asSymbol() InvokeDynamicEntry::asSymbol} and converted back to a constant + * pool entry through {@link ConstantPoolBuilder#invokeDynamicEntry(DynamicCallSiteDesc) + * ConstantPoolBuilder::invokeDynamicEntry}. + * <p> + * An invoke dynamic entry is composite: + * {@snippet lang=text : + * // @link substring="InvokeDynamicEntry" target="ConstantPoolBuilder#invokeDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)" : + * InvokeDynamicEntry( + * BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the {@link #type() type} in the {@code nameAndType} is a {@linkplain + * #typeSymbol() method descriptor} string. * + * @apiNote + * A dynamically-computed call site is frequently called a <dfn>{@index "dynamic + * call site"}</dfn>, or an <dfn>{@index "indy"}</dfn>, from the abbreviation of + * "invoke dynamic". + * + * @see ConstantPoolBuilder#invokeDynamicEntry + * ConstantPoolBuilder::invokeDynamicEntry + * @see DynamicCallSiteDesc + * @see java.lang.invoke##indyinsn Dynamically-computed call sites + * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code + * CONSTANT_InvokeDynamic_info} Structures * @since 24 */ public sealed interface InvokeDynamicEntry @@ -42,14 +71,18 @@ public sealed interface InvokeDynamicEntry permits AbstractPoolEntry.InvokeDynamicEntryImpl { /** - * {@return a symbolic descriptor for the call site's invocation type} + * {@return a symbolic descriptor for the {@linkplain #type() invocation + * type} of this dynamic call site} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); } /** - * {@return a symbolic descriptor for the dynamic call site} + * {@return a symbolic descriptor for this dynamic call site} + * + * @see ConstantPoolBuilder#invokeDynamicEntry(DynamicCallSiteDesc) + * ConstantPoolBuilder::invokeDynamicEntry(DynamicCallSiteDesc) */ default DynamicCallSiteDesc asSymbol() { return DynamicCallSiteDesc.of(bootstrap().bootstrapMethod().asSymbol(), diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java index 32f85f64c7e..9137bebea35 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,13 +24,22 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.Opcode; import java.lang.classfile.TypeKind; +import java.lang.classfile.instruction.ConstantInstruction; import java.lang.constant.ConstantDesc; /** * Marker interface for constant pool entries suitable for loading via the - * {@code LDC} instructions. + * {@link ConstantInstruction.LoadConstantInstruction ldc} instructions. + * <p> + * The use of a {@code LoadableConstantEntry} is modeled by a {@link ConstantDesc}. + * Conversions are through {@link ConstantPoolBuilder#loadableConstantEntry(ConstantDesc)} + * and {@link #constantValue()}. * + * @see CodeBuilder#ldc(LoadableConstantEntry) + * @jvms 4.4 The Constant Pool * @sealedGraph * @since 24 */ @@ -38,12 +47,19 @@ public sealed interface LoadableConstantEntry extends PoolEntry permits ClassEntry, ConstantDynamicEntry, ConstantValueEntry, MethodHandleEntry, MethodTypeEntry { /** - * {@return the constant described by this entry} + * {@return a symbolic descriptor of this constant} + * + * @see ConstantPoolBuilder#loadableConstantEntry(ConstantDesc) */ ConstantDesc constantValue(); /** - * {@return the type of the constant} + * {@return the data type of this constant} + * <p> + * If the data type is of {@linkplain TypeKind#slotSize() category} 2, this + * constant must be loaded with {@link Opcode#LDC2_W ldc2_w}; otherwise, the + * data type is of category 1, and this constant must be loaded with {@link + * Opcode#LDC ldc} or {@link Opcode#LDC_W ldc_w}. */ default TypeKind typeKind() { return TypeKind.REFERENCE; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java index cd38dcfe014..dbf947d1f1d 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,18 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Long_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures + * Models a {@code CONSTANT_Long_info} structure, or a {@code long} constant, in + * the constant pool of a {@code class} file. + * <p> + * The use of a {@code LongEntry} is modeled by a {@code long}. Conversions are + * through {@link ConstantPoolBuilder#longEntry(long)} and {@link #longValue()}. + * <p> + * A long entry has a {@linkplain #width() width} of {@code 2}, making its + * subsequent constant pool index valid and unusable. * + * @see ConstantPoolBuilder#longEntry ConstantPoolBuilder::longEntry + * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} + * Structures * @since 24 */ public sealed interface LongEntry @@ -40,7 +48,10 @@ public sealed interface LongEntry permits AbstractPoolEntry.LongEntryImpl { /** - * {@return the long value} + * {@return the {@code long} value} + * + * @see ConstantPoolBuilder#longEntry(long) + * ConstantPoolBuilder::longEntry(long) */ long longValue(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java index 12d68796dd7..3d59a3c96c9 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,24 +24,45 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.Opcode; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a member reference constant in the constant pool of a classfile, - * which includes references to fields, methods, and interface methods. + * Superinterface modeling symbolic references to a member of a class or interface + * in the constant pool of a {@code class} file, which include references to + * {@linkplain FieldRefEntry fields}, {@linkplain MethodRefEntry class methods}, + * and {@linkplain InterfaceMethodRefEntry interface methods}. + * <p> + * Different types of symbolic references to a member of a class or interface + * bear structural similarities and share parts of the resolution processes, and + * they can sometimes appear in the same locations. For example, both {@link + * MethodRefEntry} and {@link InterfaceMethodRefEntry} can appear in an {@link + * Opcode#INVOKESTATIC invokestatic} instruction. + * <p> + * A member reference entry is composite: + * {@snippet lang=text : + * MemberRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } * + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @sealedGraph * @since 24 */ public sealed interface MemberRefEntry extends PoolEntry permits FieldRefEntry, InterfaceMethodRefEntry, MethodRefEntry, AbstractPoolEntry.AbstractMemberRefEntry { /** - * {@return the class in which this member ref lives} + * {@return the class or interface which this member belongs to} */ ClassEntry owner(); /** - * {@return the name and type of the member} + * {@return the name and descriptor string of the member} */ NameAndTypeEntry nameAndType(); @@ -53,7 +74,14 @@ default Utf8Entry name() { } /** - * {@return the type of the member} + * {@return the descriptor string of the member} This is a field descriptor + * string if this entry is a {@link FieldRefEntry}, or a method descriptor + * string if this entry is a {@link MethodRefEntry} or {@link + * InterfaceMethodRefEntry}. + * + * @apiNote + * Each subinterface defines a {@code typeSymbol()} accessor for the + * symbolic descriptor for the member type. */ default Utf8Entry type() { return nameAndType().type(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java index d2e08ef178c..22c07236e8a 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,13 +26,35 @@ import java.lang.constant.ConstantDesc; import java.lang.constant.DirectMethodHandleDesc; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleInfo; import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_MethodHandle_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure + * Models a {@code CONSTANT_MethodHandle_info} structure, or a symbolic + * reference to a {@linkplain MethodHandle method handle}, in the constant pool + * of a {@code class} file. The method handle directly accesses an accessible + * method, field, or constructor. + * <p> + * The use of a {@code MethodHandleEntry} is modeled by a {@link + * DirectMethodHandleDesc}. Conversions are through {@link + * ConstantPoolBuilder#methodHandleEntry(DirectMethodHandleDesc)} and {@link + * #asSymbol()}. + * <p> + * A method handle entry is composite: + * {@snippet lang=text : + * // @link substring="MethodHandleEntry" target="ConstantPoolBuilder#methodHandleEntry(int, MemberRefEntry)" : + * MethodHandleEntry( + * int refKind, // @link substring="refKind" target="#kind()" + * MemberRefEntry reference // @link substring="reference" target="#reference()" + * ) + * } + * where {@code refKind} is in the range {@code [1, 9]}. + * + * @see ConstantPoolBuilder#methodHandleEntry + * ConstantPoolBuilder::methodHandleEntry + * @jvms 4.4.8 The {@code CONSTANT_MethodHandle_info} Structure * * @since 24 */ @@ -40,6 +62,11 @@ public sealed interface MethodHandleEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodHandleEntryImpl { + /** + * {@inheritDoc} + * <p> + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); @@ -47,17 +74,22 @@ default ConstantDesc constantValue() { /** * {@return the reference kind of this method handle (JVMS {@jvms 4.4.8})} - * @see java.lang.invoke.MethodHandleInfo + * + * @see MethodHandleInfo##refkinds Reference kinds */ int kind(); /** - * {@return the constant pool entry describing the method} + * {@return the constant pool entry describing the field or method, + * according to the {@linkplain #kind() reference kind}} */ MemberRefEntry reference(); /** * {@return a symbolic descriptor for this method handle} + * + * @see ConstantPoolBuilder#methodHandleEntry(DirectMethodHandleDesc) + * ConstantPoolBuilder::methodHandleEntry(DirectMethodHandleDesc) */ DirectMethodHandleDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java index 5be9e88fa2f..29503741ec3 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,17 +30,31 @@ import jdk.internal.classfile.impl.Util; /** - * Models a {@code CONSTANT_MethodRef_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures + * Models a {@code CONSTANT_MethodRef_info} structure, or a symbolic reference + * to a class method, in the constant pool of a {@code class} file. + * <p> + * A class method reference entry is composite: + * {@snippet lang=text : + * // @link substring="MethodRefEntry" target="ConstantPoolBuilder#methodRefEntry(ClassEntry, NameAndTypeEntry)" : + * MethodRefEntry( + * ClassEntry owner, // @link substring="owner" target="#owner()" + * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" + * ) + * } + * where the type in the {@code NameAndTypeEntry} is a {@linkplain #typeSymbol() + * method descriptor} string. * + * @see ConstantPoolBuilder#methodRefEntry ConstantPoolBuilder::methodRefEntry + * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code + * CONSTANT_Methodref_info}, and {@code + * CONSTANT_InterfaceMethodref_info} Structures * @since 24 */ public sealed interface MethodRefEntry extends MemberRefEntry permits AbstractPoolEntry.MethodRefEntryImpl { /** - * {@return a symbolic descriptor for the method's type} + * {@return a symbolic descriptor for the {@linkplain #type() method type}} */ default MethodTypeDesc typeSymbol() { return Util.methodTypeSymbol(type()); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java index b6fad856358..5da36502678 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,28 +30,46 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_MethodType_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.9 The CONSTANT_MethodType_info Structure + * Models a {@code CONSTANT_MethodType_info} structure, or a symbolic reference + * to a method type, in the constant pool of a {@code class} file. + * <p> + * The use of a {@code MethodTypeEntry} is modeled by a {@link MethodTypeDesc}. + * Conversions are through {@link ConstantPoolBuilder#methodTypeEntry(MethodTypeDesc)} + * and {@link #asSymbol()}. + * <p> + * A method type entry is composite: + * {@snippet lang=text : + * // @link substring="MethodTypeEntry" target="ConstantPoolBuilder#methodTypeEntry(Utf8Entry)" : + * MethodTypeEntry(Utf8Entry descriptor) // @link substring="descriptor" target="#descriptor()" + * } + * where {@code descriptor} is a {@linkplain #asSymbol() method descriptor} + * string. * + * @jvms 4.4.9 The {@code CONSTANT_MethodType_info} Structure * @since 24 */ public sealed interface MethodTypeEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodTypeEntryImpl { + /** + * {@inheritDoc} + * <p> + * This is equivalent to {@link #asSymbol() asSymbol()}. + */ @Override default ConstantDesc constantValue() { return asSymbol(); } /** - * {@return the constant pool entry describing the method type} + * {@return the {@linkplain #asSymbol() method descriptor} string} */ Utf8Entry descriptor(); /** - * {@return a symbolic descriptor for the method type} + * {@return a symbolic descriptor for the {@linkplain #descriptor() method + * type}} */ MethodTypeDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java index d0cdae5678f..fd920aa1231 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,21 +29,32 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Module_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.11 The CONSTANT_Module_info Structure + * Models a {@code CONSTANT_Module_info} structure, denoting a module, in the + * constant pool of a {@code class} file. + * <p> + * The use of a {@code ModuleEntry} is modeled by a {@link ModuleDesc}. + * Conversions are through {@link ConstantPoolBuilder#moduleEntry(ModuleDesc)} + * and {@link #asSymbol()}. + * <p> + * A module entry is composite: + * {@snippet lang=text : + * // @link substring="ModuleEntry" target="ConstantPoolBuilder#moduleEntry(Utf8Entry)" : + * ModuleEntry(Utf8Entry name) // @link substring="name" target="#name()" + * } + * where {@code name} is a {@linkplain #asSymbol() module name}. * + * @jvms 4.4.11 The {@code CONSTANT_Module_info} Structure * @since 24 */ public sealed interface ModuleEntry extends PoolEntry permits AbstractPoolEntry.ModuleEntryImpl { /** - * {@return the name of the module} + * {@return the name of the {@linkplain #asSymbol() module}} */ Utf8Entry name(); /** - * {@return a symbolic descriptor for the module} + * {@return a symbolic descriptor for the {@linkplain #name() module name}} */ ModuleDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java index eff7e3456d1..38a23b0940e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,13 +24,36 @@ */ package java.lang.classfile.constantpool; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.invoke.TypeDescriptor; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_NameAndType_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.6 The CONSTANT_NameAndType_info Structure + * Models a {@code CONSTANT_NameAndType_info} structure, representing a field or + * method, in the constant pool of a {@code class} file. + * <p> + * The use of a {@code NameAndTypeEntry} is symbolically represented as a + * {@code String name}, and a {@link ConstantPoolBuilder#nameAndTypeEntry(String, + * ClassDesc) ClassDesc} or a {@link ConstantPoolBuilder#nameAndTypeEntry(String, + * MethodTypeDesc) MethodTypeDesc} {@code type}, depending on where this {@code + * NameAndTypeEntry} appears. The accessors to the symbolic descriptors for the + * {@code type} is defined on a per-use-site basis, such as {@link + * FieldRefEntry#typeSymbol()} returning a {@code ClassDesc}, and {@link + * MethodRefEntry#typeSymbol()} returning a {@code MethodTypeDesc}. + * <p> + * A name and type entry is composite: + * {@snippet lang=text : + * NameAndTypeEntry( // @link substring="NameAndTypeEntry" target="ConstantPoolBuilder#nameAndTypeEntry(Utf8Entry, Utf8Entry)" + * Utf8Entry name, // @link substring="name" target="#name()" + * Utf8Entry type // @link substring="type" target="#type()" + * ) + * } + * where {@code name} is an unqualified name, and {@code type} is a field or + * method descriptor string. * + * @jvms 4.4.6 The {@code CONSTANT_NameAndType_info} Structure * @since 24 */ public sealed interface NameAndTypeEntry extends PoolEntry @@ -42,7 +65,10 @@ public sealed interface NameAndTypeEntry extends PoolEntry Utf8Entry name(); /** - * {@return the field or method descriptor} + * {@return the field or method {@linkplain TypeDescriptor descriptor} + * string} It is a method descriptor strings if it starts with {@code (}. + * Otherwise, it is a field descriptor string, and must start with one of + * the {@code BCDFIJSZL[} characters. */ Utf8Entry type(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java index 54ea2fc38e5..ec56d0a4870 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,21 +29,35 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_Package_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.12 The CONSTANT_Package_info Structure + * Models a {@code CONSTANT_Package_info}, representing a package, in the + * constant pool of a {@code class} file. + * <p> + * The use of a {@code PackageEntry} is represented by a {@link PackageDesc} + * that does not represent the unnamed package. Conversions are through + * {@link ConstantPoolBuilder#packageEntry(PackageDesc)} and + * {@link #asSymbol()}. + * <p> + * A package entry is composite: + * {@snippet lang=text : + * // @link substring="PackageEntry" target="ConstantPoolBuilder#packageEntry(Utf8Entry)" : + * PackageEntry(Utf8Entry name) // @link substring="name" target="#name()" + * } + * where {@code name} is the {@linkplain ClassEntry##internalname internal form} + * of a binary package name and is not empty. * + * @jvms 4.4.12 The {@code CONSTANT_Package_info} Structure * @since 24 */ public sealed interface PackageEntry extends PoolEntry permits AbstractPoolEntry.PackageEntryImpl { /** - * {@return the package name} + * {@return the {@linkplain ClassEntry##internalname internal form} of the + * {@linkplain #asSymbol() package} name} */ Utf8Entry name(); /** - * {@return a symbolic descriptor for the package name} + * {@return a symbolic descriptor for the {@linkplain #name() package name}} */ PackageDesc asSymbol(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java index 5762a92a061..5d27e54e679 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,28 @@ */ package java.lang.classfile.constantpool; +import java.lang.classfile.Attribute; +import java.lang.classfile.ClassFileBuilder; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; + /** - * Models an entry in the constant pool of a classfile. + * Models an entry in the constant pool of a {@code class} file. Entries are + * read from {@code class} files, and can be created with a {@link + * ConstantPoolBuilder} to write to {@code class} files. + * + * @implNote + * <h2 id="unbound">Unbound Constant Pool Entries</h2> + * Implementations may create unbound constant pool entries not belonging to + * an actual constant pool. They conveniently represent constant pool entries + * referred by unbound {@linkplain Attribute attributes} not read from a {@code + * class} file. Their {@link #index() index()} return a non-positive invalid + * value, and behaviors of their {@link #constantPool() constantPool()} are + * unspecified. They are considered alien to any {@linkplain + * ClassFileBuilder#constantPool() contextual constant pool} and will be + * converted when they are written to {@code class} files. * + * @see ConstantPoolBuilder##alien Alien Constant Pool Entries * @sealedGraph * @since 24 */ @@ -88,6 +107,14 @@ public sealed interface PoolEntry /** * {@return the constant pool this entry is from} + * + * @apiNote + * Given a {@link ConstantPoolBuilder} {@code builder} and a {@code + * PoolEntry entry}, use {@link ConstantPoolBuilder#canWriteDirect + * builder.canWriteDirect(entry.constantPool())} instead of object equality + * of the constant pool to determine if an entry belongs to the builder. + * + * @see ##unbound Unbound Constant Pool Entries */ ConstantPool constantPool(); @@ -102,11 +129,32 @@ public sealed interface PoolEntry /** * {@return the index within the constant pool corresponding to this entry} + * A valid index is always positive; if the index is non-positive, this + * entry is {@linkplain ##unbound unbound}. + * + * @see ##unbound Unbound Constant Pool Entries */ int index(); /** * {@return the number of constant pool slots this entry consumes} + * <p> + * All pool entries except {@link LongEntry CONSTANT_Long} and {@link + * DoubleEntry CONSTANT_Double} have width {@code 1}. These two exceptions + * have width {@code 2}, and their subsequent indices at {@link #index() + * index() + 1} are considered unusable. + * + * @apiNote + * If this entry is {@linkplain LoadableConstantEntry loadable}, the width + * of this entry does not decide if this entry should be loaded with {@link + * Opcode#LDC ldc} or {@link Opcode#LDC2_W ldc2_w}. For example, {@link + * ConstantDynamicEntry} always has width {@code 1}, but it must be loaded + * with {@code ldc2_w} if its {@linkplain ConstantDynamicEntry#typeKind() + * type} is {@link TypeKind#LONG long} or {@link TypeKind#DOUBLE double}. + * Use {@link LoadableConstantEntry#typeKind() typeKind().slotSize()} to + * determine the loading instruction instead. + * + * @see ConstantPool##index Index in the Constant Pool */ int width(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java index 03ff7652f67..8a0bbb4b015 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,20 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_String_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.3 The CONSTANT_String_info Structure + * Models a {@code CONSTANT_String_info} structure, or a string constant, in the + * constant pool of a {@code class} file. + * <p> + * The use of a {@code StringEntry} is represented by a {@link String}. + * Conversions are through {@link ConstantPoolBuilder#stringEntry(String)} and + * {@link #stringValue()}. + * <p> + * A string entry is composite: + * {@snippet lang=text : + * // @link substring="StringEntry" target="ConstantPoolBuilder#stringEntry(Utf8Entry)" : + * StringEntry(Utf8Entry utf8) // @link substring="utf8" target="#utf8()" + * } * + * @jvms 4.4.3 The {@code CONSTANT_String_info} Structure * @since 24 */ public sealed interface StringEntry @@ -38,11 +48,15 @@ public sealed interface StringEntry permits AbstractPoolEntry.StringEntryImpl { /** * {@return the UTF constant pool entry describing the string contents} + * + * @see ConstantPoolBuilder#stringEntry(Utf8Entry) */ Utf8Entry utf8(); /** * {@return the string value for this entry} + * + * @see ConstantPoolBuilder#stringEntry(String) */ String stringValue(); } diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java index db03bf6a403..1d885051b2b 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,13 +24,40 @@ */ package java.lang.classfile.constantpool; +import java.io.DataInput; +import java.lang.classfile.AnnotationValue; +import java.lang.classfile.MethodModel; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.invoke.TypeDescriptor; + import jdk.internal.classfile.impl.AbstractPoolEntry; /** - * Models a {@code CONSTANT_UTF8_info} constant in the constant pool of a - * classfile. - * @jvms 4.4.7 The CONSTANT_Utf8_info Structure + * Models a {@code CONSTANT_UTF8_info} constant, representing strings, in the + * constant pool of a {@code class} file. This describes strings in the + * {@linkplain DataInput##modified-utf-8 Modified UTF-8} format. + * <p> + * The use of a {@code Utf8Entry} is represented by a {@link String}. + * Conversions are through {@link ConstantPoolBuilder#utf8Entry(String)} and + * {@link #stringValue()}. + * <p> + * Some uses of {@code Utf8Entry} represent field or method {@linkplain + * TypeDescriptor#descriptorString() descriptor strings}, symbolically + * represented as {@link ClassDesc} or {@link MethodTypeDesc}, depending on + * where a {@code Utf8Entry} appear. Entries representing such uses are created + * with {@link ConstantPoolBuilder#utf8Entry(ClassDesc)} and {@link + * ConstantPoolBuilder#utf8Entry(MethodTypeDesc)}, and they can be converted to + * symbolic descriptors on a per-use-site basis, such as in {@link + * AnnotationValue.OfClass#classSymbol()} and {@link MethodModel#methodTypeSymbol()}. + * <p> + * Unlike most constant pool entries, a UTF-8 entry is of flexible length: it is + * represented as an array structure, with an {@code u2} for the data length in + * bytes, followed by that number of bytes of Modified UTF-8 data. It can + * represent at most 65535 bytes of data due to the physical restrictions. * + * @jvms 4.4.7 The {@code CONSTANT_Utf8_info} Structure + * @see DataInput##modified-utf-8 Modified UTF-8 * @since 24 */ public sealed interface Utf8Entry @@ -39,6 +66,15 @@ public sealed interface Utf8Entry /** * {@return the string value for this entry} + * + * @apiNote + * A {@code Utf8Entry} can be used directly as a {@link CharSequence} if + * {@code String} functionalities are not strictly desired. If only string + * equivalence is desired, {@link #equalsString(String) equalsString} should + * be used. Reduction of string processing can significantly improve {@code + * class} file reading performance. + * + * @see ConstantPoolBuilder#utf8Entry(String) */ String stringValue(); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java index 83039c6565c..66e72496d3a 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,11 +24,59 @@ */ /** - * <h2>Provides interfaces describing classfile constant pool entries for the {@link java.lang.classfile} library.</h2> + * <h2>Provides interfaces describing constant pool entries for the {@link java.lang.classfile} library.</h2> * - * The {@code java.lang.classfile.constantpool} package contains interfaces describing classfile constant pool entries. + * The {@code java.lang.classfile.constantpool} package contains interfaces describing constant pool entries in the + * {@code class} file format. Constant pool entries are low-level models to faithfully represent the exact structure + * of a {@code class} file. + * <p> + * Unless otherwise specified, passing {@code null} or an array or collection containing a {@code null} element as an + * argument to a constructor or method of any Class-File API class or interface will cause a {@link NullPointerException} + * to be thrown. * + * <h2 id="reading">Reading the constant pool entries</h2> + * When read from {@code class} files, the pool entries are lazily inflated; the contents of these entries, besides the + * bare structure, are not evaluated to speed up parsing. Entries to users interest, usually accessed from other models + * and elements, have their contents read on demand. For example, to search for methods, a user should filter first by + * access flags and then by method name, and use {@link Utf8Entry#equalsString(String)} instead of checking equality + * against {@link Utf8Entry#stringValue()}. This avoids inflation of UTF-8 entries as much as possible: + * {@snippet lang="java" class="PackageSnippets" region="isStaticWorkMethod"} + * <p> + * The entries also define accessors to validated symbolic information with nominal descriptor abstractions from the + * {@link java.lang.constant} package. These symbolic information accessors perform validation against the read + * {@code class} files, and throw {@link IllegalArgumentException} when the accessed constant pool entry contains + * invalid data. The nominal descriptors represent validated data, which saves users from extra validations in future + * processing. + * <p> + * Due to the lazy nature of {@code class} file parsing, {@link IllegalArgumentException} indicating malformed + * {@code class} file data can be thrown at any method invocation. For example, an exception may come from a {@link + * ClassEntry} when it is first read from the constant pool (referring to an invalid index or wrong type of entry), when + * its referred UTF-8 entry is expanded (malformed UTF-8 data), or when its symbolic information is accessed (the string + * is not valid for a class entry). + * + * <h2 id="writing">Writing the constant pool entries</h2> + * In general, users do not need to worry about working with the constant pool and its entries when writing {@code + * class} files. Most Class-File API models and elements have two sets of factory methods: one that accepts symbolic + * information representing the uses, and another that accepts constant pool entries. The constant pool builder + * associated with {@code class} file builders, {@link ClassFileBuilder#constantPool}, automatically creates or reuses + * pool entries from the symbolic information. Validated data in symbolic information helps {@code class} file + * generation by avoiding extraneous parsing of raw constant pool entry data. + * <p> + * As always, users can use factories that accept constant pool entries if they already have them by hand, or if they + * desire fine-grained control over {@code class} file generation. + * <p> + * If many models and elements are reused from another {@link ClassModel} in class building, the class building process + * can use a constant pool builder that extends from the given {@code ClassModel}, available through {@link + * ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel)}, so that byte data with constant pool + * references can be copied in batch, speeding up class building. This is especially applicable to class transformations, + * and {@link ClassFile.ConstantPoolSharingOption ConstantPoolSharingOption} exists to control this behavior. + * + * @jvms 4.4 The Constant Pool * @since 24 */ package java.lang.classfile.constantpool; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileBuilder; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java b/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java new file mode 100644 index 00000000000..983aa1adb4c --- /dev/null +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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 java.lang.classfile.constantpool.snippet; + +import java.lang.classfile.ClassFile; +import java.lang.classfile.MethodModel; +import java.lang.classfile.constantpool.Utf8Entry; + +class PackageSnippets { + + // @start region=isStaticWorkMethod + boolean isStaticWorkMethod(MethodModel method) { + // check static flag first to avoid unnecessary evaluation of UTF-8 entry + return (method.flags().flagsMask() & ClassFile.ACC_STATIC) != 0 + // use equalsString to avoid full conversion to String for comparison + // the Utf8Entry can also act as a basic CharSequence without full conversion + // @link substring="methodName" target="MethodModel#methodName" : + && method.methodName().equalsString("work"); // @link substring="equalsString" target="Utf8Entry#equalsString" + } + // @end +} diff --git a/test/jdk/jdk/classfile/SnippetsTest.java b/test/jdk/jdk/classfile/SnippetsTest.java index f6fa2281e14..2b84820e9b9 100644 --- a/test/jdk/jdk/classfile/SnippetsTest.java +++ b/test/jdk/jdk/classfile/SnippetsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,9 @@ public class SnippetsTest { @ParameterizedTest @ValueSource(strings = { "src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java", - "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java"}) + "src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java", + "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java" + }) void testSnippet(String source) throws Exception { var p = Paths.get(System.getProperty("test.src", ".")).toAbsolutePath(); while ((p = p.getParent()) != null) { From 95551b2ba4ffda1c2d91f7ed85d7c3184bfd8dcd Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Wed, 8 Jan 2025 08:44:22 +0000 Subject: [PATCH 57/99] 8347047: Cleanup action passed to MemorySegment::reinterpret keeps old segment alive Reviewed-by: mcimadamore --- .../internal/foreign/AbstractMemorySegmentImpl.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index e51e158c93c..9ccaf92b8d6 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -145,12 +145,17 @@ private NativeMemorySegmentImpl reinterpretInternal(Class<?> callerClass, long n Reflection.ensureNativeAccess(callerClass, MemorySegment.class, "reinterpret", false); Utils.checkNonNegativeArgument(newSize, "newSize"); if (!isNative()) throw new UnsupportedOperationException("Not a native segment"); - Runnable action = cleanup != null ? - () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) : - null; + Runnable action = cleanupAction(address(), newSize, cleanup); return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, scope, readOnly, action); } + // Using a static helper method ensures there is no unintended lambda capturing of `this` + private static Runnable cleanupAction(long address, long newSize, Consumer<MemorySegment> cleanup) { + return cleanup != null ? + () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address, newSize)) : + null; + } + private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) { return dup(offset, newSize, readOnly, scope); } From cf5ef5faabce0f7ecd6d1c1e81790158d6c759da Mon Sep 17 00:00:00 2001 From: Shaojin Wen <swen@openjdk.org> Date: Wed, 8 Jan 2025 09:40:17 +0000 Subject: [PATCH 58/99] 8343629: More MergeStore benchmark Reviewed-by: epeter --- .../bench/vm/compiler/MergeLoadBench.java | 515 ++++++++++ .../bench/vm/compiler/MergeStoreBench.java | 913 +++++------------- 2 files changed, 770 insertions(+), 658 deletions(-) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java new file mode 100644 index 00000000000..e29b5373791 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import jdk.internal.misc.Unsafe; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +public class MergeLoadBench { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + + final static int NUMBERS = 8192; + + final byte[] bytes4 = new byte[NUMBERS * 4]; + final byte[] bytes8 = new byte[NUMBERS * 8]; + final int [] ints = new int [NUMBERS ]; + final long[] longs = new long[NUMBERS ]; + + @Setup + public void setup() { + Random r = new Random(); + for (int i = 0; i < ints.length; i++) { + ints[i] = r.nextInt(); + INT_L.set(bytes4, i * 4, i); + } + + for (int i = 0; i < longs.length; i++) { + longs[i] = r.nextLong(); + LONG_L.set(bytes8, i * 8, i); + } + } + + /* + * The names of these cases have the following `B/L/V/U` suffixes, which are: + * ``` + * B BigEndian + * L LittleEndian + * V VarHandle + * U Unsafe + * R ReverseBytes + * C Unsafe.getChar & putChar + * S Unsafe.getShort & putShort + * ``` + */ + + @Benchmark + public void getIntB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_B.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_L.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += Integer.reverseBytes( + UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); + } + BH.consume(sum); + } + + @Benchmark + public void getIntU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getLongB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_B.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_L.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += Long.reverseBytes( + UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); + } + BH.consume(sum); + } + + @Benchmark + public void getLongU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getCharB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharB(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_B.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharBU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharL(bytes4, i); + sum += c; + } + BH.consume(sum); + } + @Benchmark + public void getCharLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharLU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + + @Benchmark + public void getCharLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_L.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharC(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + static int getIntB(byte[] array, int offset) { + return ((array[offset ] & 0xff) << 24) + | ((array[offset + 1] & 0xff) << 16) + | ((array[offset + 2] & 0xff) << 8) + | ((array[offset + 3] & 0xff) ); + } + + static int getIntBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) << 24) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 3) & 0xff) ); + } + + static int getIntL(byte[] array, int offset) { + return ((array[offset ] & 0xff) ) + | ((array[offset + 1] & 0xff) << 8) + | ((array[offset + 2] & 0xff) << 16) + | ((array[offset + 3] & 0xff) << 24); + } + + static int getIntRB(byte[] array, int offset) { + return Integer.reverseBytes(getIntB(array, offset)); + } + + static int getIntRBU(byte[] array, int offset) { + return Integer.reverseBytes(getIntBU(array, offset)); + } + + static int getIntRL(byte[] array, int offset) { + return Integer.reverseBytes(getIntL(array, offset)); + } + + static int getIntRLU(byte[] array, int offset) { + return Integer.reverseBytes(getIntLU(array, offset)); + } + + static long getLongB(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) << 56) + | (((long) array[offset + 1] & 0xff) << 48) + | (((long) array[offset + 2] & 0xff) << 40) + | (((long) array[offset + 3] & 0xff) << 32) + | (((long) array[offset + 4] & 0xff) << 24) + | (((long) array[offset + 5] & 0xff) << 16) + | (((long) array[offset + 6] & 0xff) << 8) + | (((long) array[offset + 7] & 0xff) ); + } + + static long getLongBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); + } + + public static long getLongL(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) ) + | (((long) array[offset + 1] & 0xff) << 8) + | (((long) array[offset + 2] & 0xff) << 16) + | (((long) array[offset + 3] & 0xff) << 24) + | (((long) array[offset + 4] & 0xff) << 32) + | (((long) array[offset + 5] & 0xff) << 40) + | (((long) array[offset + 6] & 0xff) << 48) + | (((long) array[offset + 7] & 0xff) << 56); + } + + static long getLongLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); + } + + static long getLongRB(byte[] array, int offset) { + return getLongB(array, offset); + } + + static long getLongRBU(byte[] array, int offset) { + return getLongBU(array, offset); + } + + static long getLongRL(byte[] array, int offset) { + return getLongL(array, offset); + } + + static long getLongRLU(byte[] array, int offset) { + return getLongLU(array, offset); + } + + public static int getIntLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); + } + + public static char getCharB(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff) << 8) + | ((val[index + 1] & 0xff))); + } + + public static char getCharBR(byte[] val, int index) { + return Character.reverseBytes(getCharB(val, index)); + } + + public static char getCharL(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff)) + | ((val[index + 1] & 0xff) << 8)); + } + + public static char getCharLR(byte[] val, int index) { + return Character.reverseBytes(getCharL(val, index)); + } + + public static char getCharBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 1) & 0xff) )); + } + + public static char getCharLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java index 870422de256..88b68868813 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java @@ -25,13 +25,9 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.lang.reflect.Field; import java.nio.ByteOrder; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -41,18 +37,19 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) -@Fork(value = 3, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) public class MergeStoreBench { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - final static VarHandle INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN); - final static VarHandle INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN); - final static VarHandle LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN); - final static VarHandle CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); final static int NUMBERS = 8192; @@ -89,115 +86,6 @@ public void setup() { * ``` */ - @Benchmark - public void getIntB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_B.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_L.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += Integer.reverseBytes( - UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); - } - BH.consume(sum); - } - - @Benchmark - public void getIntU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); - } - BH.consume(sum); - } - @Benchmark public void setIntB(Blackhole BH) { int sum = 0; @@ -211,613 +99,396 @@ public void setIntB(Blackhole BH) { @Benchmark public void setIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_B.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_B.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntL(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_L.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_L.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRB(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRB(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRL(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - v = Integer.reverseBytes(v); - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Integer.reverseBytes(ints[i])); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_B.get(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_L.get(bytes8, i * 8); + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, ints[i]); + off += 4; } - BH.consume(sum); - } - - @Benchmark - public void getLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += Long.reverseBytes( - UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); - } - BH.consume(sum); - } - - @Benchmark - public void getLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); - } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_B.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_B.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_L.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_L.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - v = Long.reverseBytes(v); - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Long.reverseBytes(longs[i])); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getCharB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharB(bytes4, i); - sum += c; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_B.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; - } - BH.consume(sum); - } - - @Benchmark - public void getCharBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharBU(bytes4, i); - sum += c; + public void setCharBS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortB(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharL(bytes4, i); - sum += c; - } - BH.consume(sum); - } - @Benchmark - public void getCharLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharLU(bytes4, i); - sum += c; + public void setCharBV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_B.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } - @Benchmark - public void getCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_L.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortL(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_L.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharBS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortB(bytes4, i * 2, c); - sum += c; + public void setCharC(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } + /* + * putChars4 and putBytes4 Test whether four constant chars can be MergeStored + * + */ @Benchmark - public void setCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_B.set(bytes4, i * 2, c); - sum += c; + public void putBytes4(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortL(bytes4, i * 2, c); - sum += c; + public void putBytes4X(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4X(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_L.set(bytes4, i * 2, c); - sum += c; + public void putBytes4U(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4U(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2, c); - sum += c; + @SuppressWarnings("deprecation") + public void putBytes4GetBytes(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + "null".getBytes(0, 4, bytes4, off); + off += 4; } - BH.consume(sum); + BH.consume(off); } - /* - * putChars4 Test whether four constant chars can be MergeStored - * - */ @Benchmark public void putChars4B(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4B(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4B(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4L(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4L(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4L(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4C(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4C(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4C(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4S(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4S(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4S(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); - } - - static int getIntB(byte[] array, int offset) { - return ((array[offset ] & 0xff) << 24) - | ((array[offset + 1] & 0xff) << 16) - | ((array[offset + 2] & 0xff) << 8) - | ((array[offset + 3] & 0xff) ); - } - - static int getIntBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) << 24) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 3) & 0xff) ); - } - - static int getIntL(byte[] array, int offset) { - return ((array[offset ] & 0xff) ) - | ((array[offset + 1] & 0xff) << 8) - | ((array[offset + 2] & 0xff) << 16) - | ((array[offset + 3] & 0xff) << 24); - } - - static int getIntRB(byte[] array, int offset) { - return Integer.reverseBytes(getIntB(array, offset)); - } - - static int getIntRBU(byte[] array, int offset) { - return Integer.reverseBytes(getIntBU(array, offset)); - } - - static int getIntRL(byte[] array, int offset) { - return Integer.reverseBytes(getIntL(array, offset)); - } - - static int getIntRLU(byte[] array, int offset) { - return Integer.reverseBytes(getIntLU(array, offset)); + BH.consume(off); } static void setIntB(byte[] array, int offset, int value) { @@ -870,68 +541,6 @@ public static void setIntRBU(byte[] array, int offset, int value) { setIntBU(array, offset, value); } - static long getLongB(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) << 56) - | (((long) array[offset + 1] & 0xff) << 48) - | (((long) array[offset + 2] & 0xff) << 40) - | (((long) array[offset + 3] & 0xff) << 32) - | (((long) array[offset + 4] & 0xff) << 24) - | (((long) array[offset + 5] & 0xff) << 16) - | (((long) array[offset + 6] & 0xff) << 8) - | (((long) array[offset + 7] & 0xff) ); - } - - static long getLongBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); - } - - public static long getLongL(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) ) - | (((long) array[offset + 1] & 0xff) << 8) - | (((long) array[offset + 2] & 0xff) << 16) - | (((long) array[offset + 3] & 0xff) << 24) - | (((long) array[offset + 4] & 0xff) << 32) - | (((long) array[offset + 5] & 0xff) << 40) - | (((long) array[offset + 6] & 0xff) << 48) - | (((long) array[offset + 7] & 0xff) << 56); - } - - static long getLongLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); - } - - static long getLongRB(byte[] array, int offset) { - return getLongB(array, offset); - } - - static long getLongRBU(byte[] array, int offset) { - return getLongBU(array, offset); - } - - static long getLongRL(byte[] array, int offset) { - return getLongL(array, offset); - } - - static long getLongRLU(byte[] array, int offset) { - return getLongLU(array, offset); - } - static void setLongB(byte[] array, int offset, long value) { array[offset] = (byte) (value >> 56); array[offset + 1] = (byte) (value >> 48); @@ -998,112 +607,95 @@ public static void setLongLU(byte[] array, int offset, long value) { UNSAFE.putByte(array, address + 7, (byte) (value >> 56)); } - public static int getIntLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); - } - - public static char getCharB(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff) << 8) - | ((val[index + 1] & 0xff))); - } - - public static char getCharBR(byte[] val, int index) { - return Character.reverseBytes(getCharB(val, index)); - } - - public static char getCharL(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff)) - | ((val[index + 1] & 0xff) << 8)); + public int putBytes4(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset ] = (byte) c0; + bytes[offset + 1] = (byte) c1; + bytes[offset + 2] = (byte) c2; + bytes[offset + 3] = (byte) c3; + return offset + 4; } - public static char getCharLR(byte[] val, int index) { - return Character.reverseBytes(getCharL(val, index)); + public int putBytes4X(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset++] = (byte) c0; + bytes[offset++] = (byte) c1; + bytes[offset++] = (byte) c2; + bytes[offset++] = (byte) c3; + return offset; } - public static char getCharBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 1) & 0xff) )); - } - - public static char getCharLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + public int putBytes4U(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + UNSAFE.putByte(bytes, address , (byte) c0); + UNSAFE.putByte(bytes, address + 1, (byte) c1); + UNSAFE.putByte(bytes, address + 2, (byte) c2); + UNSAFE.putByte(bytes, address + 3, (byte) c3); + return offset + 4; } - public void putChars4B(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4B(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortB(bytes, offset , c0); putShortB(bytes, offset + 1, c1); putShortB(bytes, offset + 2, c2); putShortB(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4BU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortBU(bytes, offset , c0); putShortBU(bytes, offset + 1, c1); putShortBU(bytes, offset + 2, c2); putShortBU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; - CHAR_B.set(bytes, offset , c0); + public int putChars4BV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + CHAR_B.set(bytes, offset , c0); CHAR_B.set(bytes, offset + 2, c1); CHAR_B.set(bytes, offset + 4, c2); CHAR_B.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4L(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4L(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortL(bytes, offset , c0); putShortL(bytes, offset + 1, c1); putShortL(bytes, offset + 2, c2); putShortL(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4LV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; + public int putChars4LV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { CHAR_L.set(bytes, offset , c0); CHAR_L.set(bytes, offset + 2, c1); CHAR_L.set(bytes, offset + 4, c2); CHAR_L.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4LU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4LU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortLU(bytes, offset , c0); putShortLU(bytes, offset + 1, c1); putShortLU(bytes, offset + 2, c2); putShortLU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4C(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4C(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putChar(bytes, address , c0); UNSAFE.putChar(bytes, address + 2, c1); UNSAFE.putChar(bytes, address + 4, c2); UNSAFE.putChar(bytes, address + 6, c3); + return offset + 8; } - public void putChars4S(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4S(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putShort(bytes, address , (short) c0); UNSAFE.putShort(bytes, address + 2, (short) c1); UNSAFE.putShort(bytes, address + 4, (short) c2); UNSAFE.putShort(bytes, address + 6, (short) c3); + return offset + 8; } private static void putShortB(byte[] val, int index, int c) { @@ -1129,4 +721,9 @@ public static void putShortLU(byte[] array, int offset, int c) { UNSAFE.putByte(array, address , (byte) (c )); UNSAFE.putByte(array, address + 1, (byte) (c >> 8)); } + + @Fork(value = 1, jvmArgs = { + "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:+UnlockDiagnosticVMOptions", "-XX:-MergeStores" + }) + public static class MergeStoresDisabled extends MergeStoreBench {} } From 2c4ce7d8306c98c3171f79d1a3586f815d6509ed Mon Sep 17 00:00:00 2001 From: Severin Gehwolf <sgehwolf@openjdk.org> Date: Wed, 8 Jan 2025 10:39:13 +0000 Subject: [PATCH 59/99] 8346239: Improve memory efficiency of JimageDiffGenerator Reviewed-by: mbaesken --- .../runtimelink/JimageDiffGenerator.java | 59 +++++++++++++++++-- .../runtimelink/ResourcePoolReader.java | 6 ++ .../jlink/runtimeImage/AddOptionsTest.java | 2 +- .../BasicJlinkMissingJavaBase.java | 2 +- .../jlink/runtimeImage/BasicJlinkTest.java | 2 +- .../runtimeImage/CustomModuleJlinkTest.java | 2 +- .../runtimeImage/GenerateJLIClassesTest.java | 2 +- .../runtimeImage/JavaSEReproducibleTest.java | 2 +- .../KeepPackagedModulesFailTest.java | 2 +- .../runtimeImage/ModifiedFilesExitTest.java | 2 +- .../ModifiedFilesWarningTest.java | 2 +- .../jlink/runtimeImage/MultiHopTest.java | 2 +- ...PackagedModulesVsRuntimeImageLinkTest.java | 3 +- .../PatchedJDKModuleJlinkTest.java | 2 +- .../jlink/runtimeImage/SystemModulesTest.java | 2 +- .../runtimeImage/SystemModulesTest2.java | 2 +- 16 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java index 3ef42fb9aa0..60014e2bbd7 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/JimageDiffGenerator.java @@ -24,6 +24,9 @@ */ package jdk.tools.jlink.internal.runtimelink; +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -49,6 +52,7 @@ public class JimageDiffGenerator { public interface ImageResource extends AutoCloseable { public List<String> getEntries(); public byte[] getResourceBytes(String name); + public InputStream getResource(String name); } /** @@ -71,7 +75,6 @@ public List<ResourceDiff> generateDiff(ImageResource base, ImageResource image) resources.addAll(image.getEntries()); baseResources = base.getEntries(); for (String item: baseResources) { - byte[] baseBytes = base.getResourceBytes(item); // First check that every item in the base image exist in // the optimized image as well. If it does not, it's a removed // item in the optimized image. @@ -82,19 +85,18 @@ public List<ResourceDiff> generateDiff(ImageResource base, ImageResource image) ResourceDiff.Builder builder = new ResourceDiff.Builder(); ResourceDiff diff = builder.setKind(ResourceDiff.Kind.REMOVED) .setName(item) - .setResourceBytes(baseBytes) + .setResourceBytes(base.getResourceBytes(item)) .build(); diffs.add(diff); continue; } // Verify resource bytes are equal if present in both images - boolean contentEquals = Arrays.equals(baseBytes, image.getResourceBytes(item)); - if (!contentEquals) { + if (!compareStreams(base.getResource(item), image.getResource(item))) { // keep track of original bytes (non-optimized) ResourceDiff.Builder builder = new ResourceDiff.Builder(); ResourceDiff diff = builder.setKind(ResourceDiff.Kind.MODIFIED) .setName(item) - .setResourceBytes(baseBytes) + .setResourceBytes(base.getResourceBytes(item)) .build(); diffs.add(diff); } @@ -112,4 +114,51 @@ public List<ResourceDiff> generateDiff(ImageResource base, ImageResource image) return diffs; } + /** + * Compare the contents of the two input streams (byte-by-byte). + * + * @param is1 The first input stream + * @param is2 The second input stream + * @return {@code true} iff the two streams contain the same number of + * bytes and each byte of the streams are equal. {@code false} + * otherwise. + */ + private boolean compareStreams(InputStream is1, InputStream is2) { + byte[] buf1 = new byte[1024]; + byte[] buf2 = new byte[1024]; + int bytesRead1, bytesRead2 = 0; + try { + try (is1; is2) { + while ((bytesRead1 = is1.read(buf1)) != -1 && + (bytesRead2 = is2.read(buf2)) != -1) { + if (bytesRead1 != bytesRead2) { + return false; + } + if (bytesRead1 == buf1.length) { + if (!Arrays.equals(buf1, buf2)) { + return false; + } + } else { + for (int i = 0; i < bytesRead1; i++) { + if (buf1[i] != buf2[i]) { + return false; + } + } + } + } + // ensure we read both to the end + if (bytesRead1 == -1) { + bytesRead2 = is2.read(buf2); + if (bytesRead2 != -1) { + return false; + } + return true; + } + } + } catch (IOException e) { + throw new UncheckedIOException("IO exception when comparing bytes", e); + } + return false; + } + } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java index 910fe57b75a..c4c16579906 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/ResourcePoolReader.java @@ -25,6 +25,7 @@ package jdk.tools.jlink.internal.runtimelink; +import java.io.InputStream; import java.util.List; import java.util.Objects; @@ -56,4 +57,9 @@ public byte[] getResourceBytes(String name) { return pool.findEntry(name).orElseThrow().contentBytes(); } + @Override + public InputStream getResource(String name) { + return pool.findEntry(name).orElseThrow().content(); + } + } diff --git a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java index 827f7da624d..1ffe1240d07 100644 --- a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m AddOptionsTest + * @run main/othervm -Xmx1g AddOptionsTest */ public class AddOptionsTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java index ebf5b060665..b0d2a2d66f5 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkMissingJavaBase + * @run main/othervm -Xmx1g BasicJlinkMissingJavaBase */ public class BasicJlinkMissingJavaBase extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java index 8cbd74e5ed1..b97ebff9b49 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkTest false + * @run main/othervm -Xmx1g BasicJlinkTest false */ public class BasicJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java index d6c237a173b..369bccfecfc 100644 --- a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m CustomModuleJlinkTest + * @run main/othervm -Xmx1g CustomModuleJlinkTest */ public class CustomModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java index e59d18bd6f0..533a8db30d0 100644 --- a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m GenerateJLIClassesTest + * @run main/othervm -Xmx1g GenerateJLIClassesTest */ public class GenerateJLIClassesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java index a376d075ecd..d923358aed9 100644 --- a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java +++ b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m JavaSEReproducibleTest + * @run main/othervm -Xmx1g JavaSEReproducibleTest */ public class JavaSEReproducibleTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java index 6fdaf5a9824..8094579ecd5 100644 --- a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java +++ b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m KeepPackagedModulesFailTest + * @run main/othervm -Xmx1g KeepPackagedModulesFailTest */ public class KeepPackagedModulesFailTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java index 777ce302ce7..443cbbaec3c 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesExitTest + * @run main/othervm -Xmx1g ModifiedFilesExitTest */ public class ModifiedFilesExitTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java index c871024f37c..619c67e01b4 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesWarningTest + * @run main/othervm -Xmx1g ModifiedFilesWarningTest */ public class ModifiedFilesWarningTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java index 0e2cabe7425..88f91f238bd 100644 --- a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java +++ b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m MultiHopTest + * @run main/othervm -Xmx1g MultiHopTest */ public class MultiHopTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java index d276e80702b..ef7030d2e62 100644 --- a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java @@ -49,7 +49,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm/timeout=1200 -Xmx1400m PackagedModulesVsRuntimeImageLinkTest + * @run main/othervm/timeout=1200 -Xmx1g PackagedModulesVsRuntimeImageLinkTest */ public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest { @@ -76,7 +76,6 @@ void runTest(Helper helper, boolean isLinkableRuntime) throws Exception { .output(helper.createNewImageDir("java-se-jmodfull")) .addMods("java.se").call().assertSuccess(); - System.out.println("Now comparing jmod-less and jmod-full) images"); compareRecursively(javaSEruntimeLink, javaSEJmodFull); } diff --git a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java index d4654ec98bd..81579e0754b 100644 --- a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m PatchedJDKModuleJlinkTest + * @run main/othervm -Xmx1g PatchedJDKModuleJlinkTest */ public class PatchedJDKModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java index d0a6234eec0..fac8cac112d 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest + * @run main/othervm -Xmx1g SystemModulesTest */ public class SystemModulesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java index ee22a55f3a7..6be4ad7321c 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest2 + * @run main/othervm -Xmx1g SystemModulesTest2 */ public class SystemModulesTest2 extends AbstractLinkableRuntimeTest { From 72c297bcbf9f4b2386ea03cd0e2b48106c79bf50 Mon Sep 17 00:00:00 2001 From: Chen Liang <liach@openjdk.org> Date: Wed, 8 Jan 2025 10:56:48 +0000 Subject: [PATCH 60/99] 8347163: Javadoc error in ConstantPoolBuilder after JDK-8342468 Reviewed-by: jpai, shade --- .../java/lang/classfile/constantpool/ConstantPoolBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java index e1518ab6a02..260fc982dab 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java @@ -400,7 +400,7 @@ default MethodHandleEntry methodHandleEntry(DirectMethodHandleDesc descriptor) { * * @param refKind the reference kind of the method handle * @param reference the {@code MemberRefEntry} - * @see MethodHandleInfo##refKinds Reference kinds + * @see MethodHandleInfo##refkinds Reference kinds * @see MethodHandleEntry#kind() MethodHandleEntry::kind * @see MethodHandleEntry#reference() MethodHandleEntry::reference */ From 5ab20ecaf9629500727f1eda19eacd1862402265 Mon Sep 17 00:00:00 2001 From: Erik Gahlin <egahlin@openjdk.org> Date: Wed, 8 Jan 2025 12:44:53 +0000 Subject: [PATCH 61/99] 8345337: JFR: jfr view should display all direct subfields for an event type Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/FieldBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java index c6916bc52ef..391db7cc930 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java @@ -353,9 +353,10 @@ record WildcardElement(String name, String label, ValueDescriptor field) { var subFields = we.field().getFields().reversed(); if (!subFields.isEmpty() && !KNOWN_TYPES.contains(we.field().getTypeName())) { for (ValueDescriptor subField : subFields) { - String n = we.name + "." + subField.getName(); - String l = we.label + " : " + makeLabel(subField, false); - if (stack.size() < 2) { // Limit depth to 2 + // Limit depth to 2 + if (!we.name.contains(".")) { + String n = we.name + "." + subField.getName(); + String l = we.label + " : " + makeLabel(subField, false); stack.push(new WildcardElement(n, l, subField)); } } From dc316f600dc0ae7b1c8a7a92d21b0c71057f3799 Mon Sep 17 00:00:00 2001 From: Erik Gahlin <egahlin@openjdk.org> Date: Wed, 8 Jan 2025 14:40:13 +0000 Subject: [PATCH 62/99] 8346052: JFR: Incorrect average value in 'jfr view' Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/Function.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java index 29d55e95673..767202bdae8 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java @@ -175,9 +175,9 @@ public void add(Object value) { @Override public Object result() { if (count != 0) { - long s = seconds / count; - long n = nanos / count; - return Duration.ofSeconds(s, n); + double total = 1_000_000_000.0 * seconds + nanos; + double average = total / count; + return Duration.ofNanos(Math.round(average)); } else { return null; } From cb842ee2b92f1a69a1053b8857868ab64284c3d7 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Wed, 8 Jan 2025 14:44:10 +0000 Subject: [PATCH 63/99] 8346872: tools/jpackage/windows/WinLongPathTest.java fails Reviewed-by: almatvee, mbaesken --- .../jpackage/windows/WinLongPathTest.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/jdk/tools/jpackage/windows/WinLongPathTest.java b/test/jdk/tools/jpackage/windows/WinLongPathTest.java index e9e5ef8ce03..10e713f02a8 100644 --- a/test/jdk/tools/jpackage/windows/WinLongPathTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.RunnablePackageTest.Action; import jdk.jpackage.test.TKit; @@ -39,8 +40,10 @@ * @bug 8289771 * @summary jpackage with long paths on windows * @library /test/jdk/tools/jpackage/helpers + * @library /test/lib * @key jpackagePlatformPackage * @build jdk.jpackage.test.* + * @build jtreg.SkippedException * @requires (os.family == "windows") * @compile WinLongPathTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main @@ -64,6 +67,8 @@ public static List<Object[]> input() { @Test public void test() throws IOException { + verifyDosNamesSupported(); + if (appImage) { var cmd = JPackageCommand.helloAppImage(); setOptionLongPath(cmd, optionName); @@ -84,4 +89,23 @@ private static void setOptionLongPath(JPackageCommand cmd, String option) throws Files.createDirectories(longPath); cmd.setArgumentValue(option, longPath); } + + private static void verifyDosNamesSupported() throws IOException { + // Pick the file's name long enough to make Windows shorten it. + final var probeDosNameFile = TKit.createTempFile(Path.of("probeDosName")); + + // The output should be a DOS variant of the `probeDosNameFile` path. + // The filename should differ if the volume owning `probeDosNameFile` file supports DOS names. + final var dosPath = new Executor() + .addArguments("/c", String.format("for %%P in (\"%s\") do @echo %%~sP", probeDosNameFile)) + .setExecutable("cmd") + .dumpOutput() + .executeAndGetFirstLineOfOutput(); + + if (Path.of(dosPath).getFileName().equals(probeDosNameFile.getFileName())) { + TKit.throwSkippedException(String.format("The volume %s owning the test work directory doesn't support DOS paths", + probeDosNameFile.toAbsolutePath().getRoot())); + } + } + } From a85848b22c09fb78b2278b905798ee04bfaa4b66 Mon Sep 17 00:00:00 2001 From: Erik Gahlin <egahlin@openjdk.org> Date: Wed, 8 Jan 2025 15:53:22 +0000 Subject: [PATCH 64/99] 8346047: JFR: Incorrect percentile value in 'jfr view' Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/internal/query/Function.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java index 767202bdae8..0c9ca96ee20 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java @@ -89,7 +89,7 @@ public static Function create(Field field) { return createPercentile(field, 0.99); } if (aggregator == Aggregator.P999) { - return createPercentile(field, 0.9999); + return createPercentile(field, 0.999); } if (aggregator == Aggregator.MAXIMUM) { return new Maximum(); @@ -578,7 +578,7 @@ public Object result() { double doubleIndex = (size + 1) * percentile; int valueIndex = (int) doubleIndex - 1; int valueNextIndex = (int) doubleIndex; - double fraction = doubleIndex - valueIndex; + double fraction = doubleIndex - (int) doubleIndex; if (valueIndex < 0) { return numbers.getFirst(); From eefa625e67416d24c4c7c7ea05083d3f73642556 Mon Sep 17 00:00:00 2001 From: Erik Gahlin <egahlin@openjdk.org> Date: Wed, 8 Jan 2025 16:03:40 +0000 Subject: [PATCH 65/99] 8346099: JFR: Query for 'jfr view' can't handle wildcard with multiple event types Reviewed-by: mgronlun --- .../classes/jdk/jfr/internal/query/FieldBuilder.java | 1 - .../classes/jdk/jfr/internal/query/QueryResolver.java | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java index 391db7cc930..df6fb9f2a9a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java @@ -370,7 +370,6 @@ record WildcardElement(String name, String label, ValueDescriptor field) { FieldBuilder fb = new FieldBuilder(eventTypes, type, we.name()); Field field = fb.build().getFirst(); field.label = we.label; - field.index = result.size(); field.visible = true; field.sourceFields.add(field); result.add(field); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java index 4d947eea9a5..1b68a038a17 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/QueryResolver.java @@ -98,11 +98,19 @@ public List<Field> resolve() throws QueryException { resolveGroupBy(); resolveOrderBy(); resolveWhere(); + applyIndex(); applyColumn(); applyFormat(); return resultFields; } + private void applyIndex() { + int index = 0; + for (Field field : resultFields) { + field.index = index++; + } + } + private void resolveWhere() throws QuerySyntaxException { for (Condition condition : where) { List<Field> fields = new ArrayList<>(); @@ -238,7 +246,6 @@ private Field addField(String name, List<FilteredType> types) throws QueryExcept } } for (Field field: fields) { - field.index = resultFields.size(); primary.sourceFields.add(field); // Convert to String if field data types mismatch if (mixedTypes) { From b0ef523a9ced2fcea87c6929c6d15a7733e2e48f Mon Sep 17 00:00:00 2001 From: Naoto Sato <naoto@openjdk.org> Date: Wed, 8 Jan 2025 16:48:44 +0000 Subject: [PATCH 66/99] 8166983: Remove old/legacy unused tzdata files Reviewed-by: iris, rriggs --- src/java.base/share/data/tzdata/solar87 | 413 ------- src/java.base/share/data/tzdata/solar88 | 413 ------- src/java.base/share/data/tzdata/solar89 | 418 ------- src/java.base/share/data/tzdata/zone.tab | 470 -------- .../java/util/TimeZone/tools/share/Makefile | 5 +- test/jdk/sun/util/calendar/zi/BackEnd.java | 66 -- test/jdk/sun/util/calendar/zi/Beyond2037.java | 73 -- test/jdk/sun/util/calendar/zi/Checksum.java | 65 - test/jdk/sun/util/calendar/zi/DayOfWeek.java | 52 - test/jdk/sun/util/calendar/zi/Gen.java | 342 ------ test/jdk/sun/util/calendar/zi/GenDoc.java | 776 ------------ test/jdk/sun/util/calendar/zi/Main.java | 232 ---- test/jdk/sun/util/calendar/zi/Mappings.java | 193 --- test/jdk/sun/util/calendar/zi/Month.java | 87 -- test/jdk/sun/util/calendar/zi/Rule.java | 189 --- test/jdk/sun/util/calendar/zi/RuleDay.java | 184 --- test/jdk/sun/util/calendar/zi/RuleRec.java | 229 ---- test/jdk/sun/util/calendar/zi/Simple.java | 184 --- .../sun/util/calendar/zi/TestZoneInfo310.java | 283 ----- test/jdk/sun/util/calendar/zi/Time.java | 339 ------ test/jdk/sun/util/calendar/zi/Timezone.java | 450 ------- .../sun/util/calendar/zi/TzIDOldMapping.java | 64 - test/jdk/sun/util/calendar/zi/Zone.java | 164 --- .../sun/util/calendar/zi/ZoneInfoFile.java | 1049 ----------------- .../jdk/sun/util/calendar/zi/ZoneInfoOld.java | 1022 ---------------- test/jdk/sun/util/calendar/zi/ZoneRec.java | 248 ---- test/jdk/sun/util/calendar/zi/Zoneinfo.java | 579 --------- .../calendar/zi/tzdata_jdk/jdk11_backward | 78 -- 28 files changed, 2 insertions(+), 8665 deletions(-) delete mode 100644 src/java.base/share/data/tzdata/solar87 delete mode 100644 src/java.base/share/data/tzdata/solar88 delete mode 100644 src/java.base/share/data/tzdata/solar89 delete mode 100644 src/java.base/share/data/tzdata/zone.tab delete mode 100644 test/jdk/sun/util/calendar/zi/BackEnd.java delete mode 100644 test/jdk/sun/util/calendar/zi/Beyond2037.java delete mode 100644 test/jdk/sun/util/calendar/zi/Checksum.java delete mode 100644 test/jdk/sun/util/calendar/zi/DayOfWeek.java delete mode 100644 test/jdk/sun/util/calendar/zi/Gen.java delete mode 100644 test/jdk/sun/util/calendar/zi/GenDoc.java delete mode 100644 test/jdk/sun/util/calendar/zi/Main.java delete mode 100644 test/jdk/sun/util/calendar/zi/Mappings.java delete mode 100644 test/jdk/sun/util/calendar/zi/Month.java delete mode 100644 test/jdk/sun/util/calendar/zi/Rule.java delete mode 100644 test/jdk/sun/util/calendar/zi/RuleDay.java delete mode 100644 test/jdk/sun/util/calendar/zi/RuleRec.java delete mode 100644 test/jdk/sun/util/calendar/zi/Simple.java delete mode 100644 test/jdk/sun/util/calendar/zi/TestZoneInfo310.java delete mode 100644 test/jdk/sun/util/calendar/zi/Time.java delete mode 100644 test/jdk/sun/util/calendar/zi/Timezone.java delete mode 100644 test/jdk/sun/util/calendar/zi/TzIDOldMapping.java delete mode 100644 test/jdk/sun/util/calendar/zi/Zone.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneInfoFile.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneInfoOld.java delete mode 100644 test/jdk/sun/util/calendar/zi/ZoneRec.java delete mode 100644 test/jdk/sun/util/calendar/zi/Zoneinfo.java delete mode 100644 test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward diff --git a/src/java.base/share/data/tzdata/solar87 b/src/java.base/share/data/tzdata/solar87 deleted file mode 100644 index 0512ca410c1..00000000000 --- a/src/java.base/share/data/tzdata/solar87 +++ /dev/null @@ -1,413 +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. 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. -# -# <pre> -# This file is in the public domain, so clarified as of -# 2009-05-17 by Arthur David Olson. - -# So much for footnotes about Saudi Arabia. -# Apparent noon times below are for Riyadh; your mileage will vary. -# Times were computed using formulas in the U.S. Naval Observatory's -# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of -# [plus or minus two] seconds during the current year." -# -# Rounding to the nearest five seconds results in fewer than -# 256 different "time types"--a limit that's faced because time types are -# stored on disk as unsigned chars. - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule sol87 1987 only - Jan 1 12:03:20s -0:03:20 - -Rule sol87 1987 only - Jan 2 12:03:50s -0:03:50 - -Rule sol87 1987 only - Jan 3 12:04:15s -0:04:15 - -Rule sol87 1987 only - Jan 4 12:04:45s -0:04:45 - -Rule sol87 1987 only - Jan 5 12:05:10s -0:05:10 - -Rule sol87 1987 only - Jan 6 12:05:40s -0:05:40 - -Rule sol87 1987 only - Jan 7 12:06:05s -0:06:05 - -Rule sol87 1987 only - Jan 8 12:06:30s -0:06:30 - -Rule sol87 1987 only - Jan 9 12:06:55s -0:06:55 - -Rule sol87 1987 only - Jan 10 12:07:20s -0:07:20 - -Rule sol87 1987 only - Jan 11 12:07:45s -0:07:45 - -Rule sol87 1987 only - Jan 12 12:08:10s -0:08:10 - -Rule sol87 1987 only - Jan 13 12:08:30s -0:08:30 - -Rule sol87 1987 only - Jan 14 12:08:55s -0:08:55 - -Rule sol87 1987 only - Jan 15 12:09:15s -0:09:15 - -Rule sol87 1987 only - Jan 16 12:09:35s -0:09:35 - -Rule sol87 1987 only - Jan 17 12:09:55s -0:09:55 - -Rule sol87 1987 only - Jan 18 12:10:15s -0:10:15 - -Rule sol87 1987 only - Jan 19 12:10:35s -0:10:35 - -Rule sol87 1987 only - Jan 20 12:10:55s -0:10:55 - -Rule sol87 1987 only - Jan 21 12:11:10s -0:11:10 - -Rule sol87 1987 only - Jan 22 12:11:30s -0:11:30 - -Rule sol87 1987 only - Jan 23 12:11:45s -0:11:45 - -Rule sol87 1987 only - Jan 24 12:12:00s -0:12:00 - -Rule sol87 1987 only - Jan 25 12:12:15s -0:12:15 - -Rule sol87 1987 only - Jan 26 12:12:30s -0:12:30 - -Rule sol87 1987 only - Jan 27 12:12:40s -0:12:40 - -Rule sol87 1987 only - Jan 28 12:12:55s -0:12:55 - -Rule sol87 1987 only - Jan 29 12:13:05s -0:13:05 - -Rule sol87 1987 only - Jan 30 12:13:15s -0:13:15 - -Rule sol87 1987 only - Jan 31 12:13:25s -0:13:25 - -Rule sol87 1987 only - Feb 1 12:13:35s -0:13:35 - -Rule sol87 1987 only - Feb 2 12:13:40s -0:13:40 - -Rule sol87 1987 only - Feb 3 12:13:50s -0:13:50 - -Rule sol87 1987 only - Feb 4 12:13:55s -0:13:55 - -Rule sol87 1987 only - Feb 5 12:14:00s -0:14:00 - -Rule sol87 1987 only - Feb 6 12:14:05s -0:14:05 - -Rule sol87 1987 only - Feb 7 12:14:10s -0:14:10 - -Rule sol87 1987 only - Feb 8 12:14:10s -0:14:10 - -Rule sol87 1987 only - Feb 9 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 10 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 11 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 12 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 13 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 14 12:14:15s -0:14:15 - -Rule sol87 1987 only - Feb 15 12:14:10s -0:14:10 - -Rule sol87 1987 only - Feb 16 12:14:10s -0:14:10 - -Rule sol87 1987 only - Feb 17 12:14:05s -0:14:05 - -Rule sol87 1987 only - Feb 18 12:14:00s -0:14:00 - -Rule sol87 1987 only - Feb 19 12:13:55s -0:13:55 - -Rule sol87 1987 only - Feb 20 12:13:50s -0:13:50 - -Rule sol87 1987 only - Feb 21 12:13:45s -0:13:45 - -Rule sol87 1987 only - Feb 22 12:13:35s -0:13:35 - -Rule sol87 1987 only - Feb 23 12:13:30s -0:13:30 - -Rule sol87 1987 only - Feb 24 12:13:20s -0:13:20 - -Rule sol87 1987 only - Feb 25 12:13:10s -0:13:10 - -Rule sol87 1987 only - Feb 26 12:13:00s -0:13:00 - -Rule sol87 1987 only - Feb 27 12:12:50s -0:12:50 - -Rule sol87 1987 only - Feb 28 12:12:40s -0:12:40 - -Rule sol87 1987 only - Mar 1 12:12:30s -0:12:30 - -Rule sol87 1987 only - Mar 2 12:12:20s -0:12:20 - -Rule sol87 1987 only - Mar 3 12:12:05s -0:12:05 - -Rule sol87 1987 only - Mar 4 12:11:55s -0:11:55 - -Rule sol87 1987 only - Mar 5 12:11:40s -0:11:40 - -Rule sol87 1987 only - Mar 6 12:11:25s -0:11:25 - -Rule sol87 1987 only - Mar 7 12:11:15s -0:11:15 - -Rule sol87 1987 only - Mar 8 12:11:00s -0:11:00 - -Rule sol87 1987 only - Mar 9 12:10:45s -0:10:45 - -Rule sol87 1987 only - Mar 10 12:10:30s -0:10:30 - -Rule sol87 1987 only - Mar 11 12:10:15s -0:10:15 - -Rule sol87 1987 only - Mar 12 12:09:55s -0:09:55 - -Rule sol87 1987 only - Mar 13 12:09:40s -0:09:40 - -Rule sol87 1987 only - Mar 14 12:09:25s -0:09:25 - -Rule sol87 1987 only - Mar 15 12:09:10s -0:09:10 - -Rule sol87 1987 only - Mar 16 12:08:50s -0:08:50 - -Rule sol87 1987 only - Mar 17 12:08:35s -0:08:35 - -Rule sol87 1987 only - Mar 18 12:08:15s -0:08:15 - -Rule sol87 1987 only - Mar 19 12:08:00s -0:08:00 - -Rule sol87 1987 only - Mar 20 12:07:40s -0:07:40 - -Rule sol87 1987 only - Mar 21 12:07:25s -0:07:25 - -Rule sol87 1987 only - Mar 22 12:07:05s -0:07:05 - -Rule sol87 1987 only - Mar 23 12:06:50s -0:06:50 - -Rule sol87 1987 only - Mar 24 12:06:30s -0:06:30 - -Rule sol87 1987 only - Mar 25 12:06:10s -0:06:10 - -Rule sol87 1987 only - Mar 26 12:05:55s -0:05:55 - -Rule sol87 1987 only - Mar 27 12:05:35s -0:05:35 - -Rule sol87 1987 only - Mar 28 12:05:15s -0:05:15 - -Rule sol87 1987 only - Mar 29 12:05:00s -0:05:00 - -Rule sol87 1987 only - Mar 30 12:04:40s -0:04:40 - -Rule sol87 1987 only - Mar 31 12:04:25s -0:04:25 - -Rule sol87 1987 only - Apr 1 12:04:05s -0:04:05 - -Rule sol87 1987 only - Apr 2 12:03:45s -0:03:45 - -Rule sol87 1987 only - Apr 3 12:03:30s -0:03:30 - -Rule sol87 1987 only - Apr 4 12:03:10s -0:03:10 - -Rule sol87 1987 only - Apr 5 12:02:55s -0:02:55 - -Rule sol87 1987 only - Apr 6 12:02:35s -0:02:35 - -Rule sol87 1987 only - Apr 7 12:02:20s -0:02:20 - -Rule sol87 1987 only - Apr 8 12:02:05s -0:02:05 - -Rule sol87 1987 only - Apr 9 12:01:45s -0:01:45 - -Rule sol87 1987 only - Apr 10 12:01:30s -0:01:30 - -Rule sol87 1987 only - Apr 11 12:01:15s -0:01:15 - -Rule sol87 1987 only - Apr 12 12:00:55s -0:00:55 - -Rule sol87 1987 only - Apr 13 12:00:40s -0:00:40 - -Rule sol87 1987 only - Apr 14 12:00:25s -0:00:25 - -Rule sol87 1987 only - Apr 15 12:00:10s -0:00:10 - -Rule sol87 1987 only - Apr 16 11:59:55s 0:00:05 - -Rule sol87 1987 only - Apr 17 11:59:45s 0:00:15 - -Rule sol87 1987 only - Apr 18 11:59:30s 0:00:30 - -Rule sol87 1987 only - Apr 19 11:59:15s 0:00:45 - -Rule sol87 1987 only - Apr 20 11:59:05s 0:00:55 - -Rule sol87 1987 only - Apr 21 11:58:50s 0:01:10 - -Rule sol87 1987 only - Apr 22 11:58:40s 0:01:20 - -Rule sol87 1987 only - Apr 23 11:58:25s 0:01:35 - -Rule sol87 1987 only - Apr 24 11:58:15s 0:01:45 - -Rule sol87 1987 only - Apr 25 11:58:05s 0:01:55 - -Rule sol87 1987 only - Apr 26 11:57:55s 0:02:05 - -Rule sol87 1987 only - Apr 27 11:57:45s 0:02:15 - -Rule sol87 1987 only - Apr 28 11:57:35s 0:02:25 - -Rule sol87 1987 only - Apr 29 11:57:25s 0:02:35 - -Rule sol87 1987 only - Apr 30 11:57:15s 0:02:45 - -Rule sol87 1987 only - May 1 11:57:10s 0:02:50 - -Rule sol87 1987 only - May 2 11:57:00s 0:03:00 - -Rule sol87 1987 only - May 3 11:56:55s 0:03:05 - -Rule sol87 1987 only - May 4 11:56:50s 0:03:10 - -Rule sol87 1987 only - May 5 11:56:45s 0:03:15 - -Rule sol87 1987 only - May 6 11:56:40s 0:03:20 - -Rule sol87 1987 only - May 7 11:56:35s 0:03:25 - -Rule sol87 1987 only - May 8 11:56:30s 0:03:30 - -Rule sol87 1987 only - May 9 11:56:25s 0:03:35 - -Rule sol87 1987 only - May 10 11:56:25s 0:03:35 - -Rule sol87 1987 only - May 11 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 12 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 13 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 14 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 15 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 16 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 17 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 18 11:56:20s 0:03:40 - -Rule sol87 1987 only - May 19 11:56:25s 0:03:35 - -Rule sol87 1987 only - May 20 11:56:25s 0:03:35 - -Rule sol87 1987 only - May 21 11:56:30s 0:03:30 - -Rule sol87 1987 only - May 22 11:56:35s 0:03:25 - -Rule sol87 1987 only - May 23 11:56:40s 0:03:20 - -Rule sol87 1987 only - May 24 11:56:45s 0:03:15 - -Rule sol87 1987 only - May 25 11:56:50s 0:03:10 - -Rule sol87 1987 only - May 26 11:56:55s 0:03:05 - -Rule sol87 1987 only - May 27 11:57:00s 0:03:00 - -Rule sol87 1987 only - May 28 11:57:10s 0:02:50 - -Rule sol87 1987 only - May 29 11:57:15s 0:02:45 - -Rule sol87 1987 only - May 30 11:57:25s 0:02:35 - -Rule sol87 1987 only - May 31 11:57:30s 0:02:30 - -Rule sol87 1987 only - Jun 1 11:57:40s 0:02:20 - -Rule sol87 1987 only - Jun 2 11:57:50s 0:02:10 - -Rule sol87 1987 only - Jun 3 11:58:00s 0:02:00 - -Rule sol87 1987 only - Jun 4 11:58:10s 0:01:50 - -Rule sol87 1987 only - Jun 5 11:58:20s 0:01:40 - -Rule sol87 1987 only - Jun 6 11:58:30s 0:01:30 - -Rule sol87 1987 only - Jun 7 11:58:40s 0:01:20 - -Rule sol87 1987 only - Jun 8 11:58:50s 0:01:10 - -Rule sol87 1987 only - Jun 9 11:59:05s 0:00:55 - -Rule sol87 1987 only - Jun 10 11:59:15s 0:00:45 - -Rule sol87 1987 only - Jun 11 11:59:30s 0:00:30 - -Rule sol87 1987 only - Jun 12 11:59:40s 0:00:20 - -Rule sol87 1987 only - Jun 13 11:59:50s 0:00:10 - -Rule sol87 1987 only - Jun 14 12:00:05s -0:00:05 - -Rule sol87 1987 only - Jun 15 12:00:15s -0:00:15 - -Rule sol87 1987 only - Jun 16 12:00:30s -0:00:30 - -Rule sol87 1987 only - Jun 17 12:00:45s -0:00:45 - -Rule sol87 1987 only - Jun 18 12:00:55s -0:00:55 - -Rule sol87 1987 only - Jun 19 12:01:10s -0:01:10 - -Rule sol87 1987 only - Jun 20 12:01:20s -0:01:20 - -Rule sol87 1987 only - Jun 21 12:01:35s -0:01:35 - -Rule sol87 1987 only - Jun 22 12:01:50s -0:01:50 - -Rule sol87 1987 only - Jun 23 12:02:00s -0:02:00 - -Rule sol87 1987 only - Jun 24 12:02:15s -0:02:15 - -Rule sol87 1987 only - Jun 25 12:02:25s -0:02:25 - -Rule sol87 1987 only - Jun 26 12:02:40s -0:02:40 - -Rule sol87 1987 only - Jun 27 12:02:50s -0:02:50 - -Rule sol87 1987 only - Jun 28 12:03:05s -0:03:05 - -Rule sol87 1987 only - Jun 29 12:03:15s -0:03:15 - -Rule sol87 1987 only - Jun 30 12:03:30s -0:03:30 - -Rule sol87 1987 only - Jul 1 12:03:40s -0:03:40 - -Rule sol87 1987 only - Jul 2 12:03:50s -0:03:50 - -Rule sol87 1987 only - Jul 3 12:04:05s -0:04:05 - -Rule sol87 1987 only - Jul 4 12:04:15s -0:04:15 - -Rule sol87 1987 only - Jul 5 12:04:25s -0:04:25 - -Rule sol87 1987 only - Jul 6 12:04:35s -0:04:35 - -Rule sol87 1987 only - Jul 7 12:04:45s -0:04:45 - -Rule sol87 1987 only - Jul 8 12:04:55s -0:04:55 - -Rule sol87 1987 only - Jul 9 12:05:05s -0:05:05 - -Rule sol87 1987 only - Jul 10 12:05:15s -0:05:15 - -Rule sol87 1987 only - Jul 11 12:05:20s -0:05:20 - -Rule sol87 1987 only - Jul 12 12:05:30s -0:05:30 - -Rule sol87 1987 only - Jul 13 12:05:40s -0:05:40 - -Rule sol87 1987 only - Jul 14 12:05:45s -0:05:45 - -Rule sol87 1987 only - Jul 15 12:05:50s -0:05:50 - -Rule sol87 1987 only - Jul 16 12:06:00s -0:06:00 - -Rule sol87 1987 only - Jul 17 12:06:05s -0:06:05 - -Rule sol87 1987 only - Jul 18 12:06:10s -0:06:10 - -Rule sol87 1987 only - Jul 19 12:06:15s -0:06:15 - -Rule sol87 1987 only - Jul 20 12:06:15s -0:06:15 - -Rule sol87 1987 only - Jul 21 12:06:20s -0:06:20 - -Rule sol87 1987 only - Jul 22 12:06:25s -0:06:25 - -Rule sol87 1987 only - Jul 23 12:06:25s -0:06:25 - -Rule sol87 1987 only - Jul 24 12:06:25s -0:06:25 - -Rule sol87 1987 only - Jul 25 12:06:30s -0:06:30 - -Rule sol87 1987 only - Jul 26 12:06:30s -0:06:30 - -Rule sol87 1987 only - Jul 27 12:06:30s -0:06:30 - -Rule sol87 1987 only - Jul 28 12:06:30s -0:06:30 - -Rule sol87 1987 only - Jul 29 12:06:25s -0:06:25 - -Rule sol87 1987 only - Jul 30 12:06:25s -0:06:25 - -Rule sol87 1987 only - Jul 31 12:06:25s -0:06:25 - -Rule sol87 1987 only - Aug 1 12:06:20s -0:06:20 - -Rule sol87 1987 only - Aug 2 12:06:15s -0:06:15 - -Rule sol87 1987 only - Aug 3 12:06:10s -0:06:10 - -Rule sol87 1987 only - Aug 4 12:06:05s -0:06:05 - -Rule sol87 1987 only - Aug 5 12:06:00s -0:06:00 - -Rule sol87 1987 only - Aug 6 12:05:55s -0:05:55 - -Rule sol87 1987 only - Aug 7 12:05:50s -0:05:50 - -Rule sol87 1987 only - Aug 8 12:05:40s -0:05:40 - -Rule sol87 1987 only - Aug 9 12:05:35s -0:05:35 - -Rule sol87 1987 only - Aug 10 12:05:25s -0:05:25 - -Rule sol87 1987 only - Aug 11 12:05:15s -0:05:15 - -Rule sol87 1987 only - Aug 12 12:05:05s -0:05:05 - -Rule sol87 1987 only - Aug 13 12:04:55s -0:04:55 - -Rule sol87 1987 only - Aug 14 12:04:45s -0:04:45 - -Rule sol87 1987 only - Aug 15 12:04:35s -0:04:35 - -Rule sol87 1987 only - Aug 16 12:04:25s -0:04:25 - -Rule sol87 1987 only - Aug 17 12:04:10s -0:04:10 - -Rule sol87 1987 only - Aug 18 12:04:00s -0:04:00 - -Rule sol87 1987 only - Aug 19 12:03:45s -0:03:45 - -Rule sol87 1987 only - Aug 20 12:03:30s -0:03:30 - -Rule sol87 1987 only - Aug 21 12:03:15s -0:03:15 - -Rule sol87 1987 only - Aug 22 12:03:00s -0:03:00 - -Rule sol87 1987 only - Aug 23 12:02:45s -0:02:45 - -Rule sol87 1987 only - Aug 24 12:02:30s -0:02:30 - -Rule sol87 1987 only - Aug 25 12:02:15s -0:02:15 - -Rule sol87 1987 only - Aug 26 12:02:00s -0:02:00 - -Rule sol87 1987 only - Aug 27 12:01:40s -0:01:40 - -Rule sol87 1987 only - Aug 28 12:01:25s -0:01:25 - -Rule sol87 1987 only - Aug 29 12:01:05s -0:01:05 - -Rule sol87 1987 only - Aug 30 12:00:50s -0:00:50 - -Rule sol87 1987 only - Aug 31 12:00:30s -0:00:30 - -Rule sol87 1987 only - Sep 1 12:00:10s -0:00:10 - -Rule sol87 1987 only - Sep 2 11:59:50s 0:00:10 - -Rule sol87 1987 only - Sep 3 11:59:35s 0:00:25 - -Rule sol87 1987 only - Sep 4 11:59:15s 0:00:45 - -Rule sol87 1987 only - Sep 5 11:58:55s 0:01:05 - -Rule sol87 1987 only - Sep 6 11:58:35s 0:01:25 - -Rule sol87 1987 only - Sep 7 11:58:15s 0:01:45 - -Rule sol87 1987 only - Sep 8 11:57:55s 0:02:05 - -Rule sol87 1987 only - Sep 9 11:57:30s 0:02:30 - -Rule sol87 1987 only - Sep 10 11:57:10s 0:02:50 - -Rule sol87 1987 only - Sep 11 11:56:50s 0:03:10 - -Rule sol87 1987 only - Sep 12 11:56:30s 0:03:30 - -Rule sol87 1987 only - Sep 13 11:56:10s 0:03:50 - -Rule sol87 1987 only - Sep 14 11:55:45s 0:04:15 - -Rule sol87 1987 only - Sep 15 11:55:25s 0:04:35 - -Rule sol87 1987 only - Sep 16 11:55:05s 0:04:55 - -Rule sol87 1987 only - Sep 17 11:54:45s 0:05:15 - -Rule sol87 1987 only - Sep 18 11:54:20s 0:05:40 - -Rule sol87 1987 only - Sep 19 11:54:00s 0:06:00 - -Rule sol87 1987 only - Sep 20 11:53:40s 0:06:20 - -Rule sol87 1987 only - Sep 21 11:53:15s 0:06:45 - -Rule sol87 1987 only - Sep 22 11:52:55s 0:07:05 - -Rule sol87 1987 only - Sep 23 11:52:35s 0:07:25 - -Rule sol87 1987 only - Sep 24 11:52:15s 0:07:45 - -Rule sol87 1987 only - Sep 25 11:51:55s 0:08:05 - -Rule sol87 1987 only - Sep 26 11:51:35s 0:08:25 - -Rule sol87 1987 only - Sep 27 11:51:10s 0:08:50 - -Rule sol87 1987 only - Sep 28 11:50:50s 0:09:10 - -Rule sol87 1987 only - Sep 29 11:50:30s 0:09:30 - -Rule sol87 1987 only - Sep 30 11:50:10s 0:09:50 - -Rule sol87 1987 only - Oct 1 11:49:50s 0:10:10 - -Rule sol87 1987 only - Oct 2 11:49:35s 0:10:25 - -Rule sol87 1987 only - Oct 3 11:49:15s 0:10:45 - -Rule sol87 1987 only - Oct 4 11:48:55s 0:11:05 - -Rule sol87 1987 only - Oct 5 11:48:35s 0:11:25 - -Rule sol87 1987 only - Oct 6 11:48:20s 0:11:40 - -Rule sol87 1987 only - Oct 7 11:48:00s 0:12:00 - -Rule sol87 1987 only - Oct 8 11:47:45s 0:12:15 - -Rule sol87 1987 only - Oct 9 11:47:25s 0:12:35 - -Rule sol87 1987 only - Oct 10 11:47:10s 0:12:50 - -Rule sol87 1987 only - Oct 11 11:46:55s 0:13:05 - -Rule sol87 1987 only - Oct 12 11:46:40s 0:13:20 - -Rule sol87 1987 only - Oct 13 11:46:25s 0:13:35 - -Rule sol87 1987 only - Oct 14 11:46:10s 0:13:50 - -Rule sol87 1987 only - Oct 15 11:45:55s 0:14:05 - -Rule sol87 1987 only - Oct 16 11:45:45s 0:14:15 - -Rule sol87 1987 only - Oct 17 11:45:30s 0:14:30 - -Rule sol87 1987 only - Oct 18 11:45:20s 0:14:40 - -Rule sol87 1987 only - Oct 19 11:45:05s 0:14:55 - -Rule sol87 1987 only - Oct 20 11:44:55s 0:15:05 - -Rule sol87 1987 only - Oct 21 11:44:45s 0:15:15 - -Rule sol87 1987 only - Oct 22 11:44:35s 0:15:25 - -Rule sol87 1987 only - Oct 23 11:44:25s 0:15:35 - -Rule sol87 1987 only - Oct 24 11:44:20s 0:15:40 - -Rule sol87 1987 only - Oct 25 11:44:10s 0:15:50 - -Rule sol87 1987 only - Oct 26 11:44:05s 0:15:55 - -Rule sol87 1987 only - Oct 27 11:43:55s 0:16:05 - -Rule sol87 1987 only - Oct 28 11:43:50s 0:16:10 - -Rule sol87 1987 only - Oct 29 11:43:45s 0:16:15 - -Rule sol87 1987 only - Oct 30 11:43:45s 0:16:15 - -Rule sol87 1987 only - Oct 31 11:43:40s 0:16:20 - -Rule sol87 1987 only - Nov 1 11:43:40s 0:16:20 - -Rule sol87 1987 only - Nov 2 11:43:35s 0:16:25 - -Rule sol87 1987 only - Nov 3 11:43:35s 0:16:25 - -Rule sol87 1987 only - Nov 4 11:43:35s 0:16:25 - -Rule sol87 1987 only - Nov 5 11:43:35s 0:16:25 - -Rule sol87 1987 only - Nov 6 11:43:40s 0:16:20 - -Rule sol87 1987 only - Nov 7 11:43:40s 0:16:20 - -Rule sol87 1987 only - Nov 8 11:43:45s 0:16:15 - -Rule sol87 1987 only - Nov 9 11:43:50s 0:16:10 - -Rule sol87 1987 only - Nov 10 11:43:55s 0:16:05 - -Rule sol87 1987 only - Nov 11 11:44:00s 0:16:00 - -Rule sol87 1987 only - Nov 12 11:44:05s 0:15:55 - -Rule sol87 1987 only - Nov 13 11:44:15s 0:15:45 - -Rule sol87 1987 only - Nov 14 11:44:20s 0:15:40 - -Rule sol87 1987 only - Nov 15 11:44:30s 0:15:30 - -Rule sol87 1987 only - Nov 16 11:44:40s 0:15:20 - -Rule sol87 1987 only - Nov 17 11:44:50s 0:15:10 - -Rule sol87 1987 only - Nov 18 11:45:05s 0:14:55 - -Rule sol87 1987 only - Nov 19 11:45:15s 0:14:45 - -Rule sol87 1987 only - Nov 20 11:45:30s 0:14:30 - -Rule sol87 1987 only - Nov 21 11:45:45s 0:14:15 - -Rule sol87 1987 only - Nov 22 11:46:00s 0:14:00 - -Rule sol87 1987 only - Nov 23 11:46:15s 0:13:45 - -Rule sol87 1987 only - Nov 24 11:46:30s 0:13:30 - -Rule sol87 1987 only - Nov 25 11:46:50s 0:13:10 - -Rule sol87 1987 only - Nov 26 11:47:10s 0:12:50 - -Rule sol87 1987 only - Nov 27 11:47:25s 0:12:35 - -Rule sol87 1987 only - Nov 28 11:47:45s 0:12:15 - -Rule sol87 1987 only - Nov 29 11:48:05s 0:11:55 - -Rule sol87 1987 only - Nov 30 11:48:30s 0:11:30 - -Rule sol87 1987 only - Dec 1 11:48:50s 0:11:10 - -Rule sol87 1987 only - Dec 2 11:49:10s 0:10:50 - -Rule sol87 1987 only - Dec 3 11:49:35s 0:10:25 - -Rule sol87 1987 only - Dec 4 11:50:00s 0:10:00 - -Rule sol87 1987 only - Dec 5 11:50:25s 0:09:35 - -Rule sol87 1987 only - Dec 6 11:50:50s 0:09:10 - -Rule sol87 1987 only - Dec 7 11:51:15s 0:08:45 - -Rule sol87 1987 only - Dec 8 11:51:40s 0:08:20 - -Rule sol87 1987 only - Dec 9 11:52:05s 0:07:55 - -Rule sol87 1987 only - Dec 10 11:52:30s 0:07:30 - -Rule sol87 1987 only - Dec 11 11:53:00s 0:07:00 - -Rule sol87 1987 only - Dec 12 11:53:25s 0:06:35 - -Rule sol87 1987 only - Dec 13 11:53:55s 0:06:05 - -Rule sol87 1987 only - Dec 14 11:54:25s 0:05:35 - -Rule sol87 1987 only - Dec 15 11:54:50s 0:05:10 - -Rule sol87 1987 only - Dec 16 11:55:20s 0:04:40 - -Rule sol87 1987 only - Dec 17 11:55:50s 0:04:10 - -Rule sol87 1987 only - Dec 18 11:56:20s 0:03:40 - -Rule sol87 1987 only - Dec 19 11:56:50s 0:03:10 - -Rule sol87 1987 only - Dec 20 11:57:20s 0:02:40 - -Rule sol87 1987 only - Dec 21 11:57:50s 0:02:10 - -Rule sol87 1987 only - Dec 22 11:58:20s 0:01:40 - -Rule sol87 1987 only - Dec 23 11:58:50s 0:01:10 - -Rule sol87 1987 only - Dec 24 11:59:20s 0:00:40 - -Rule sol87 1987 only - Dec 25 11:59:50s 0:00:10 - -Rule sol87 1987 only - Dec 26 12:00:20s -0:00:20 - -Rule sol87 1987 only - Dec 27 12:00:45s -0:00:45 - -Rule sol87 1987 only - Dec 28 12:01:15s -0:01:15 - -Rule sol87 1987 only - Dec 29 12:01:45s -0:01:45 - -Rule sol87 1987 only - Dec 30 12:02:15s -0:02:15 - -Rule sol87 1987 only - Dec 31 12:02:45s -0:02:45 - - -# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs -# Before and after 1987, we'll operate on local mean solar time. - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone Asia/Riyadh87 3:07:04 - zzz 1987 - 3:07:04 sol87 zzz 1988 - 3:07:04 - zzz -# For backward compatibility... -Link Asia/Riyadh87 Mideast/Riyadh87 diff --git a/src/java.base/share/data/tzdata/solar88 b/src/java.base/share/data/tzdata/solar88 deleted file mode 100644 index 3314cb1d640..00000000000 --- a/src/java.base/share/data/tzdata/solar88 +++ /dev/null @@ -1,413 +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. 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. -# -# <pre> -# This file is in the public domain, so clarified as of -# 2009-05-17 by Arthur David Olson. - -# Apparent noon times below are for Riyadh; they're a bit off for other places. -# Times were computed using formulas in the U.S. Naval Observatory's -# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of -# [plus or minus two] seconds during the current year." -# -# Rounding to the nearest five seconds results in fewer than -# 256 different "time types"--a limit that's faced because time types are -# stored on disk as unsigned chars. - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule sol88 1988 only - Jan 1 12:03:15s -0:03:15 - -Rule sol88 1988 only - Jan 2 12:03:40s -0:03:40 - -Rule sol88 1988 only - Jan 3 12:04:10s -0:04:10 - -Rule sol88 1988 only - Jan 4 12:04:40s -0:04:40 - -Rule sol88 1988 only - Jan 5 12:05:05s -0:05:05 - -Rule sol88 1988 only - Jan 6 12:05:30s -0:05:30 - -Rule sol88 1988 only - Jan 7 12:06:00s -0:06:00 - -Rule sol88 1988 only - Jan 8 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jan 9 12:06:50s -0:06:50 - -Rule sol88 1988 only - Jan 10 12:07:15s -0:07:15 - -Rule sol88 1988 only - Jan 11 12:07:40s -0:07:40 - -Rule sol88 1988 only - Jan 12 12:08:05s -0:08:05 - -Rule sol88 1988 only - Jan 13 12:08:25s -0:08:25 - -Rule sol88 1988 only - Jan 14 12:08:50s -0:08:50 - -Rule sol88 1988 only - Jan 15 12:09:10s -0:09:10 - -Rule sol88 1988 only - Jan 16 12:09:30s -0:09:30 - -Rule sol88 1988 only - Jan 17 12:09:50s -0:09:50 - -Rule sol88 1988 only - Jan 18 12:10:10s -0:10:10 - -Rule sol88 1988 only - Jan 19 12:10:30s -0:10:30 - -Rule sol88 1988 only - Jan 20 12:10:50s -0:10:50 - -Rule sol88 1988 only - Jan 21 12:11:05s -0:11:05 - -Rule sol88 1988 only - Jan 22 12:11:25s -0:11:25 - -Rule sol88 1988 only - Jan 23 12:11:40s -0:11:40 - -Rule sol88 1988 only - Jan 24 12:11:55s -0:11:55 - -Rule sol88 1988 only - Jan 25 12:12:10s -0:12:10 - -Rule sol88 1988 only - Jan 26 12:12:25s -0:12:25 - -Rule sol88 1988 only - Jan 27 12:12:40s -0:12:40 - -Rule sol88 1988 only - Jan 28 12:12:50s -0:12:50 - -Rule sol88 1988 only - Jan 29 12:13:00s -0:13:00 - -Rule sol88 1988 only - Jan 30 12:13:10s -0:13:10 - -Rule sol88 1988 only - Jan 31 12:13:20s -0:13:20 - -Rule sol88 1988 only - Feb 1 12:13:30s -0:13:30 - -Rule sol88 1988 only - Feb 2 12:13:40s -0:13:40 - -Rule sol88 1988 only - Feb 3 12:13:45s -0:13:45 - -Rule sol88 1988 only - Feb 4 12:13:55s -0:13:55 - -Rule sol88 1988 only - Feb 5 12:14:00s -0:14:00 - -Rule sol88 1988 only - Feb 6 12:14:05s -0:14:05 - -Rule sol88 1988 only - Feb 7 12:14:10s -0:14:10 - -Rule sol88 1988 only - Feb 8 12:14:10s -0:14:10 - -Rule sol88 1988 only - Feb 9 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 10 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 11 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 12 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 13 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 14 12:14:15s -0:14:15 - -Rule sol88 1988 only - Feb 15 12:14:10s -0:14:10 - -Rule sol88 1988 only - Feb 16 12:14:10s -0:14:10 - -Rule sol88 1988 only - Feb 17 12:14:05s -0:14:05 - -Rule sol88 1988 only - Feb 18 12:14:00s -0:14:00 - -Rule sol88 1988 only - Feb 19 12:13:55s -0:13:55 - -Rule sol88 1988 only - Feb 20 12:13:50s -0:13:50 - -Rule sol88 1988 only - Feb 21 12:13:45s -0:13:45 - -Rule sol88 1988 only - Feb 22 12:13:40s -0:13:40 - -Rule sol88 1988 only - Feb 23 12:13:30s -0:13:30 - -Rule sol88 1988 only - Feb 24 12:13:20s -0:13:20 - -Rule sol88 1988 only - Feb 25 12:13:15s -0:13:15 - -Rule sol88 1988 only - Feb 26 12:13:05s -0:13:05 - -Rule sol88 1988 only - Feb 27 12:12:55s -0:12:55 - -Rule sol88 1988 only - Feb 28 12:12:45s -0:12:45 - -Rule sol88 1988 only - Feb 29 12:12:30s -0:12:30 - -Rule sol88 1988 only - Mar 1 12:12:20s -0:12:20 - -Rule sol88 1988 only - Mar 2 12:12:10s -0:12:10 - -Rule sol88 1988 only - Mar 3 12:11:55s -0:11:55 - -Rule sol88 1988 only - Mar 4 12:11:45s -0:11:45 - -Rule sol88 1988 only - Mar 5 12:11:30s -0:11:30 - -Rule sol88 1988 only - Mar 6 12:11:15s -0:11:15 - -Rule sol88 1988 only - Mar 7 12:11:00s -0:11:00 - -Rule sol88 1988 only - Mar 8 12:10:45s -0:10:45 - -Rule sol88 1988 only - Mar 9 12:10:30s -0:10:30 - -Rule sol88 1988 only - Mar 10 12:10:15s -0:10:15 - -Rule sol88 1988 only - Mar 11 12:10:00s -0:10:00 - -Rule sol88 1988 only - Mar 12 12:09:45s -0:09:45 - -Rule sol88 1988 only - Mar 13 12:09:30s -0:09:30 - -Rule sol88 1988 only - Mar 14 12:09:10s -0:09:10 - -Rule sol88 1988 only - Mar 15 12:08:55s -0:08:55 - -Rule sol88 1988 only - Mar 16 12:08:40s -0:08:40 - -Rule sol88 1988 only - Mar 17 12:08:20s -0:08:20 - -Rule sol88 1988 only - Mar 18 12:08:05s -0:08:05 - -Rule sol88 1988 only - Mar 19 12:07:45s -0:07:45 - -Rule sol88 1988 only - Mar 20 12:07:30s -0:07:30 - -Rule sol88 1988 only - Mar 21 12:07:10s -0:07:10 - -Rule sol88 1988 only - Mar 22 12:06:50s -0:06:50 - -Rule sol88 1988 only - Mar 23 12:06:35s -0:06:35 - -Rule sol88 1988 only - Mar 24 12:06:15s -0:06:15 - -Rule sol88 1988 only - Mar 25 12:06:00s -0:06:00 - -Rule sol88 1988 only - Mar 26 12:05:40s -0:05:40 - -Rule sol88 1988 only - Mar 27 12:05:20s -0:05:20 - -Rule sol88 1988 only - Mar 28 12:05:05s -0:05:05 - -Rule sol88 1988 only - Mar 29 12:04:45s -0:04:45 - -Rule sol88 1988 only - Mar 30 12:04:25s -0:04:25 - -Rule sol88 1988 only - Mar 31 12:04:10s -0:04:10 - -Rule sol88 1988 only - Apr 1 12:03:50s -0:03:50 - -Rule sol88 1988 only - Apr 2 12:03:35s -0:03:35 - -Rule sol88 1988 only - Apr 3 12:03:15s -0:03:15 - -Rule sol88 1988 only - Apr 4 12:03:00s -0:03:00 - -Rule sol88 1988 only - Apr 5 12:02:40s -0:02:40 - -Rule sol88 1988 only - Apr 6 12:02:25s -0:02:25 - -Rule sol88 1988 only - Apr 7 12:02:05s -0:02:05 - -Rule sol88 1988 only - Apr 8 12:01:50s -0:01:50 - -Rule sol88 1988 only - Apr 9 12:01:35s -0:01:35 - -Rule sol88 1988 only - Apr 10 12:01:15s -0:01:15 - -Rule sol88 1988 only - Apr 11 12:01:00s -0:01:00 - -Rule sol88 1988 only - Apr 12 12:00:45s -0:00:45 - -Rule sol88 1988 only - Apr 13 12:00:30s -0:00:30 - -Rule sol88 1988 only - Apr 14 12:00:15s -0:00:15 - -Rule sol88 1988 only - Apr 15 12:00:00s 0:00:00 - -Rule sol88 1988 only - Apr 16 11:59:45s 0:00:15 - -Rule sol88 1988 only - Apr 17 11:59:30s 0:00:30 - -Rule sol88 1988 only - Apr 18 11:59:20s 0:00:40 - -Rule sol88 1988 only - Apr 19 11:59:05s 0:00:55 - -Rule sol88 1988 only - Apr 20 11:58:55s 0:01:05 - -Rule sol88 1988 only - Apr 21 11:58:40s 0:01:20 - -Rule sol88 1988 only - Apr 22 11:58:30s 0:01:30 - -Rule sol88 1988 only - Apr 23 11:58:15s 0:01:45 - -Rule sol88 1988 only - Apr 24 11:58:05s 0:01:55 - -Rule sol88 1988 only - Apr 25 11:57:55s 0:02:05 - -Rule sol88 1988 only - Apr 26 11:57:45s 0:02:15 - -Rule sol88 1988 only - Apr 27 11:57:35s 0:02:25 - -Rule sol88 1988 only - Apr 28 11:57:30s 0:02:30 - -Rule sol88 1988 only - Apr 29 11:57:20s 0:02:40 - -Rule sol88 1988 only - Apr 30 11:57:10s 0:02:50 - -Rule sol88 1988 only - May 1 11:57:05s 0:02:55 - -Rule sol88 1988 only - May 2 11:56:55s 0:03:05 - -Rule sol88 1988 only - May 3 11:56:50s 0:03:10 - -Rule sol88 1988 only - May 4 11:56:45s 0:03:15 - -Rule sol88 1988 only - May 5 11:56:40s 0:03:20 - -Rule sol88 1988 only - May 6 11:56:35s 0:03:25 - -Rule sol88 1988 only - May 7 11:56:30s 0:03:30 - -Rule sol88 1988 only - May 8 11:56:25s 0:03:35 - -Rule sol88 1988 only - May 9 11:56:25s 0:03:35 - -Rule sol88 1988 only - May 10 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 11 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 12 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 13 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 14 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 15 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 16 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 17 11:56:20s 0:03:40 - -Rule sol88 1988 only - May 18 11:56:25s 0:03:35 - -Rule sol88 1988 only - May 19 11:56:25s 0:03:35 - -Rule sol88 1988 only - May 20 11:56:30s 0:03:30 - -Rule sol88 1988 only - May 21 11:56:35s 0:03:25 - -Rule sol88 1988 only - May 22 11:56:40s 0:03:20 - -Rule sol88 1988 only - May 23 11:56:45s 0:03:15 - -Rule sol88 1988 only - May 24 11:56:50s 0:03:10 - -Rule sol88 1988 only - May 25 11:56:55s 0:03:05 - -Rule sol88 1988 only - May 26 11:57:00s 0:03:00 - -Rule sol88 1988 only - May 27 11:57:05s 0:02:55 - -Rule sol88 1988 only - May 28 11:57:15s 0:02:45 - -Rule sol88 1988 only - May 29 11:57:20s 0:02:40 - -Rule sol88 1988 only - May 30 11:57:30s 0:02:30 - -Rule sol88 1988 only - May 31 11:57:40s 0:02:20 - -Rule sol88 1988 only - Jun 1 11:57:50s 0:02:10 - -Rule sol88 1988 only - Jun 2 11:57:55s 0:02:05 - -Rule sol88 1988 only - Jun 3 11:58:05s 0:01:55 - -Rule sol88 1988 only - Jun 4 11:58:15s 0:01:45 - -Rule sol88 1988 only - Jun 5 11:58:30s 0:01:30 - -Rule sol88 1988 only - Jun 6 11:58:40s 0:01:20 - -Rule sol88 1988 only - Jun 7 11:58:50s 0:01:10 - -Rule sol88 1988 only - Jun 8 11:59:00s 0:01:00 - -Rule sol88 1988 only - Jun 9 11:59:15s 0:00:45 - -Rule sol88 1988 only - Jun 10 11:59:25s 0:00:35 - -Rule sol88 1988 only - Jun 11 11:59:35s 0:00:25 - -Rule sol88 1988 only - Jun 12 11:59:50s 0:00:10 - -Rule sol88 1988 only - Jun 13 12:00:00s 0:00:00 - -Rule sol88 1988 only - Jun 14 12:00:15s -0:00:15 - -Rule sol88 1988 only - Jun 15 12:00:25s -0:00:25 - -Rule sol88 1988 only - Jun 16 12:00:40s -0:00:40 - -Rule sol88 1988 only - Jun 17 12:00:55s -0:00:55 - -Rule sol88 1988 only - Jun 18 12:01:05s -0:01:05 - -Rule sol88 1988 only - Jun 19 12:01:20s -0:01:20 - -Rule sol88 1988 only - Jun 20 12:01:30s -0:01:30 - -Rule sol88 1988 only - Jun 21 12:01:45s -0:01:45 - -Rule sol88 1988 only - Jun 22 12:02:00s -0:02:00 - -Rule sol88 1988 only - Jun 23 12:02:10s -0:02:10 - -Rule sol88 1988 only - Jun 24 12:02:25s -0:02:25 - -Rule sol88 1988 only - Jun 25 12:02:35s -0:02:35 - -Rule sol88 1988 only - Jun 26 12:02:50s -0:02:50 - -Rule sol88 1988 only - Jun 27 12:03:00s -0:03:00 - -Rule sol88 1988 only - Jun 28 12:03:15s -0:03:15 - -Rule sol88 1988 only - Jun 29 12:03:25s -0:03:25 - -Rule sol88 1988 only - Jun 30 12:03:40s -0:03:40 - -Rule sol88 1988 only - Jul 1 12:03:50s -0:03:50 - -Rule sol88 1988 only - Jul 2 12:04:00s -0:04:00 - -Rule sol88 1988 only - Jul 3 12:04:10s -0:04:10 - -Rule sol88 1988 only - Jul 4 12:04:25s -0:04:25 - -Rule sol88 1988 only - Jul 5 12:04:35s -0:04:35 - -Rule sol88 1988 only - Jul 6 12:04:45s -0:04:45 - -Rule sol88 1988 only - Jul 7 12:04:55s -0:04:55 - -Rule sol88 1988 only - Jul 8 12:05:05s -0:05:05 - -Rule sol88 1988 only - Jul 9 12:05:10s -0:05:10 - -Rule sol88 1988 only - Jul 10 12:05:20s -0:05:20 - -Rule sol88 1988 only - Jul 11 12:05:30s -0:05:30 - -Rule sol88 1988 only - Jul 12 12:05:35s -0:05:35 - -Rule sol88 1988 only - Jul 13 12:05:45s -0:05:45 - -Rule sol88 1988 only - Jul 14 12:05:50s -0:05:50 - -Rule sol88 1988 only - Jul 15 12:05:55s -0:05:55 - -Rule sol88 1988 only - Jul 16 12:06:00s -0:06:00 - -Rule sol88 1988 only - Jul 17 12:06:05s -0:06:05 - -Rule sol88 1988 only - Jul 18 12:06:10s -0:06:10 - -Rule sol88 1988 only - Jul 19 12:06:15s -0:06:15 - -Rule sol88 1988 only - Jul 20 12:06:20s -0:06:20 - -Rule sol88 1988 only - Jul 21 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jul 22 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jul 23 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jul 24 12:06:30s -0:06:30 - -Rule sol88 1988 only - Jul 25 12:06:30s -0:06:30 - -Rule sol88 1988 only - Jul 26 12:06:30s -0:06:30 - -Rule sol88 1988 only - Jul 27 12:06:30s -0:06:30 - -Rule sol88 1988 only - Jul 28 12:06:30s -0:06:30 - -Rule sol88 1988 only - Jul 29 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jul 30 12:06:25s -0:06:25 - -Rule sol88 1988 only - Jul 31 12:06:20s -0:06:20 - -Rule sol88 1988 only - Aug 1 12:06:15s -0:06:15 - -Rule sol88 1988 only - Aug 2 12:06:15s -0:06:15 - -Rule sol88 1988 only - Aug 3 12:06:10s -0:06:10 - -Rule sol88 1988 only - Aug 4 12:06:05s -0:06:05 - -Rule sol88 1988 only - Aug 5 12:05:55s -0:05:55 - -Rule sol88 1988 only - Aug 6 12:05:50s -0:05:50 - -Rule sol88 1988 only - Aug 7 12:05:45s -0:05:45 - -Rule sol88 1988 only - Aug 8 12:05:35s -0:05:35 - -Rule sol88 1988 only - Aug 9 12:05:25s -0:05:25 - -Rule sol88 1988 only - Aug 10 12:05:20s -0:05:20 - -Rule sol88 1988 only - Aug 11 12:05:10s -0:05:10 - -Rule sol88 1988 only - Aug 12 12:05:00s -0:05:00 - -Rule sol88 1988 only - Aug 13 12:04:50s -0:04:50 - -Rule sol88 1988 only - Aug 14 12:04:35s -0:04:35 - -Rule sol88 1988 only - Aug 15 12:04:25s -0:04:25 - -Rule sol88 1988 only - Aug 16 12:04:15s -0:04:15 - -Rule sol88 1988 only - Aug 17 12:04:00s -0:04:00 - -Rule sol88 1988 only - Aug 18 12:03:50s -0:03:50 - -Rule sol88 1988 only - Aug 19 12:03:35s -0:03:35 - -Rule sol88 1988 only - Aug 20 12:03:20s -0:03:20 - -Rule sol88 1988 only - Aug 21 12:03:05s -0:03:05 - -Rule sol88 1988 only - Aug 22 12:02:50s -0:02:50 - -Rule sol88 1988 only - Aug 23 12:02:35s -0:02:35 - -Rule sol88 1988 only - Aug 24 12:02:20s -0:02:20 - -Rule sol88 1988 only - Aug 25 12:02:00s -0:02:00 - -Rule sol88 1988 only - Aug 26 12:01:45s -0:01:45 - -Rule sol88 1988 only - Aug 27 12:01:30s -0:01:30 - -Rule sol88 1988 only - Aug 28 12:01:10s -0:01:10 - -Rule sol88 1988 only - Aug 29 12:00:50s -0:00:50 - -Rule sol88 1988 only - Aug 30 12:00:35s -0:00:35 - -Rule sol88 1988 only - Aug 31 12:00:15s -0:00:15 - -Rule sol88 1988 only - Sep 1 11:59:55s 0:00:05 - -Rule sol88 1988 only - Sep 2 11:59:35s 0:00:25 - -Rule sol88 1988 only - Sep 3 11:59:20s 0:00:40 - -Rule sol88 1988 only - Sep 4 11:59:00s 0:01:00 - -Rule sol88 1988 only - Sep 5 11:58:40s 0:01:20 - -Rule sol88 1988 only - Sep 6 11:58:20s 0:01:40 - -Rule sol88 1988 only - Sep 7 11:58:00s 0:02:00 - -Rule sol88 1988 only - Sep 8 11:57:35s 0:02:25 - -Rule sol88 1988 only - Sep 9 11:57:15s 0:02:45 - -Rule sol88 1988 only - Sep 10 11:56:55s 0:03:05 - -Rule sol88 1988 only - Sep 11 11:56:35s 0:03:25 - -Rule sol88 1988 only - Sep 12 11:56:15s 0:03:45 - -Rule sol88 1988 only - Sep 13 11:55:50s 0:04:10 - -Rule sol88 1988 only - Sep 14 11:55:30s 0:04:30 - -Rule sol88 1988 only - Sep 15 11:55:10s 0:04:50 - -Rule sol88 1988 only - Sep 16 11:54:50s 0:05:10 - -Rule sol88 1988 only - Sep 17 11:54:25s 0:05:35 - -Rule sol88 1988 only - Sep 18 11:54:05s 0:05:55 - -Rule sol88 1988 only - Sep 19 11:53:45s 0:06:15 - -Rule sol88 1988 only - Sep 20 11:53:25s 0:06:35 - -Rule sol88 1988 only - Sep 21 11:53:00s 0:07:00 - -Rule sol88 1988 only - Sep 22 11:52:40s 0:07:20 - -Rule sol88 1988 only - Sep 23 11:52:20s 0:07:40 - -Rule sol88 1988 only - Sep 24 11:52:00s 0:08:00 - -Rule sol88 1988 only - Sep 25 11:51:40s 0:08:20 - -Rule sol88 1988 only - Sep 26 11:51:15s 0:08:45 - -Rule sol88 1988 only - Sep 27 11:50:55s 0:09:05 - -Rule sol88 1988 only - Sep 28 11:50:35s 0:09:25 - -Rule sol88 1988 only - Sep 29 11:50:15s 0:09:45 - -Rule sol88 1988 only - Sep 30 11:49:55s 0:10:05 - -Rule sol88 1988 only - Oct 1 11:49:35s 0:10:25 - -Rule sol88 1988 only - Oct 2 11:49:20s 0:10:40 - -Rule sol88 1988 only - Oct 3 11:49:00s 0:11:00 - -Rule sol88 1988 only - Oct 4 11:48:40s 0:11:20 - -Rule sol88 1988 only - Oct 5 11:48:25s 0:11:35 - -Rule sol88 1988 only - Oct 6 11:48:05s 0:11:55 - -Rule sol88 1988 only - Oct 7 11:47:50s 0:12:10 - -Rule sol88 1988 only - Oct 8 11:47:30s 0:12:30 - -Rule sol88 1988 only - Oct 9 11:47:15s 0:12:45 - -Rule sol88 1988 only - Oct 10 11:47:00s 0:13:00 - -Rule sol88 1988 only - Oct 11 11:46:45s 0:13:15 - -Rule sol88 1988 only - Oct 12 11:46:30s 0:13:30 - -Rule sol88 1988 only - Oct 13 11:46:15s 0:13:45 - -Rule sol88 1988 only - Oct 14 11:46:00s 0:14:00 - -Rule sol88 1988 only - Oct 15 11:45:45s 0:14:15 - -Rule sol88 1988 only - Oct 16 11:45:35s 0:14:25 - -Rule sol88 1988 only - Oct 17 11:45:20s 0:14:40 - -Rule sol88 1988 only - Oct 18 11:45:10s 0:14:50 - -Rule sol88 1988 only - Oct 19 11:45:00s 0:15:00 - -Rule sol88 1988 only - Oct 20 11:44:45s 0:15:15 - -Rule sol88 1988 only - Oct 21 11:44:40s 0:15:20 - -Rule sol88 1988 only - Oct 22 11:44:30s 0:15:30 - -Rule sol88 1988 only - Oct 23 11:44:20s 0:15:40 - -Rule sol88 1988 only - Oct 24 11:44:10s 0:15:50 - -Rule sol88 1988 only - Oct 25 11:44:05s 0:15:55 - -Rule sol88 1988 only - Oct 26 11:44:00s 0:16:00 - -Rule sol88 1988 only - Oct 27 11:43:55s 0:16:05 - -Rule sol88 1988 only - Oct 28 11:43:50s 0:16:10 - -Rule sol88 1988 only - Oct 29 11:43:45s 0:16:15 - -Rule sol88 1988 only - Oct 30 11:43:40s 0:16:20 - -Rule sol88 1988 only - Oct 31 11:43:40s 0:16:20 - -Rule sol88 1988 only - Nov 1 11:43:35s 0:16:25 - -Rule sol88 1988 only - Nov 2 11:43:35s 0:16:25 - -Rule sol88 1988 only - Nov 3 11:43:35s 0:16:25 - -Rule sol88 1988 only - Nov 4 11:43:35s 0:16:25 - -Rule sol88 1988 only - Nov 5 11:43:40s 0:16:20 - -Rule sol88 1988 only - Nov 6 11:43:40s 0:16:20 - -Rule sol88 1988 only - Nov 7 11:43:45s 0:16:15 - -Rule sol88 1988 only - Nov 8 11:43:45s 0:16:15 - -Rule sol88 1988 only - Nov 9 11:43:50s 0:16:10 - -Rule sol88 1988 only - Nov 10 11:44:00s 0:16:00 - -Rule sol88 1988 only - Nov 11 11:44:05s 0:15:55 - -Rule sol88 1988 only - Nov 12 11:44:10s 0:15:50 - -Rule sol88 1988 only - Nov 13 11:44:20s 0:15:40 - -Rule sol88 1988 only - Nov 14 11:44:30s 0:15:30 - -Rule sol88 1988 only - Nov 15 11:44:40s 0:15:20 - -Rule sol88 1988 only - Nov 16 11:44:50s 0:15:10 - -Rule sol88 1988 only - Nov 17 11:45:00s 0:15:00 - -Rule sol88 1988 only - Nov 18 11:45:15s 0:14:45 - -Rule sol88 1988 only - Nov 19 11:45:25s 0:14:35 - -Rule sol88 1988 only - Nov 20 11:45:40s 0:14:20 - -Rule sol88 1988 only - Nov 21 11:45:55s 0:14:05 - -Rule sol88 1988 only - Nov 22 11:46:10s 0:13:50 - -Rule sol88 1988 only - Nov 23 11:46:30s 0:13:30 - -Rule sol88 1988 only - Nov 24 11:46:45s 0:13:15 - -Rule sol88 1988 only - Nov 25 11:47:05s 0:12:55 - -Rule sol88 1988 only - Nov 26 11:47:20s 0:12:40 - -Rule sol88 1988 only - Nov 27 11:47:40s 0:12:20 - -Rule sol88 1988 only - Nov 28 11:48:00s 0:12:00 - -Rule sol88 1988 only - Nov 29 11:48:25s 0:11:35 - -Rule sol88 1988 only - Nov 30 11:48:45s 0:11:15 - -Rule sol88 1988 only - Dec 1 11:49:05s 0:10:55 - -Rule sol88 1988 only - Dec 2 11:49:30s 0:10:30 - -Rule sol88 1988 only - Dec 3 11:49:55s 0:10:05 - -Rule sol88 1988 only - Dec 4 11:50:15s 0:09:45 - -Rule sol88 1988 only - Dec 5 11:50:40s 0:09:20 - -Rule sol88 1988 only - Dec 6 11:51:05s 0:08:55 - -Rule sol88 1988 only - Dec 7 11:51:35s 0:08:25 - -Rule sol88 1988 only - Dec 8 11:52:00s 0:08:00 - -Rule sol88 1988 only - Dec 9 11:52:25s 0:07:35 - -Rule sol88 1988 only - Dec 10 11:52:55s 0:07:05 - -Rule sol88 1988 only - Dec 11 11:53:20s 0:06:40 - -Rule sol88 1988 only - Dec 12 11:53:50s 0:06:10 - -Rule sol88 1988 only - Dec 13 11:54:15s 0:05:45 - -Rule sol88 1988 only - Dec 14 11:54:45s 0:05:15 - -Rule sol88 1988 only - Dec 15 11:55:15s 0:04:45 - -Rule sol88 1988 only - Dec 16 11:55:45s 0:04:15 - -Rule sol88 1988 only - Dec 17 11:56:15s 0:03:45 - -Rule sol88 1988 only - Dec 18 11:56:40s 0:03:20 - -Rule sol88 1988 only - Dec 19 11:57:10s 0:02:50 - -Rule sol88 1988 only - Dec 20 11:57:40s 0:02:20 - -Rule sol88 1988 only - Dec 21 11:58:10s 0:01:50 - -Rule sol88 1988 only - Dec 22 11:58:40s 0:01:20 - -Rule sol88 1988 only - Dec 23 11:59:10s 0:00:50 - -Rule sol88 1988 only - Dec 24 11:59:40s 0:00:20 - -Rule sol88 1988 only - Dec 25 12:00:10s -0:00:10 - -Rule sol88 1988 only - Dec 26 12:00:40s -0:00:40 - -Rule sol88 1988 only - Dec 27 12:01:10s -0:01:10 - -Rule sol88 1988 only - Dec 28 12:01:40s -0:01:40 - -Rule sol88 1988 only - Dec 29 12:02:10s -0:02:10 - -Rule sol88 1988 only - Dec 30 12:02:35s -0:02:35 - -Rule sol88 1988 only - Dec 31 12:03:05s -0:03:05 - - -# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs -# Before and after 1988, we'll operate on local mean solar time. - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone Asia/Riyadh88 3:07:04 - zzz 1988 - 3:07:04 sol88 zzz 1989 - 3:07:04 - zzz -# For backward compatibility... -Link Asia/Riyadh88 Mideast/Riyadh88 diff --git a/src/java.base/share/data/tzdata/solar89 b/src/java.base/share/data/tzdata/solar89 deleted file mode 100644 index 3aa88cf0893..00000000000 --- a/src/java.base/share/data/tzdata/solar89 +++ /dev/null @@ -1,418 +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. 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. -# -# <pre> -# This file is in the public domain, so clarified as of -# 2009-05-17 by Arthur David Olson. - -# Apparent noon times below are for Riyadh; they're a bit off for other places. -# Times were computed using a formula provided by the U. S. Naval Observatory: -# eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l) -# -12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l) -# + 19.3 * cos(3 * l); -# where l is the "mean longitude of the Sun" given by -# l = 279.642 degrees + 0.985647 * d -# and d is the interval in days from January 0, 0 hours Universal Time -# (equaling the day of the year plus the fraction of a day from zero hours). -# The accuracy of the formula is plus or minus three seconds. -# -# Rounding to the nearest five seconds results in fewer than -# 256 different "time types"--a limit that's faced because time types are -# stored on disk as unsigned chars. - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule sol89 1989 only - Jan 1 12:03:35s -0:03:35 - -Rule sol89 1989 only - Jan 2 12:04:05s -0:04:05 - -Rule sol89 1989 only - Jan 3 12:04:30s -0:04:30 - -Rule sol89 1989 only - Jan 4 12:05:00s -0:05:00 - -Rule sol89 1989 only - Jan 5 12:05:25s -0:05:25 - -Rule sol89 1989 only - Jan 6 12:05:50s -0:05:50 - -Rule sol89 1989 only - Jan 7 12:06:15s -0:06:15 - -Rule sol89 1989 only - Jan 8 12:06:45s -0:06:45 - -Rule sol89 1989 only - Jan 9 12:07:10s -0:07:10 - -Rule sol89 1989 only - Jan 10 12:07:35s -0:07:35 - -Rule sol89 1989 only - Jan 11 12:07:55s -0:07:55 - -Rule sol89 1989 only - Jan 12 12:08:20s -0:08:20 - -Rule sol89 1989 only - Jan 13 12:08:45s -0:08:45 - -Rule sol89 1989 only - Jan 14 12:09:05s -0:09:05 - -Rule sol89 1989 only - Jan 15 12:09:25s -0:09:25 - -Rule sol89 1989 only - Jan 16 12:09:45s -0:09:45 - -Rule sol89 1989 only - Jan 17 12:10:05s -0:10:05 - -Rule sol89 1989 only - Jan 18 12:10:25s -0:10:25 - -Rule sol89 1989 only - Jan 19 12:10:45s -0:10:45 - -Rule sol89 1989 only - Jan 20 12:11:05s -0:11:05 - -Rule sol89 1989 only - Jan 21 12:11:20s -0:11:20 - -Rule sol89 1989 only - Jan 22 12:11:35s -0:11:35 - -Rule sol89 1989 only - Jan 23 12:11:55s -0:11:55 - -Rule sol89 1989 only - Jan 24 12:12:10s -0:12:10 - -Rule sol89 1989 only - Jan 25 12:12:20s -0:12:20 - -Rule sol89 1989 only - Jan 26 12:12:35s -0:12:35 - -Rule sol89 1989 only - Jan 27 12:12:50s -0:12:50 - -Rule sol89 1989 only - Jan 28 12:13:00s -0:13:00 - -Rule sol89 1989 only - Jan 29 12:13:10s -0:13:10 - -Rule sol89 1989 only - Jan 30 12:13:20s -0:13:20 - -Rule sol89 1989 only - Jan 31 12:13:30s -0:13:30 - -Rule sol89 1989 only - Feb 1 12:13:40s -0:13:40 - -Rule sol89 1989 only - Feb 2 12:13:45s -0:13:45 - -Rule sol89 1989 only - Feb 3 12:13:55s -0:13:55 - -Rule sol89 1989 only - Feb 4 12:14:00s -0:14:00 - -Rule sol89 1989 only - Feb 5 12:14:05s -0:14:05 - -Rule sol89 1989 only - Feb 6 12:14:10s -0:14:10 - -Rule sol89 1989 only - Feb 7 12:14:10s -0:14:10 - -Rule sol89 1989 only - Feb 8 12:14:15s -0:14:15 - -Rule sol89 1989 only - Feb 9 12:14:15s -0:14:15 - -Rule sol89 1989 only - Feb 10 12:14:20s -0:14:20 - -Rule sol89 1989 only - Feb 11 12:14:20s -0:14:20 - -Rule sol89 1989 only - Feb 12 12:14:20s -0:14:20 - -Rule sol89 1989 only - Feb 13 12:14:15s -0:14:15 - -Rule sol89 1989 only - Feb 14 12:14:15s -0:14:15 - -Rule sol89 1989 only - Feb 15 12:14:10s -0:14:10 - -Rule sol89 1989 only - Feb 16 12:14:10s -0:14:10 - -Rule sol89 1989 only - Feb 17 12:14:05s -0:14:05 - -Rule sol89 1989 only - Feb 18 12:14:00s -0:14:00 - -Rule sol89 1989 only - Feb 19 12:13:55s -0:13:55 - -Rule sol89 1989 only - Feb 20 12:13:50s -0:13:50 - -Rule sol89 1989 only - Feb 21 12:13:40s -0:13:40 - -Rule sol89 1989 only - Feb 22 12:13:35s -0:13:35 - -Rule sol89 1989 only - Feb 23 12:13:25s -0:13:25 - -Rule sol89 1989 only - Feb 24 12:13:15s -0:13:15 - -Rule sol89 1989 only - Feb 25 12:13:05s -0:13:05 - -Rule sol89 1989 only - Feb 26 12:12:55s -0:12:55 - -Rule sol89 1989 only - Feb 27 12:12:45s -0:12:45 - -Rule sol89 1989 only - Feb 28 12:12:35s -0:12:35 - -Rule sol89 1989 only - Mar 1 12:12:25s -0:12:25 - -Rule sol89 1989 only - Mar 2 12:12:10s -0:12:10 - -Rule sol89 1989 only - Mar 3 12:12:00s -0:12:00 - -Rule sol89 1989 only - Mar 4 12:11:45s -0:11:45 - -Rule sol89 1989 only - Mar 5 12:11:35s -0:11:35 - -Rule sol89 1989 only - Mar 6 12:11:20s -0:11:20 - -Rule sol89 1989 only - Mar 7 12:11:05s -0:11:05 - -Rule sol89 1989 only - Mar 8 12:10:50s -0:10:50 - -Rule sol89 1989 only - Mar 9 12:10:35s -0:10:35 - -Rule sol89 1989 only - Mar 10 12:10:20s -0:10:20 - -Rule sol89 1989 only - Mar 11 12:10:05s -0:10:05 - -Rule sol89 1989 only - Mar 12 12:09:50s -0:09:50 - -Rule sol89 1989 only - Mar 13 12:09:30s -0:09:30 - -Rule sol89 1989 only - Mar 14 12:09:15s -0:09:15 - -Rule sol89 1989 only - Mar 15 12:09:00s -0:09:00 - -Rule sol89 1989 only - Mar 16 12:08:40s -0:08:40 - -Rule sol89 1989 only - Mar 17 12:08:25s -0:08:25 - -Rule sol89 1989 only - Mar 18 12:08:05s -0:08:05 - -Rule sol89 1989 only - Mar 19 12:07:50s -0:07:50 - -Rule sol89 1989 only - Mar 20 12:07:30s -0:07:30 - -Rule sol89 1989 only - Mar 21 12:07:15s -0:07:15 - -Rule sol89 1989 only - Mar 22 12:06:55s -0:06:55 - -Rule sol89 1989 only - Mar 23 12:06:35s -0:06:35 - -Rule sol89 1989 only - Mar 24 12:06:20s -0:06:20 - -Rule sol89 1989 only - Mar 25 12:06:00s -0:06:00 - -Rule sol89 1989 only - Mar 26 12:05:40s -0:05:40 - -Rule sol89 1989 only - Mar 27 12:05:25s -0:05:25 - -Rule sol89 1989 only - Mar 28 12:05:05s -0:05:05 - -Rule sol89 1989 only - Mar 29 12:04:50s -0:04:50 - -Rule sol89 1989 only - Mar 30 12:04:30s -0:04:30 - -Rule sol89 1989 only - Mar 31 12:04:10s -0:04:10 - -Rule sol89 1989 only - Apr 1 12:03:55s -0:03:55 - -Rule sol89 1989 only - Apr 2 12:03:35s -0:03:35 - -Rule sol89 1989 only - Apr 3 12:03:20s -0:03:20 - -Rule sol89 1989 only - Apr 4 12:03:00s -0:03:00 - -Rule sol89 1989 only - Apr 5 12:02:45s -0:02:45 - -Rule sol89 1989 only - Apr 6 12:02:25s -0:02:25 - -Rule sol89 1989 only - Apr 7 12:02:10s -0:02:10 - -Rule sol89 1989 only - Apr 8 12:01:50s -0:01:50 - -Rule sol89 1989 only - Apr 9 12:01:35s -0:01:35 - -Rule sol89 1989 only - Apr 10 12:01:20s -0:01:20 - -Rule sol89 1989 only - Apr 11 12:01:05s -0:01:05 - -Rule sol89 1989 only - Apr 12 12:00:50s -0:00:50 - -Rule sol89 1989 only - Apr 13 12:00:35s -0:00:35 - -Rule sol89 1989 only - Apr 14 12:00:20s -0:00:20 - -Rule sol89 1989 only - Apr 15 12:00:05s -0:00:05 - -Rule sol89 1989 only - Apr 16 11:59:50s 0:00:10 - -Rule sol89 1989 only - Apr 17 11:59:35s 0:00:25 - -Rule sol89 1989 only - Apr 18 11:59:20s 0:00:40 - -Rule sol89 1989 only - Apr 19 11:59:10s 0:00:50 - -Rule sol89 1989 only - Apr 20 11:58:55s 0:01:05 - -Rule sol89 1989 only - Apr 21 11:58:45s 0:01:15 - -Rule sol89 1989 only - Apr 22 11:58:30s 0:01:30 - -Rule sol89 1989 only - Apr 23 11:58:20s 0:01:40 - -Rule sol89 1989 only - Apr 24 11:58:10s 0:01:50 - -Rule sol89 1989 only - Apr 25 11:58:00s 0:02:00 - -Rule sol89 1989 only - Apr 26 11:57:50s 0:02:10 - -Rule sol89 1989 only - Apr 27 11:57:40s 0:02:20 - -Rule sol89 1989 only - Apr 28 11:57:30s 0:02:30 - -Rule sol89 1989 only - Apr 29 11:57:20s 0:02:40 - -Rule sol89 1989 only - Apr 30 11:57:15s 0:02:45 - -Rule sol89 1989 only - May 1 11:57:05s 0:02:55 - -Rule sol89 1989 only - May 2 11:57:00s 0:03:00 - -Rule sol89 1989 only - May 3 11:56:50s 0:03:10 - -Rule sol89 1989 only - May 4 11:56:45s 0:03:15 - -Rule sol89 1989 only - May 5 11:56:40s 0:03:20 - -Rule sol89 1989 only - May 6 11:56:35s 0:03:25 - -Rule sol89 1989 only - May 7 11:56:30s 0:03:30 - -Rule sol89 1989 only - May 8 11:56:30s 0:03:30 - -Rule sol89 1989 only - May 9 11:56:25s 0:03:35 - -Rule sol89 1989 only - May 10 11:56:25s 0:03:35 - -Rule sol89 1989 only - May 11 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 12 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 13 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 14 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 15 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 16 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 17 11:56:20s 0:03:40 - -Rule sol89 1989 only - May 18 11:56:25s 0:03:35 - -Rule sol89 1989 only - May 19 11:56:25s 0:03:35 - -Rule sol89 1989 only - May 20 11:56:30s 0:03:30 - -Rule sol89 1989 only - May 21 11:56:35s 0:03:25 - -Rule sol89 1989 only - May 22 11:56:35s 0:03:25 - -Rule sol89 1989 only - May 23 11:56:40s 0:03:20 - -Rule sol89 1989 only - May 24 11:56:45s 0:03:15 - -Rule sol89 1989 only - May 25 11:56:55s 0:03:05 - -Rule sol89 1989 only - May 26 11:57:00s 0:03:00 - -Rule sol89 1989 only - May 27 11:57:05s 0:02:55 - -Rule sol89 1989 only - May 28 11:57:15s 0:02:45 - -Rule sol89 1989 only - May 29 11:57:20s 0:02:40 - -Rule sol89 1989 only - May 30 11:57:30s 0:02:30 - -Rule sol89 1989 only - May 31 11:57:35s 0:02:25 - -Rule sol89 1989 only - Jun 1 11:57:45s 0:02:15 - -Rule sol89 1989 only - Jun 2 11:57:55s 0:02:05 - -Rule sol89 1989 only - Jun 3 11:58:05s 0:01:55 - -Rule sol89 1989 only - Jun 4 11:58:15s 0:01:45 - -Rule sol89 1989 only - Jun 5 11:58:25s 0:01:35 - -Rule sol89 1989 only - Jun 6 11:58:35s 0:01:25 - -Rule sol89 1989 only - Jun 7 11:58:45s 0:01:15 - -Rule sol89 1989 only - Jun 8 11:59:00s 0:01:00 - -Rule sol89 1989 only - Jun 9 11:59:10s 0:00:50 - -Rule sol89 1989 only - Jun 10 11:59:20s 0:00:40 - -Rule sol89 1989 only - Jun 11 11:59:35s 0:00:25 - -Rule sol89 1989 only - Jun 12 11:59:45s 0:00:15 - -Rule sol89 1989 only - Jun 13 12:00:00s 0:00:00 - -Rule sol89 1989 only - Jun 14 12:00:10s -0:00:10 - -Rule sol89 1989 only - Jun 15 12:00:25s -0:00:25 - -Rule sol89 1989 only - Jun 16 12:00:35s -0:00:35 - -Rule sol89 1989 only - Jun 17 12:00:50s -0:00:50 - -Rule sol89 1989 only - Jun 18 12:01:05s -0:01:05 - -Rule sol89 1989 only - Jun 19 12:01:15s -0:01:15 - -Rule sol89 1989 only - Jun 20 12:01:30s -0:01:30 - -Rule sol89 1989 only - Jun 21 12:01:40s -0:01:40 - -Rule sol89 1989 only - Jun 22 12:01:55s -0:01:55 - -Rule sol89 1989 only - Jun 23 12:02:10s -0:02:10 - -Rule sol89 1989 only - Jun 24 12:02:20s -0:02:20 - -Rule sol89 1989 only - Jun 25 12:02:35s -0:02:35 - -Rule sol89 1989 only - Jun 26 12:02:45s -0:02:45 - -Rule sol89 1989 only - Jun 27 12:03:00s -0:03:00 - -Rule sol89 1989 only - Jun 28 12:03:10s -0:03:10 - -Rule sol89 1989 only - Jun 29 12:03:25s -0:03:25 - -Rule sol89 1989 only - Jun 30 12:03:35s -0:03:35 - -Rule sol89 1989 only - Jul 1 12:03:45s -0:03:45 - -Rule sol89 1989 only - Jul 2 12:04:00s -0:04:00 - -Rule sol89 1989 only - Jul 3 12:04:10s -0:04:10 - -Rule sol89 1989 only - Jul 4 12:04:20s -0:04:20 - -Rule sol89 1989 only - Jul 5 12:04:30s -0:04:30 - -Rule sol89 1989 only - Jul 6 12:04:40s -0:04:40 - -Rule sol89 1989 only - Jul 7 12:04:50s -0:04:50 - -Rule sol89 1989 only - Jul 8 12:05:00s -0:05:00 - -Rule sol89 1989 only - Jul 9 12:05:10s -0:05:10 - -Rule sol89 1989 only - Jul 10 12:05:20s -0:05:20 - -Rule sol89 1989 only - Jul 11 12:05:25s -0:05:25 - -Rule sol89 1989 only - Jul 12 12:05:35s -0:05:35 - -Rule sol89 1989 only - Jul 13 12:05:40s -0:05:40 - -Rule sol89 1989 only - Jul 14 12:05:50s -0:05:50 - -Rule sol89 1989 only - Jul 15 12:05:55s -0:05:55 - -Rule sol89 1989 only - Jul 16 12:06:00s -0:06:00 - -Rule sol89 1989 only - Jul 17 12:06:05s -0:06:05 - -Rule sol89 1989 only - Jul 18 12:06:10s -0:06:10 - -Rule sol89 1989 only - Jul 19 12:06:15s -0:06:15 - -Rule sol89 1989 only - Jul 20 12:06:20s -0:06:20 - -Rule sol89 1989 only - Jul 21 12:06:20s -0:06:20 - -Rule sol89 1989 only - Jul 22 12:06:25s -0:06:25 - -Rule sol89 1989 only - Jul 23 12:06:25s -0:06:25 - -Rule sol89 1989 only - Jul 24 12:06:30s -0:06:30 - -Rule sol89 1989 only - Jul 25 12:06:30s -0:06:30 - -Rule sol89 1989 only - Jul 26 12:06:30s -0:06:30 - -Rule sol89 1989 only - Jul 27 12:06:30s -0:06:30 - -Rule sol89 1989 only - Jul 28 12:06:30s -0:06:30 - -Rule sol89 1989 only - Jul 29 12:06:25s -0:06:25 - -Rule sol89 1989 only - Jul 30 12:06:25s -0:06:25 - -Rule sol89 1989 only - Jul 31 12:06:20s -0:06:20 - -Rule sol89 1989 only - Aug 1 12:06:20s -0:06:20 - -Rule sol89 1989 only - Aug 2 12:06:15s -0:06:15 - -Rule sol89 1989 only - Aug 3 12:06:10s -0:06:10 - -Rule sol89 1989 only - Aug 4 12:06:05s -0:06:05 - -Rule sol89 1989 only - Aug 5 12:06:00s -0:06:00 - -Rule sol89 1989 only - Aug 6 12:05:50s -0:05:50 - -Rule sol89 1989 only - Aug 7 12:05:45s -0:05:45 - -Rule sol89 1989 only - Aug 8 12:05:35s -0:05:35 - -Rule sol89 1989 only - Aug 9 12:05:30s -0:05:30 - -Rule sol89 1989 only - Aug 10 12:05:20s -0:05:20 - -Rule sol89 1989 only - Aug 11 12:05:10s -0:05:10 - -Rule sol89 1989 only - Aug 12 12:05:00s -0:05:00 - -Rule sol89 1989 only - Aug 13 12:04:50s -0:04:50 - -Rule sol89 1989 only - Aug 14 12:04:40s -0:04:40 - -Rule sol89 1989 only - Aug 15 12:04:30s -0:04:30 - -Rule sol89 1989 only - Aug 16 12:04:15s -0:04:15 - -Rule sol89 1989 only - Aug 17 12:04:05s -0:04:05 - -Rule sol89 1989 only - Aug 18 12:03:50s -0:03:50 - -Rule sol89 1989 only - Aug 19 12:03:35s -0:03:35 - -Rule sol89 1989 only - Aug 20 12:03:25s -0:03:25 - -Rule sol89 1989 only - Aug 21 12:03:10s -0:03:10 - -Rule sol89 1989 only - Aug 22 12:02:55s -0:02:55 - -Rule sol89 1989 only - Aug 23 12:02:40s -0:02:40 - -Rule sol89 1989 only - Aug 24 12:02:20s -0:02:20 - -Rule sol89 1989 only - Aug 25 12:02:05s -0:02:05 - -Rule sol89 1989 only - Aug 26 12:01:50s -0:01:50 - -Rule sol89 1989 only - Aug 27 12:01:30s -0:01:30 - -Rule sol89 1989 only - Aug 28 12:01:15s -0:01:15 - -Rule sol89 1989 only - Aug 29 12:00:55s -0:00:55 - -Rule sol89 1989 only - Aug 30 12:00:40s -0:00:40 - -Rule sol89 1989 only - Aug 31 12:00:20s -0:00:20 - -Rule sol89 1989 only - Sep 1 12:00:00s 0:00:00 - -Rule sol89 1989 only - Sep 2 11:59:45s 0:00:15 - -Rule sol89 1989 only - Sep 3 11:59:25s 0:00:35 - -Rule sol89 1989 only - Sep 4 11:59:05s 0:00:55 - -Rule sol89 1989 only - Sep 5 11:58:45s 0:01:15 - -Rule sol89 1989 only - Sep 6 11:58:25s 0:01:35 - -Rule sol89 1989 only - Sep 7 11:58:05s 0:01:55 - -Rule sol89 1989 only - Sep 8 11:57:45s 0:02:15 - -Rule sol89 1989 only - Sep 9 11:57:20s 0:02:40 - -Rule sol89 1989 only - Sep 10 11:57:00s 0:03:00 - -Rule sol89 1989 only - Sep 11 11:56:40s 0:03:20 - -Rule sol89 1989 only - Sep 12 11:56:20s 0:03:40 - -Rule sol89 1989 only - Sep 13 11:56:00s 0:04:00 - -Rule sol89 1989 only - Sep 14 11:55:35s 0:04:25 - -Rule sol89 1989 only - Sep 15 11:55:15s 0:04:45 - -Rule sol89 1989 only - Sep 16 11:54:55s 0:05:05 - -Rule sol89 1989 only - Sep 17 11:54:35s 0:05:25 - -Rule sol89 1989 only - Sep 18 11:54:10s 0:05:50 - -Rule sol89 1989 only - Sep 19 11:53:50s 0:06:10 - -Rule sol89 1989 only - Sep 20 11:53:30s 0:06:30 - -Rule sol89 1989 only - Sep 21 11:53:10s 0:06:50 - -Rule sol89 1989 only - Sep 22 11:52:45s 0:07:15 - -Rule sol89 1989 only - Sep 23 11:52:25s 0:07:35 - -Rule sol89 1989 only - Sep 24 11:52:05s 0:07:55 - -Rule sol89 1989 only - Sep 25 11:51:45s 0:08:15 - -Rule sol89 1989 only - Sep 26 11:51:25s 0:08:35 - -Rule sol89 1989 only - Sep 27 11:51:05s 0:08:55 - -Rule sol89 1989 only - Sep 28 11:50:40s 0:09:20 - -Rule sol89 1989 only - Sep 29 11:50:20s 0:09:40 - -Rule sol89 1989 only - Sep 30 11:50:00s 0:10:00 - -Rule sol89 1989 only - Oct 1 11:49:45s 0:10:15 - -Rule sol89 1989 only - Oct 2 11:49:25s 0:10:35 - -Rule sol89 1989 only - Oct 3 11:49:05s 0:10:55 - -Rule sol89 1989 only - Oct 4 11:48:45s 0:11:15 - -Rule sol89 1989 only - Oct 5 11:48:30s 0:11:30 - -Rule sol89 1989 only - Oct 6 11:48:10s 0:11:50 - -Rule sol89 1989 only - Oct 7 11:47:50s 0:12:10 - -Rule sol89 1989 only - Oct 8 11:47:35s 0:12:25 - -Rule sol89 1989 only - Oct 9 11:47:20s 0:12:40 - -Rule sol89 1989 only - Oct 10 11:47:00s 0:13:00 - -Rule sol89 1989 only - Oct 11 11:46:45s 0:13:15 - -Rule sol89 1989 only - Oct 12 11:46:30s 0:13:30 - -Rule sol89 1989 only - Oct 13 11:46:15s 0:13:45 - -Rule sol89 1989 only - Oct 14 11:46:00s 0:14:00 - -Rule sol89 1989 only - Oct 15 11:45:50s 0:14:10 - -Rule sol89 1989 only - Oct 16 11:45:35s 0:14:25 - -Rule sol89 1989 only - Oct 17 11:45:20s 0:14:40 - -Rule sol89 1989 only - Oct 18 11:45:10s 0:14:50 - -Rule sol89 1989 only - Oct 19 11:45:00s 0:15:00 - -Rule sol89 1989 only - Oct 20 11:44:50s 0:15:10 - -Rule sol89 1989 only - Oct 21 11:44:40s 0:15:20 - -Rule sol89 1989 only - Oct 22 11:44:30s 0:15:30 - -Rule sol89 1989 only - Oct 23 11:44:20s 0:15:40 - -Rule sol89 1989 only - Oct 24 11:44:10s 0:15:50 - -Rule sol89 1989 only - Oct 25 11:44:05s 0:15:55 - -Rule sol89 1989 only - Oct 26 11:44:00s 0:16:00 - -Rule sol89 1989 only - Oct 27 11:43:50s 0:16:10 - -Rule sol89 1989 only - Oct 28 11:43:45s 0:16:15 - -Rule sol89 1989 only - Oct 29 11:43:40s 0:16:20 - -Rule sol89 1989 only - Oct 30 11:43:40s 0:16:20 - -Rule sol89 1989 only - Oct 31 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 1 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 2 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 3 11:43:30s 0:16:30 - -Rule sol89 1989 only - Nov 4 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 5 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 6 11:43:35s 0:16:25 - -Rule sol89 1989 only - Nov 7 11:43:40s 0:16:20 - -Rule sol89 1989 only - Nov 8 11:43:45s 0:16:15 - -Rule sol89 1989 only - Nov 9 11:43:50s 0:16:10 - -Rule sol89 1989 only - Nov 10 11:43:55s 0:16:05 - -Rule sol89 1989 only - Nov 11 11:44:00s 0:16:00 - -Rule sol89 1989 only - Nov 12 11:44:05s 0:15:55 - -Rule sol89 1989 only - Nov 13 11:44:15s 0:15:45 - -Rule sol89 1989 only - Nov 14 11:44:25s 0:15:35 - -Rule sol89 1989 only - Nov 15 11:44:35s 0:15:25 - -Rule sol89 1989 only - Nov 16 11:44:45s 0:15:15 - -Rule sol89 1989 only - Nov 17 11:44:55s 0:15:05 - -Rule sol89 1989 only - Nov 18 11:45:10s 0:14:50 - -Rule sol89 1989 only - Nov 19 11:45:20s 0:14:40 - -Rule sol89 1989 only - Nov 20 11:45:35s 0:14:25 - -Rule sol89 1989 only - Nov 21 11:45:50s 0:14:10 - -Rule sol89 1989 only - Nov 22 11:46:05s 0:13:55 - -Rule sol89 1989 only - Nov 23 11:46:25s 0:13:35 - -Rule sol89 1989 only - Nov 24 11:46:40s 0:13:20 - -Rule sol89 1989 only - Nov 25 11:47:00s 0:13:00 - -Rule sol89 1989 only - Nov 26 11:47:20s 0:12:40 - -Rule sol89 1989 only - Nov 27 11:47:35s 0:12:25 - -Rule sol89 1989 only - Nov 28 11:47:55s 0:12:05 - -Rule sol89 1989 only - Nov 29 11:48:20s 0:11:40 - -Rule sol89 1989 only - Nov 30 11:48:40s 0:11:20 - -Rule sol89 1989 only - Dec 1 11:49:00s 0:11:00 - -Rule sol89 1989 only - Dec 2 11:49:25s 0:10:35 - -Rule sol89 1989 only - Dec 3 11:49:50s 0:10:10 - -Rule sol89 1989 only - Dec 4 11:50:15s 0:09:45 - -Rule sol89 1989 only - Dec 5 11:50:35s 0:09:25 - -Rule sol89 1989 only - Dec 6 11:51:00s 0:09:00 - -Rule sol89 1989 only - Dec 7 11:51:30s 0:08:30 - -Rule sol89 1989 only - Dec 8 11:51:55s 0:08:05 - -Rule sol89 1989 only - Dec 9 11:52:20s 0:07:40 - -Rule sol89 1989 only - Dec 10 11:52:50s 0:07:10 - -Rule sol89 1989 only - Dec 11 11:53:15s 0:06:45 - -Rule sol89 1989 only - Dec 12 11:53:45s 0:06:15 - -Rule sol89 1989 only - Dec 13 11:54:10s 0:05:50 - -Rule sol89 1989 only - Dec 14 11:54:40s 0:05:20 - -Rule sol89 1989 only - Dec 15 11:55:10s 0:04:50 - -Rule sol89 1989 only - Dec 16 11:55:40s 0:04:20 - -Rule sol89 1989 only - Dec 17 11:56:05s 0:03:55 - -Rule sol89 1989 only - Dec 18 11:56:35s 0:03:25 - -Rule sol89 1989 only - Dec 19 11:57:05s 0:02:55 - -Rule sol89 1989 only - Dec 20 11:57:35s 0:02:25 - -Rule sol89 1989 only - Dec 21 11:58:05s 0:01:55 - -Rule sol89 1989 only - Dec 22 11:58:35s 0:01:25 - -Rule sol89 1989 only - Dec 23 11:59:05s 0:00:55 - -Rule sol89 1989 only - Dec 24 11:59:35s 0:00:25 - -Rule sol89 1989 only - Dec 25 12:00:05s -0:00:05 - -Rule sol89 1989 only - Dec 26 12:00:35s -0:00:35 - -Rule sol89 1989 only - Dec 27 12:01:05s -0:01:05 - -Rule sol89 1989 only - Dec 28 12:01:35s -0:01:35 - -Rule sol89 1989 only - Dec 29 12:02:00s -0:02:00 - -Rule sol89 1989 only - Dec 30 12:02:30s -0:02:30 - -Rule sol89 1989 only - Dec 31 12:03:00s -0:03:00 - - -# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs -# Before and after 1989, we'll operate on local mean solar time. - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone Asia/Riyadh89 3:07:04 - zzz 1989 - 3:07:04 sol89 zzz 1990 - 3:07:04 - zzz -# For backward compatibility... -Link Asia/Riyadh89 Mideast/Riyadh89 diff --git a/src/java.base/share/data/tzdata/zone.tab b/src/java.base/share/data/tzdata/zone.tab deleted file mode 100644 index b90ab4e4b25..00000000000 --- a/src/java.base/share/data/tzdata/zone.tab +++ /dev/null @@ -1,470 +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. 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. -# -# tzdb timezone descriptions (deprecated version) -# -# This file is in the public domain, so clarified as of -# 2009-05-17 by Arthur David Olson. -# -# From Paul Eggert (2021-09-20): -# This file is intended as a backward-compatibility aid for older programs. -# New programs should use zone1970.tab. This file is like zone1970.tab (see -# zone1970.tab's comments), but with the following additional restrictions: -# -# 1. This file contains only ASCII characters. -# 2. The first data column contains exactly one country code. -# -# Because of (2), each row stands for an area that is the intersection -# of a region identified by a country code and of a timezone where civil -# clocks have agreed since 1970; this is a narrower definition than -# that of zone1970.tab. -# -# Unlike zone1970.tab, a row's third column can be a Link from -# 'backward' instead of a Zone. -# -# This table is intended as an aid for users, to help them select timezones -# appropriate for their practical needs. It is not intended to take or -# endorse any position on legal or territorial claims. -# -#country- -#code coordinates TZ comments -AD +4230+00131 Europe/Andorra -AE +2518+05518 Asia/Dubai -AF +3431+06912 Asia/Kabul -AG +1703-06148 America/Antigua -AI +1812-06304 America/Anguilla -AL +4120+01950 Europe/Tirane -AM +4011+04430 Asia/Yerevan -AO -0848+01314 Africa/Luanda -AQ -7750+16636 Antarctica/McMurdo New Zealand time - McMurdo, South Pole -AQ -6617+11031 Antarctica/Casey Casey -AQ -6835+07758 Antarctica/Davis Davis -AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville -AQ -6736+06253 Antarctica/Mawson Mawson -AQ -6448-06406 Antarctica/Palmer Palmer -AQ -6734-06808 Antarctica/Rothera Rothera -AQ -690022+0393524 Antarctica/Syowa Syowa -AQ -720041+0023206 Antarctica/Troll Troll -AQ -7824+10654 Antarctica/Vostok Vostok -AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) -AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF) -AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN) -AR -2411-06518 America/Argentina/Jujuy Jujuy (JY) -AR -2649-06513 America/Argentina/Tucuman Tucuman (TM) -AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH) -AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR) -AR -3132-06831 America/Argentina/San_Juan San Juan (SJ) -AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ) -AR -3319-06621 America/Argentina/San_Luis San Luis (SL) -AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC) -AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF) -AS -1416-17042 Pacific/Pago_Pago -AT +4813+01620 Europe/Vienna -AU -3133+15905 Australia/Lord_Howe Lord Howe Island -AU -5430+15857 Antarctica/Macquarie Macquarie Island -AU -4253+14719 Australia/Hobart Tasmania -AU -3749+14458 Australia/Melbourne Victoria -AU -3352+15113 Australia/Sydney New South Wales (most areas) -AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna) -AU -2728+15302 Australia/Brisbane Queensland (most areas) -AU -2016+14900 Australia/Lindeman Queensland (Whitsunday Islands) -AU -3455+13835 Australia/Adelaide South Australia -AU -1228+13050 Australia/Darwin Northern Territory -AU -3157+11551 Australia/Perth Western Australia (most areas) -AU -3143+12852 Australia/Eucla Western Australia (Eucla) -AW +1230-06958 America/Aruba -AX +6006+01957 Europe/Mariehamn -AZ +4023+04951 Asia/Baku -BA +4352+01825 Europe/Sarajevo -BB +1306-05937 America/Barbados -BD +2343+09025 Asia/Dhaka -BE +5050+00420 Europe/Brussels -BF +1222-00131 Africa/Ouagadougou -BG +4241+02319 Europe/Sofia -BH +2623+05035 Asia/Bahrain -BI -0323+02922 Africa/Bujumbura -BJ +0629+00237 Africa/Porto-Novo -BL +1753-06251 America/St_Barthelemy -BM +3217-06446 Atlantic/Bermuda -BN +0456+11455 Asia/Brunei -BO -1630-06809 America/La_Paz -BQ +120903-0681636 America/Kralendijk -BR -0351-03225 America/Noronha Atlantic islands -BR -0127-04829 America/Belem Para (east), Amapa -BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB) -BR -0803-03454 America/Recife Pernambuco -BR -0712-04812 America/Araguaina Tocantins -BR -0940-03543 America/Maceio Alagoas, Sergipe -BR -1259-03831 America/Bahia Bahia -BR -2332-04637 America/Sao_Paulo Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS) -BR -2027-05437 America/Campo_Grande Mato Grosso do Sul -BR -1535-05605 America/Cuiaba Mato Grosso -BR -0226-05452 America/Santarem Para (west) -BR -0846-06354 America/Porto_Velho Rondonia -BR +0249-06040 America/Boa_Vista Roraima -BR -0308-06001 America/Manaus Amazonas (east) -BR -0640-06952 America/Eirunepe Amazonas (west) -BR -0958-06748 America/Rio_Branco Acre -BS +2505-07721 America/Nassau -BT +2728+08939 Asia/Thimphu -BW -2439+02555 Africa/Gaborone -BY +5354+02734 Europe/Minsk -BZ +1730-08812 America/Belize -CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE) -CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE -CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) -CA +4606-06447 America/Moncton Atlantic - New Brunswick -CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) -CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) -CA +4339-07923 America/Toronto Eastern - ON & QC (most areas) -CA +6344-06828 America/Iqaluit Eastern - NU (most areas) -CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H) -CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba -CA +744144-0944945 America/Resolute Central - NU (Resolute) -CA +624900-0920459 America/Rankin_Inlet Central - NU (central) -CA +5024-10439 America/Regina CST - SK (most areas) -CA +5017-10750 America/Swift_Current CST - SK (midwest) -CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W) -CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) -CA +682059-1334300 America/Inuvik Mountain - NT (west) -CA +4906-11631 America/Creston MST - BC (Creston) -CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) -CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) -CA +6043-13503 America/Whitehorse MST - Yukon (east) -CA +6404-13925 America/Dawson MST - Yukon (west) -CA +4916-12307 America/Vancouver Pacific - BC (most areas) -CC -1210+09655 Indian/Cocos -CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west) -CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east) -CF +0422+01835 Africa/Bangui -CG -0416+01517 Africa/Brazzaville -CH +4723+00832 Europe/Zurich -CI +0519-00402 Africa/Abidjan -CK -2114-15946 Pacific/Rarotonga -CL -3327-07040 America/Santiago most of Chile -CL -5309-07055 America/Punta_Arenas Region of Magallanes -CL -2709-10926 Pacific/Easter Easter Island -CM +0403+00942 Africa/Douala -CN +3114+12128 Asia/Shanghai Beijing Time -CN +4348+08735 Asia/Urumqi Xinjiang Time -CO +0436-07405 America/Bogota -CR +0956-08405 America/Costa_Rica -CU +2308-08222 America/Havana -CV +1455-02331 Atlantic/Cape_Verde -CW +1211-06900 America/Curacao -CX -1025+10543 Indian/Christmas -CY +3510+03322 Asia/Nicosia most of Cyprus -CY +3507+03357 Asia/Famagusta Northern Cyprus -CZ +5005+01426 Europe/Prague -DE +5230+01322 Europe/Berlin most of Germany -DE +4742+00841 Europe/Busingen Busingen -DJ +1136+04309 Africa/Djibouti -DK +5540+01235 Europe/Copenhagen -DM +1518-06124 America/Dominica -DO +1828-06954 America/Santo_Domingo -DZ +3647+00303 Africa/Algiers -EC -0210-07950 America/Guayaquil Ecuador (mainland) -EC -0054-08936 Pacific/Galapagos Galapagos Islands -EE +5925+02445 Europe/Tallinn -EG +3003+03115 Africa/Cairo -EH +2709-01312 Africa/El_Aaiun -ER +1520+03853 Africa/Asmara -ES +4024-00341 Europe/Madrid Spain (mainland) -ES +3553-00519 Africa/Ceuta Ceuta, Melilla -ES +2806-01524 Atlantic/Canary Canary Islands -ET +0902+03842 Africa/Addis_Ababa -FI +6010+02458 Europe/Helsinki -FJ -1808+17825 Pacific/Fiji -FK -5142-05751 Atlantic/Stanley -FM +0725+15147 Pacific/Chuuk Chuuk/Truk, Yap -FM +0658+15813 Pacific/Pohnpei Pohnpei/Ponape -FM +0519+16259 Pacific/Kosrae Kosrae -FO +6201-00646 Atlantic/Faroe -FR +4852+00220 Europe/Paris -GA +0023+00927 Africa/Libreville -GB +513030-0000731 Europe/London -GD +1203-06145 America/Grenada -GE +4143+04449 Asia/Tbilisi -GF +0456-05220 America/Cayenne -GG +492717-0023210 Europe/Guernsey -GH +0533-00013 Africa/Accra -GI +3608-00521 Europe/Gibraltar -GL +6411-05144 America/Nuuk most of Greenland -GL +7646-01840 America/Danmarkshavn National Park (east coast) -GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit -GL +7634-06847 America/Thule Thule/Pituffik -GM +1328-01639 Africa/Banjul -GN +0931-01343 Africa/Conakry -GP +1614-06132 America/Guadeloupe -GQ +0345+00847 Africa/Malabo -GR +3758+02343 Europe/Athens -GS -5416-03632 Atlantic/South_Georgia -GT +1438-09031 America/Guatemala -GU +1328+14445 Pacific/Guam -GW +1151-01535 Africa/Bissau -GY +0648-05810 America/Guyana -HK +2217+11409 Asia/Hong_Kong -HN +1406-08713 America/Tegucigalpa -HR +4548+01558 Europe/Zagreb -HT +1832-07220 America/Port-au-Prince -HU +4730+01905 Europe/Budapest -ID -0610+10648 Asia/Jakarta Java, Sumatra -ID -0002+10920 Asia/Pontianak Borneo (west, central) -ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west) -ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas -IE +5320-00615 Europe/Dublin -IL +314650+0351326 Asia/Jerusalem -IM +5409-00428 Europe/Isle_of_Man -IN +2232+08822 Asia/Kolkata -IO -0720+07225 Indian/Chagos -IQ +3321+04425 Asia/Baghdad -IR +3540+05126 Asia/Tehran -IS +6409-02151 Atlantic/Reykjavik -IT +4154+01229 Europe/Rome -JE +491101-0020624 Europe/Jersey -JM +175805-0764736 America/Jamaica -JO +3157+03556 Asia/Amman -JP +353916+1394441 Asia/Tokyo -KE -0117+03649 Africa/Nairobi -KG +4254+07436 Asia/Bishkek -KH +1133+10455 Asia/Phnom_Penh -KI +0125+17300 Pacific/Tarawa Gilbert Islands -KI -0247-17143 Pacific/Kanton Phoenix Islands -KI +0152-15720 Pacific/Kiritimati Line Islands -KM -1141+04316 Indian/Comoro -KN +1718-06243 America/St_Kitts -KP +3901+12545 Asia/Pyongyang -KR +3733+12658 Asia/Seoul -KW +2920+04759 Asia/Kuwait -KY +1918-08123 America/Cayman -KZ +4315+07657 Asia/Almaty most of Kazakhstan -KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda -KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay -KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe -KZ +4431+05016 Asia/Aqtau Mangghystau/Mankistau -KZ +4707+05156 Asia/Atyrau Atyrau/Atirau/Gur'yev -KZ +5113+05121 Asia/Oral West Kazakhstan -LA +1758+10236 Asia/Vientiane -LB +3353+03530 Asia/Beirut -LC +1401-06100 America/St_Lucia -LI +4709+00931 Europe/Vaduz -LK +0656+07951 Asia/Colombo -LR +0618-01047 Africa/Monrovia -LS -2928+02730 Africa/Maseru -LT +5441+02519 Europe/Vilnius -LU +4936+00609 Europe/Luxembourg -LV +5657+02406 Europe/Riga -LY +3254+01311 Africa/Tripoli -MA +3339-00735 Africa/Casablanca -MC +4342+00723 Europe/Monaco -MD +4700+02850 Europe/Chisinau -ME +4226+01916 Europe/Podgorica -MF +1804-06305 America/Marigot -MG -1855+04731 Indian/Antananarivo -MH +0709+17112 Pacific/Majuro most of Marshall Islands -MH +0905+16720 Pacific/Kwajalein Kwajalein -MK +4159+02126 Europe/Skopje -ML +1239-00800 Africa/Bamako -MM +1647+09610 Asia/Yangon -MN +4755+10653 Asia/Ulaanbaatar most of Mongolia -MN +4801+09139 Asia/Hovd Bayan-Olgii, Hovd, Uvs -MO +221150+1133230 Asia/Macau -MP +1512+14545 Pacific/Saipan -MQ +1436-06105 America/Martinique -MR +1806-01557 Africa/Nouakchott -MS +1643-06213 America/Montserrat -MT +3554+01431 Europe/Malta -MU -2010+05730 Indian/Mauritius -MV +0410+07330 Indian/Maldives -MW -1547+03500 Africa/Blantyre -MX +1924-09909 America/Mexico_City Central Mexico -MX +2105-08646 America/Cancun Quintana Roo -MX +2058-08937 America/Merida Campeche, Yucatan -MX +2540-10019 America/Monterrey Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas) -MX +2550-09730 America/Matamoros Coahuila, Nuevo Leon, Tamaulipas (US border) -MX +2838-10605 America/Chihuahua Chihuahua (most areas) -MX +3144-10629 America/Ciudad_Juarez Chihuahua (US border - west) -MX +2934-10425 America/Ojinaga Chihuahua (US border - east) -MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinaloa -MX +2048-10515 America/Bahia_Banderas Bahia de Banderas -MX +2904-11058 America/Hermosillo Sonora -MX +3232-11701 America/Tijuana Baja California -MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula) -MY +0133+11020 Asia/Kuching Sabah, Sarawak -MZ -2558+03235 Africa/Maputo -NA -2234+01706 Africa/Windhoek -NC -2216+16627 Pacific/Noumea -NE +1331+00207 Africa/Niamey -NF -2903+16758 Pacific/Norfolk -NG +0627+00324 Africa/Lagos -NI +1209-08617 America/Managua -NL +5222+00454 Europe/Amsterdam -NO +5955+01045 Europe/Oslo -NP +2743+08519 Asia/Kathmandu -NR -0031+16655 Pacific/Nauru -NU -1901-16955 Pacific/Niue -NZ -3652+17446 Pacific/Auckland most of New Zealand -NZ -4357-17633 Pacific/Chatham Chatham Islands -OM +2336+05835 Asia/Muscat -PA +0858-07932 America/Panama -PE -1203-07703 America/Lima -PF -1732-14934 Pacific/Tahiti Society Islands -PF -0900-13930 Pacific/Marquesas Marquesas Islands -PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea -PG -0613+15534 Pacific/Bougainville Bougainville -PH +1435+12100 Asia/Manila -PK +2452+06703 Asia/Karachi -PL +5215+02100 Europe/Warsaw -PM +4703-05620 America/Miquelon -PN -2504-13005 Pacific/Pitcairn -PR +182806-0660622 America/Puerto_Rico -PS +3130+03428 Asia/Gaza Gaza Strip -PS +313200+0350542 Asia/Hebron West Bank -PT +3843-00908 Europe/Lisbon Portugal (mainland) -PT +3238-01654 Atlantic/Madeira Madeira Islands -PT +3744-02540 Atlantic/Azores Azores -PW +0720+13429 Pacific/Palau -PY -2516-05740 America/Asuncion -QA +2517+05132 Asia/Qatar -RE -2052+05528 Indian/Reunion -RO +4426+02606 Europe/Bucharest -RS +4450+02030 Europe/Belgrade -RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad -RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area -# The obsolescent zone.tab format cannot represent Europe/Simferopol well. -# Put it in RU section and list as UA. See "territorial claims" above. -# Programs should use zone1970.tab instead; see above. -UA +4457+03406 Europe/Simferopol Crimea -RU +5836+04939 Europe/Kirov MSK+00 - Kirov -RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd -RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan -RU +5134+04602 Europe/Saratov MSK+01 - Saratov -RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk -RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia -RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals -RU +5500+07324 Asia/Omsk MSK+03 - Omsk -RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk -RU +5322+08345 Asia/Barnaul MSK+04 - Altai -RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk -RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo -RU +5601+09250 Asia/Krasnoyarsk MSK+04 - Krasnoyarsk area -RU +5216+10420 Asia/Irkutsk MSK+05 - Irkutsk, Buryatia -RU +5203+11328 Asia/Chita MSK+06 - Zabaykalsky -RU +6200+12940 Asia/Yakutsk MSK+06 - Lena River -RU +623923+1353314 Asia/Khandyga MSK+06 - Tomponsky, Ust-Maysky -RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River -RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky -RU +5934+15048 Asia/Magadan MSK+08 - Magadan -RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island -RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is -RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka -RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea -RW -0157+03004 Africa/Kigali -SA +2438+04643 Asia/Riyadh -SB -0932+16012 Pacific/Guadalcanal -SC -0440+05528 Indian/Mahe -SD +1536+03232 Africa/Khartoum -SE +5920+01803 Europe/Stockholm -SG +0117+10351 Asia/Singapore -SH -1555-00542 Atlantic/St_Helena -SI +4603+01431 Europe/Ljubljana -SJ +7800+01600 Arctic/Longyearbyen -SK +4809+01707 Europe/Bratislava -SL +0830-01315 Africa/Freetown -SM +4355+01228 Europe/San_Marino -SN +1440-01726 Africa/Dakar -SO +0204+04522 Africa/Mogadishu -SR +0550-05510 America/Paramaribo -SS +0451+03137 Africa/Juba -ST +0020+00644 Africa/Sao_Tome -SV +1342-08912 America/El_Salvador -SX +180305-0630250 America/Lower_Princes -SY +3330+03618 Asia/Damascus -SZ -2618+03106 Africa/Mbabane -TC +2128-07108 America/Grand_Turk -TD +1207+01503 Africa/Ndjamena -TF -492110+0701303 Indian/Kerguelen -TG +0608+00113 Africa/Lome -TH +1345+10031 Asia/Bangkok -TJ +3835+06848 Asia/Dushanbe -TK -0922-17114 Pacific/Fakaofo -TL -0833+12535 Asia/Dili -TM +3757+05823 Asia/Ashgabat -TN +3648+01011 Africa/Tunis -TO -210800-1751200 Pacific/Tongatapu -TR +4101+02858 Europe/Istanbul -TT +1039-06131 America/Port_of_Spain -TV -0831+17913 Pacific/Funafuti -TW +2503+12130 Asia/Taipei -TZ -0648+03917 Africa/Dar_es_Salaam -UA +5026+03031 Europe/Kyiv most of Ukraine -UG +0019+03225 Africa/Kampala -UM +2813-17722 Pacific/Midway Midway Islands -UM +1917+16637 Pacific/Wake Wake Island -US +404251-0740023 America/New_York Eastern (most areas) -US +421953-0830245 America/Detroit Eastern - MI (most areas) -US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area) -US +364947-0845057 America/Kentucky/Monticello Eastern - KY (Wayne) -US +394606-0860929 America/Indiana/Indianapolis Eastern - IN (most areas) -US +384038-0873143 America/Indiana/Vincennes Eastern - IN (Da, Du, K, Mn) -US +410305-0863611 America/Indiana/Winamac Eastern - IN (Pulaski) -US +382232-0862041 America/Indiana/Marengo Eastern - IN (Crawford) -US +382931-0871643 America/Indiana/Petersburg Eastern - IN (Pike) -US +384452-0850402 America/Indiana/Vevay Eastern - IN (Switzerland) -US +415100-0873900 America/Chicago Central (most areas) -US +375711-0864541 America/Indiana/Tell_City Central - IN (Perry) -US +411745-0863730 America/Indiana/Knox Central - IN (Starke) -US +450628-0873651 America/Menominee Central - MI (Wisconsin border) -US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver) -US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) -US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) -US +394421-1045903 America/Denver Mountain (most areas) -US +433649-1161209 America/Boise Mountain - ID (south), OR (east) -US +332654-1120424 America/Phoenix MST - AZ (except Navajo) -US +340308-1181434 America/Los_Angeles Pacific -US +611305-1495401 America/Anchorage Alaska (most areas) -US +581807-1342511 America/Juneau Alaska - Juneau area -US +571035-1351807 America/Sitka Alaska - Sitka area -US +550737-1313435 America/Metlakatla Alaska - Annette Island -US +593249-1394338 America/Yakutat Alaska - Yakutat -US +643004-1652423 America/Nome Alaska (west) -US +515248-1763929 America/Adak Alaska - western Aleutians -US +211825-1575130 Pacific/Honolulu Hawaii -UY -345433-0561245 America/Montevideo -UZ +3940+06648 Asia/Samarkand Uzbekistan (west) -UZ +4120+06918 Asia/Tashkent Uzbekistan (east) -VA +415408+0122711 Europe/Vatican -VC +1309-06114 America/St_Vincent -VE +1030-06656 America/Caracas -VG +1827-06437 America/Tortola -VI +1821-06456 America/St_Thomas -VN +1045+10640 Asia/Ho_Chi_Minh -VU -1740+16825 Pacific/Efate -WF -1318-17610 Pacific/Wallis -WS -1350-17144 Pacific/Apia -YE +1245+04512 Asia/Aden -YT -1247+04514 Indian/Mayotte -ZA -2615+02800 Africa/Johannesburg -ZM -1525+02817 Africa/Lusaka -ZW -1750+03103 Africa/Harare diff --git a/test/jdk/java/util/TimeZone/tools/share/Makefile b/test/jdk/java/util/TimeZone/tools/share/Makefile index 69c4838efe0..47734b96c55 100644 --- a/test/jdk/java/util/TimeZone/tools/share/Makefile +++ b/test/jdk/java/util/TimeZone/tools/share/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,7 @@ TZDATA = ../../../../../../../src/java.base/share/data/tzdata TZDATA_VER = `grep '^tzdata' $(TZDATA)/VERSION` TZNAME = africa antarctica asia australasia europe northamerica \ - solar87 solar88 solar89 southamerica \ - backward + southamerica backward TZFILES = $(addprefix $(TZDATA)/, $(TZNAME)) ALIASLIST = aliases.txt DISPLAYNAMES = displaynames.txt diff --git a/test/jdk/sun/util/calendar/zi/BackEnd.java b/test/jdk/sun/util/calendar/zi/BackEnd.java deleted file mode 100644 index 10d71ff7210..00000000000 --- a/test/jdk/sun/util/calendar/zi/BackEnd.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -/** - * <code>BackEnd</code> is an abstract base class for a back-end of compiling - * Olson's zoneinfo database and generating Java zoneinfo database. - * - * @since 1.4 - */ -abstract class BackEnd { - - /** - * Receives each zone's TimeZone information which was created by - * {@link Zoneinfo#parse} in class <code>Zoneinfo</code>, - * and processes it. - * - * @param tz Timezone object for each zone - * @return 0 if no error occurred, otherwise 1. - */ - abstract int processZoneinfo(Timezone tz); - - /** - * Receives whole information which is generated by JavaZic's front-end - * in the form of Mapping object and generates all Java zone information - * files. - * - * @param m Mappings object which is generated by - * {@link Main#compile() Main.compile()}. - * @return 0 if no error occurred, otherwise 1. - */ - abstract int generateSrc(Mappings m); - - /** - * Decides which backend class should be used and returns its instance. - * @return an instance of backend class - */ - static BackEnd getBackEnd() { - if (Zoneinfo.isYearForTimeZoneDataSpecified) { - return new Simple(); - } else if (Main.outputDoc) { - return new GenDoc(); - } else { - return new Gen(); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Beyond2037.java b/test/jdk/sun/util/calendar/zi/Beyond2037.java deleted file mode 100644 index af6f16067a8..00000000000 --- a/test/jdk/sun/util/calendar/zi/Beyond2037.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * 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 8073446 8262110 - * @summary Tests DST related beyond the year 2037 - * @run testng Beyond2037 - */ - -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; - -@Test -public class Beyond2037 { - - @DataProvider - Object[][] dstTransition() { - return new Object[][] { - {"2037/03/08 01:59:59:999", "2037/03/08 01:59:59:999"}, - {"2037/03/08 02:00:00:000", "2037/03/08 03:00:00:000"}, - {"2038/03/14 01:59:59:999", "2038/03/14 01:59:59:999"}, - {"2038/03/14 02:00:00:000", "2038/03/14 03:00:00:000"}, - {"2099/03/08 01:59:59:999", "2099/03/08 01:59:59:999"}, - {"2099/03/08 02:00:00:000", "2099/03/08 03:00:00:000"}, - {"2100/03/14 01:59:59:999", "2100/03/14 01:59:59:999"}, - {"2100/03/14 02:00:00:000", "2100/03/14 03:00:00:000"}, - {"8000/03/12 01:59:59:999", "8000/03/12 01:59:59:999"}, - {"8000/03/12 02:00:00:000", "8000/03/12 03:00:00:000"}, - }; - } - - @Test(dataProvider="dstTransition") - public void testDstTransition(String source, String expected) throws Exception { - var timeZone = TimeZone.getTimeZone("America/New_York"); - var sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS" ); - sdf.setTimeZone(timeZone); - assertEquals(sdf.format(sdf.parse(source)), expected); - } - - @Test - public void testGetOffset() throws Exception { - var timeZone = TimeZone.getTimeZone("PST8PDT"); - var df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - df.setTimeZone(timeZone); - var tMilli = df.parse("7681-03-09 03:20:49").getTime(); - assertEquals(timeZone.getOffset(tMilli), -25200000); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Checksum.java b/test/jdk/sun/util/calendar/zi/Checksum.java deleted file mode 100644 index 93a1c827903..00000000000 --- a/test/jdk/sun/util/calendar/zi/Checksum.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.zip.CRC32; - -/** - * Checksum provides methods for calculating a CRC32 value for a - * transitions table. - * - * @since 1.4 - */ -public class Checksum extends CRC32 -{ - /** - * Updates the CRC32 value from each byte of the given int - * value. The bytes are used in the big endian order. - * @param val the int value - */ - public void update(int val) { - byte[] b = new byte[4]; - b[0] = (byte)((val >>> 24) & 0xff); - b[1] = (byte)((val >>> 16) & 0xff); - b[2] = (byte)((val >>> 8) & 0xff); - b[3] = (byte)(val & 0xff); - update(b); - } - - /** - * Updates the CRC32 value from each byte of the given long - * value. The bytes are used in the big endian order. - * @param val the long value - */ - void update(long val) { - byte[] b = new byte[8]; - b[0] = (byte)((val >>> 56) & 0xff); - b[1] = (byte)((val >>> 48) & 0xff); - b[2] = (byte)((val >>> 40) & 0xff); - b[3] = (byte)((val >>> 32) & 0xff); - b[4] = (byte)((val >>> 24) & 0xff); - b[5] = (byte)((val >>> 16) & 0xff); - b[6] = (byte)((val >>> 8) & 0xff); - b[7] = (byte)(val & 0xff); - update(b); - } -} diff --git a/test/jdk/sun/util/calendar/zi/DayOfWeek.java b/test/jdk/sun/util/calendar/zi/DayOfWeek.java deleted file mode 100644 index ed820a83c39..00000000000 --- a/test/jdk/sun/util/calendar/zi/DayOfWeek.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2004, 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. - */ - -/** - * Day of week enum. - * - * @since 1.6 - */ - -enum DayOfWeek { - SUNDAY("Sun"), - MONDAY("Mon"), - TUESDAY("Tue"), - WEDNESDAY("Wed"), - THURSDAY("Thu"), - FRIDAY("Fri"), - SATURDAY("Sat"); - - private final String abbr; - - private DayOfWeek(String abbr) { - this.abbr = abbr; - } - - String getAbbr() { - return abbr; - } - - int value() { - return ordinal() + 1; - } -} diff --git a/test/jdk/sun/util/calendar/zi/Gen.java b/test/jdk/sun/util/calendar/zi/Gen.java deleted file mode 100644 index 4cdabc55321..00000000000 --- a/test/jdk/sun/util/calendar/zi/Gen.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.IOException; -import java.io.File; -import java.io.FileOutputStream; -import java.io.DataOutputStream; -import java.io.RandomAccessFile; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * <code>Gen</code> is one of back-end classes of javazic, and generates - * ZoneInfoMappings and zone-specific file for each zone. - */ -class Gen extends BackEnd { - - /** - * Generates datafile in binary TLV format for each time zone. - * Regarding contents of output files, see {@link ZoneInfoFile}. - * - * @param Timezone - * @return 0 if no errors, or 1 if error occurred. - */ - int processZoneinfo(Timezone tz) { - try { - int size; - String outputDir = Main.getOutputDir(); - String zonefile = ZoneInfoFile.getFileName(tz.getName()); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - - /* If zonefile includes file-separator, it's treated as part of - * pathname. And make directory if necessary. - */ - int index = zonefile.lastIndexOf(File.separatorChar); - if (index != -1) { - outputDir += zonefile.substring(0, index+1); - } - File outD = new File(outputDir); - outD.mkdirs(); - - FileOutputStream fos = - new FileOutputStream(outputDir + zonefile.substring(index+1)); - DataOutputStream dos = new DataOutputStream(fos); - - /* Output Label */ - dos.write(ZoneInfoFile.JAVAZI_LABEL, 0, - ZoneInfoFile.JAVAZI_LABEL.length); - - /* Output Version of ZoneInfoFile */ - dos.writeByte(ZoneInfoFile.JAVAZI_VERSION); - - List<Long> transitions = tz.getTransitions(); - if (transitions != null) { - List<Integer> dstOffsets = tz.getDstOffsets(); - List<Integer> offsets = tz.getOffsets(); - - if ((dstOffsets == null && offsets != null) || - (dstOffsets != null && offsets == null)) { - Main.panic("Data not exist. (dstOffsets or offsets)"); - return 1; - } - - /* Output Transition records */ - dos.writeByte(ZoneInfoFile.TAG_Transition); - size = transitions.size(); - dos.writeShort((size * 8) & 0xFFFF); - int dstoffset; - for (int i = 0; i < size; i++) { - /* if DST offset is 0, this means DST isn't used. - * (NOT: offset's index is 0.) - */ - if ((dstoffset = dstOffsets.get(i).intValue()) == -1) { - dstoffset = 0; - } - - dos.writeLong((transitions.get(i).longValue() << 12) - | (dstoffset << 4) - | offsets.get(i).intValue()); - - } - - /* Output data for GMTOffset */ - List<Integer> gmtoffset = tz.getGmtOffsets(); - dos.writeByte(ZoneInfoFile.TAG_Offset); - size = gmtoffset.size(); - dos.writeShort((size * 4) & 0xFFFF); - for (int i = 0; i < size; i++) { - dos.writeInt(gmtoffset.get(i)); - } - } - - /* Output data for SimpleTimeZone */ - List<RuleRec> stz = tz.getLastRules(); - if (stz != null) { - RuleRec[] rr = new RuleRec[2]; - boolean wall = true; - - rr[0] = stz.get(0); - rr[1] = stz.get(1); - - dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone); - wall = rr[0].getTime().isWall() && rr[1].getTime().isWall(); - if (wall) { - dos.writeShort(32); - } else { - dos.writeShort(40); - } - - for (int i = 0; i < 2; i++) { - dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number - dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone()); - dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt()); - dos.writeInt((int)rr[i].getTime().getTime()); - if (!wall) { - dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1); - } - } - } - - /* Output RawOffset */ - dos.writeByte(ZoneInfoFile.TAG_RawOffset); - dos.writeShort(4); - dos.writeInt(tz.getRawOffset()); - - /* Output willGMTOffsetChange flag */ - if (tz.willGMTOffsetChange()) { - dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange); - dos.writeShort(1); - dos.writeByte(1); - } - - /* Output LastDSTSaving */ - dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving); - dos.writeShort(2); - dos.writeShort(tz.getLastDSTSaving()/1000); - - /* Output checksum */ - dos.writeByte(ZoneInfoFile.TAG_CRC32); - dos.writeShort(4); - dos.writeInt(tz.getCRC32()); - - fos.close(); - dos.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - /** - * Generates ZoneInfoMappings in binary TLV format for each zone. - * Regarding contents of output files, see {@link ZoneInfoFile}. - * - * @param Mappings - * @return 0 if no errors, or 1 if error occurred. - */ - int generateSrc(Mappings map) { - try { - int index; - int block_size; - int roi_size; - long fp; - String outputDir = Main.getOutputDir(); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - - File outD = new File(outputDir); - outD.mkdirs(); - - /* Open ZoneInfoMapping file to write. */ - RandomAccessFile raf = - new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw"); - - /* Whether rawOffsetIndex list exists or not. */ - List<Integer> roi = map.getRawOffsetsIndex(); - if (roi == null) { - Main.panic("Data not exist. (rawOffsetsIndex)"); - return 1; - } - roi_size = roi.size(); - - /* Whether rawOffsetIndexTable list exists or not. */ - List<Set<String>> roit = map.getRawOffsetsIndexTable(); - if (roit == null || roit.size() != roi_size) { - Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size"); - return 1; - } - - /* Output Label */ - raf.write(ZoneInfoFile.JAVAZM_LABEL, 0, - ZoneInfoFile.JAVAZM_LABEL.length); - - /* Output Version */ - raf.writeByte(ZoneInfoFile.JAVAZM_VERSION); - - index = ZoneInfoFile.JAVAZM_LABEL.length + 2; - - /* Output Version of Olson's tzdata */ - byte[] b = Main.getVersionName().getBytes("UTF-8"); - raf.writeByte(ZoneInfoFile.TAG_TZDataVersion); - raf.writeShort((b.length+1) & 0xFFFF); - raf.write(b); - raf.writeByte(0x00); - index += b.length + 4; - - /* Output ID list. */ - raf.writeByte(ZoneInfoFile.TAG_ZoneIDs); - block_size = 2; - raf.writeShort(block_size & 0xFFFF); - short nID = 0; - raf.writeShort(nID & 0xFFFF); - for (int i = 0; i < roi_size; i++) { - for (String key : roit.get(i)) { - byte size = (byte)key.getBytes("UTF-8").length; - raf.writeByte(size & 0xFF); - raf.write(key.getBytes("UTF-8"), 0, size); - block_size += 1 + size; - nID++; - } - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.writeShort(nID & 0xFFFF); - raf.seek(fp); - - /* Output sorted rawOffset list. */ - raf.writeByte(ZoneInfoFile.TAG_RawOffsets); - index += 3 + block_size; - block_size = roi_size * 4; - raf.writeShort(block_size & 0xFFFF); - for (int i = 0; i < roi_size; i++) { - raf.writeInt(Integer.parseInt(roi.get(i).toString())); - } - - /* Output sorted rawOffsetIndex list. */ - raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices); - index += 3 + block_size; - block_size = 0; - raf.writeShort(block_size & 0xFFFF); - int num; - for (int i = 0; i < roi_size; i++) { - num = roit.get(i).size(); - block_size += num; - for (int j = 0; j < num; j++) { - raf.writeByte(i); - } - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.seek(fp); - - /* Whether alias list exists or not. */ - Map<String,String> a = map.getAliases(); - if (a == null) { - Main.panic("Data not exist. (aliases)"); - return 0; - } - - /* Output ID list. */ - raf.writeByte(ZoneInfoFile.TAG_ZoneAliases); - index += 3 + block_size; - block_size = 2; - raf.writeShort(block_size & 0xFFFF); - raf.writeShort(a.size() & 0xFFFF); - for (String key : a.keySet()) { - String alias = a.get(key); - byte key_size = (byte)key.length(); - byte alias_size = (byte)alias.length(); - raf.writeByte(key_size & 0xFF); - raf.write(key.getBytes("UTF-8"), 0, key_size); - raf.writeByte(alias_size & 0xFF); - raf.write(alias.getBytes("UTF-8"), 0, alias_size); - block_size += 2 + key_size + alias_size; - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.seek(fp); - - /* Output the exclude list if it exists. */ - List<String> excludedZones = map.getExcludeList(); - if (excludedZones != null) { - raf.writeByte(ZoneInfoFile.TAG_ExcludedZones); - index += 3 + block_size; - block_size = 2; - raf.writeShort(block_size & 0xFFFF); // place holder - raf.writeShort(excludedZones.size()); // the number of excluded zones - for (String name : excludedZones) { - byte size = (byte) name.length(); - raf.writeByte(size); // byte length - raf.write(name.getBytes("UTF-8"), 0, size); // zone name - block_size += 1 + size; - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort(block_size & 0xFFFF); - raf.seek(fp); - } - - /* Close ZoneInfoMapping file. */ - raf.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } -} diff --git a/test/jdk/sun/util/calendar/zi/GenDoc.java b/test/jdk/sun/util/calendar/zi/GenDoc.java deleted file mode 100644 index e9e6ebc0cd8..00000000000 --- a/test/jdk/sun/util/calendar/zi/GenDoc.java +++ /dev/null @@ -1,776 +0,0 @@ -/* - * 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. - */ - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.StringTokenizer; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * <code>GenDoc</code> is one of back-end classes of javazic, and generates - * index.html and other html files which prints the detailed time zone - * information for each zone. - */ -class GenDoc extends BackEnd { - - private static final String docDir = "doc"; - - private static final String header1 = - "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"" + - "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" + - "<HTML>\n<HEAD>\n<!-- Generated by javazic on "; - private static final String header2 = - "-->\n<TITLE>\n" + - "Java Platform, Standard Edition - TimeZone information based on "; - private static final String header3 = - "-->\n<TITLE>\n" + - "Java Platform, Standard Edition TimeZone - "; - private static final String header4 = - "</TITLE>\n" + - "</HEAD>\n\n"; - - private static final String body1 = - "<BODY BGCOLOR=\"white\">\n"; - private static final String body2 = - "</BODY>\n"; - - private static final String footer = - "</HTML>\n"; - - - // list of time zone name and zonefile name/real time zone name - // e.g. - // key (String) : value (String) - // "America/Denver" : "America/Denver.html" (real time zone) - // "America/Shiprock" : "America/Denver" (alias) - TreeMap<String,String> timezoneList = new TreeMap<String,String>(); - - // list of time zone's display name and time zone name - // e.g. - // key (String) : value (String) - // "Tokyo, Asia" : "Asia/Tokyo" - // "Marengo, Indiana, America" : "America/Indiana/Marengo" - // (aliases included) - TreeMap<String,String> displayNameList = new TreeMap<String,String>(); - - // list of top level regions - // e.g. - // key (String) : value (String) - // "America" : "America.html" - // (including entries in America/Indiana/, America/Kentucky/, ...) - TreeMap<String,String> regionList = new TreeMap<String,String>(); - - // mapping list from zone name to latitude & longitude - // This list is generated from zone.tab. - // e.g. - // key (String) : value (LatitudeAndLongitude object) - // "Asia/Tokyo" : latitude=35.3916, longitude=13.9444 - // (aliases not included) - HashMap<String,LatitudeAndLongitude> mapList = null; - - // SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT - // offset will change in the future, its last known offset is - // used. - SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<Integer, Set<String>>(); - - /** - * Generates HTML document for each zone. - * @param Timezone - * @return 0 if no errors, or 1 if error occurred. - */ - int processZoneinfo(Timezone tz) { - try { - int size; - int index; - String outputDir = Main.getOutputDir(); - String zonename = tz.getName(); - String zonefile = ZoneInfoFile.getFileName(zonename) + ".html"; - List<RuleRec> stz = tz.getLastRules(); - timezoneList.put(zonename, zonefile); - displayNameList.put(transform(zonename), zonename); - - // Populate zonesByOffset. (Zones that will change their - // GMT offsets are also added to zonesByOffset here.) - int lastKnownOffset = tz.getRawOffset(); - Set<String> set = zonesByOffset.get(lastKnownOffset); - if (set == null) { - set = new TreeSet<String>(); - zonesByOffset.put(lastKnownOffset, set); - } - set.add(zonename); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - outputDir += docDir + File.separatorChar; - - index = zonename.indexOf('/'); - if (index != -1) { - regionList.put(zonename.substring(0, index), - zonename.substring(0, index) + ".html"); - } - - /* If zonefile includes file-separator, it's treated as part of - * pathname. And make directory if necessary. - */ - index = zonefile.lastIndexOf('/'); - if (index != -1) { - zonefile.replace('/', File.separatorChar); - outputDir += zonefile.substring(0, index+1); - } - File outD = new File(outputDir); - outD.mkdirs(); - - /* If mapfile is available, add a link to the appropriate map */ - if (mapList == null && Main.getMapFile() != null) { - mapList = new HashMap<String, LatitudeAndLongitude>(); - FileReader fr = new FileReader(Main.getMapFile()); - BufferedReader in = new BufferedReader(fr); - String line; - while ((line = in.readLine()) != null) { - // skip blank and comment lines - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - StringTokenizer tokens = new StringTokenizer(line); - String token = tokens.nextToken(); /* We don't use the first token. */ - token = tokens.nextToken(); - LatitudeAndLongitude location = new LatitudeAndLongitude(token); - token = tokens.nextToken(); - mapList.put(token, location); - } - in.close(); - } - - /* Open zoneinfo file to write. */ - FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1)); - BufferedWriter out = new BufferedWriter(fw); - - out.write(header1 + new Date() + header3 + zonename + header4); - out.write(body1 + "<FONT size=\"+2\"><B>" + zonename + "</B></FONT>"); - LatitudeAndLongitude location = (mapList != null ? mapList.get(zonename) : null); - if (location != null) { - int deg, min, sec; - - deg = location.getLatDeg(); - min = location.getLatMin(); - sec = location.getLatSec(); - if (deg < 0) { - min = -min; - sec = -sec; - } else if (min < 0) { - sec = -sec; - } - out.write("&nbsp;&nbsp;&nbsp;" + - "<A HREF=\"http://www.mapquest.com/maps/map.adp?" + - "latlongtype=degrees" + - "&latdeg=" + deg + - "&latmin=" + min + - "&latsec=" + sec); - - deg = location.getLongDeg(); - min = location.getLongMin(); - sec = location.getLongSec(); - if (deg < 0) { - min = -min; - sec = -sec; - } else if (min < 0) { - sec = -sec; - } - out.write("&longdeg=" + deg + - "&longmin=" + min + - "&longsec=" + sec + - "\" target=\"_blank\">[map]</A>"); - } - out.write("\n<P>\n"); - - List<ZoneRec> zone = tz.getZones(); - List<RuleRec> rule = tz.getRules(); - if (rule != null && zone != null) { - out.write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n" + - "<TR>\n" + - "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>" + - "<A HREF=\"#Rules\">Rules</A><BR></TD>\n" + - "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">" + - "<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n" + - "</TR>\n</TABLE>\n"); - } - - /* Output Rule records. */ - if (rule != null) { - size = rule.size(); - out.write("<P>\n<A NAME=\"Rules\">" + - "<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n" + - "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" + - "<TR BGCOLOR=\"#CCCCFF\">\n" + - "<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>" + - "<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>" + - "<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n"); - for (int i = 0; i < size; i++) { - out.write("<TR BGCOLOR=\"#FFFFFF\">\n"); - StringTokenizer st = new StringTokenizer(rule.get(i).getLine()); - String s; - if (st.hasMoreTokens()) { /* RULE - truncated */ - st.nextToken(); - } - if (st.hasMoreTokens()) { /* NAME */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* FROM */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* TO */ - s = st.nextToken(); - if (s.equals("min") || s.equals("max")) { - out.write("<TD><FONT COLOR=\"red\">" + s + "</FONT></TD>"); - } else { - out.write("<TD>" + s + "</TD>"); - } - } - if (st.hasMoreTokens()) { /* TYPE */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* IN */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* ON */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* AT */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* SAVE */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* LETTER/S */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* NOTES */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - out.write("<TD>" + s.substring(index+1) + "</TD>\n"); - } else { - out.write("<TD>&nbsp;</TD>\n"); - } - out.write("</TR>\n"); - } - out.write("</TABLE>\n<P>&nbsp;<P>\n"); - } - - /* Output Zone records. */ - if (zone != null) { - size = zone.size(); - out.write("<P>\n<A NAME=\"Zone\">" + - "<FONT SIZE=\"+1\"><B>Zone</B></FONT></A>\n" + - "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" + - "<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>" + - "<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>" + - "<TD>NOTES</TD>\n</TR>\n"); - for (int i = 0; i < size; i++) { - out.write("<TR>\n"); - StringTokenizer st = new StringTokenizer(zone.get(i).getLine()); - String s = st.nextToken(); - if (s.equals("Zone")) { /* NAME */ - s = st.nextToken(); - s = st.nextToken(); - } - out.write("<TD>" + s + "</TD>"); /* GMTOFFSET */ - if (st.hasMoreTokens()) { /* RULES */ - out.write("<TD>" + st.nextToken() + "</TD>"); - } - if (st.hasMoreTokens()) { /* FORMAT */ - s = st.nextToken(); - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write("<TD>" + s.substring(0, index-1) + - "</TD>"); /* FORMAT */ - s = s.substring(index+1); - } else { - out.write("<TD>&nbsp;</TD>"); /* FORMAT */ - } - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - out.write("<TD>&nbsp;</TD>"); /* UNTIL */ - out.write("<TD>" + s + "</TD>\n</TR>\n"); /* NOTES */ - continue; - } else { - out.write("<TD>" + s + "</TD>"); /* FORMAT */ - } - } - - if (st.hasMoreTokens()) { /* UNTIL */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write("<TD>" + s.substring(0, index-1) + - "</TD>"); /* UNTIL */ - } else { - out.write("<TD>&nbsp;</TD>"); /* UNTIL */ - } - out.write("<TD>" + s.substring(index+1) + - "</TD>\n"); /* NOTES */ - } else { - out.write("<TD>" + s + "</TD>"); /* UNTIL */ - out.write("<TD>&nbsp;</TD>\n"); /* NOTES */ - } - } else { - out.write("<TD>&nbsp;</TD>"); /* UNTIL */ - out.write("<TD>&nbsp;</TD>\n"); /* NOTES */ - } - out.write("</TR>\n"); - } - out.write("</TABLE>\n"); - } - out.write(body2 + footer); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - /** - * Generates index.html and other top-level frame files. - * @param Mappings - * @return 0 if no errors, or 1 if error occurred. - */ - int generateSrc(Mappings map) { - try { - int len; - Object o[]; - String outputDir = Main.getOutputDir(); - FileWriter fw1, fw2; - BufferedWriter out1, out2; - - /* Whether alias list exists or not. */ - Map<String,String> a = map.getAliases(); - if (a == null) { - Main.panic("Data not exist. (aliases)"); - return 1; - } - - timezoneList.putAll(a); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - outputDir += docDir + File.separatorChar; - - File outD = new File(outputDir); - outD.mkdirs(); - - /* Creates index.html */ - fw1 = new FileWriter(outputDir + "index.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + - "<FRAMESET cols=\"20%,80%\">\n" + - "<FRAMESET rows=\"30%,70%\">\n" + - "<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n" + - "<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n" + - "</FRAMESET>" + - "<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n" + - "</FRAMESET>\n" + - "<NOFRAMES>\n" + - "<H2>\nFrame Alert\n</H2>\n\n" + - "<P>\n\n" + - "This document is designed to be viewed using the frames feature. If you see this\n" + - "message, you are using a non-frame-capable web client.\n" + - "<BR>\n" + - "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" + - "</NOFRAMES>\n" + footer); - - out1.close(); - fw1.close(); - - - /* Creates overview-frame.html */ - fw1 = new FileWriter(outputDir + "overview-frame.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n" + - "<TD NOWRAP><FONT size=\"+1\">\n" + - "<B>Java<sup><font size=-2>TM</font></sup>&nbsp;Platform<br>Standard&nbsp;Ed.</B></FONT></TD>\n" + - "</TR>\n</TABLE>\n\n" + - "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n<TD NOWRAP>" + - "<P>\n<FONT size=\"+1\">\nAll Time Zones Sorted By:</FONT>\n<BR>\n" + - "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame1.html\" TARGET=\"allTimeZoneFrame\">GMT offsets</A></FONT>\n<BR>\n" + - "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame2.html\" TARGET=\"allTimeZoneFrame\">Zone names</A></FONT>\n<BR>" + - "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame3.html\" TARGET=\"allTimeZoneFrame\">City names</A></FONT>\n" + - "<P>\n<FONT size=\"+1\">\nContinents and Oceans</FONT>\n<BR>\n"); - - for (String regionKey : regionList.keySet()) { - out1.write("&nbsp;&nbsp;<A HREF=\"" + regionList.get(regionKey) + - "\" TARGET=\"allTimeZoneFrame\">" + regionKey + - "</A><BR>\n"); - - fw2 = new FileWriter(outputDir + regionList.get(regionKey), - false); - out2 = new BufferedWriter(fw2); - - out2.write(header1 + new Date() + header3 + regionKey + - header4 + body1 + "<FONT size=\"+1\"><B>" + - regionKey + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>"); - - boolean found = false; - for (String timezoneKey : timezoneList.keySet()) { - int regionIndex = timezoneKey.indexOf('/'); - if (regionIndex == -1 || - !regionKey.equals(timezoneKey.substring(0, regionIndex))) { - if (found) { - break; - } else { - continue; - } - } - - found = true; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out2.write(timezoneKey + - " (alias for " + "<A HREF=\"" + - timezoneList.get(realName) + - "\" TARGET=\"rightFrame\">" + - realName + "</A>)"); - } else { - out2.write("<A HREF=\"" + timezoneList.get(timezoneKey) + - "\" TARGET=\"rightFrame\">" + timezoneKey + - "</A>"); - } - out2.write("<BR>\n"); - } - out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer); - - out2.close(); - fw2.close(); - } - out1.write("</FONT></TD>\n</TR></TABLE>\n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n" + - "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" + - "<TR>\n<TD NOWRAP>\n"); - - List<Integer> roi = map.getRawOffsetsIndex(); - List<Set<String>> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (Integer offset : zonesByOffset.keySet()) { - int off = roi.get(index); - Set<String> perRO = zonesByOffset.get(offset); - if (offset == off) { - // Merge aliases into zonesByOffset - perRO.addAll(roit.get(index)); - } - index++; - - for (String timezoneKey : perRO) { - out1.write("<TR>\n<TD><FONT SIZE=\"-1\">(" + - Time.toGMTFormat(offset.toString()) + - ")</FONT></TD>\n<TD>"); - - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + "<A HREF=\"" + - timezoneList.get(realName) + - "\" TARGET=\"rightFrame\">" + realName + - "</A>)"); - } else { - out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) + - "\" TARGET=\"rightFrame\">" + timezoneKey + - "</A>"); - } - out1.write("</TD>\n</TR>\n"); - } - } - out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame2.html (Sorted by zone names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n" + - "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" + - "<TR>\n<TD NOWRAP>\n"); - o = timezoneList.keySet().toArray(); - len = timezoneList.size(); - for (int i = 0; i < len; i++) { - Object timezoneKey = o[i]; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + - "<A HREF=\"" + timezoneList.get(realName) + - "\" TARGET=\"rightFrame\">" + realName + - "</A>)"); - } else { - out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) + - "\" TARGET=\"rightFrame\">" + timezoneKey + - "</A>"); - } - out1.write("<BR> \n"); - } - out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates allTimeZone-frame3.html (Sorted by city names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n" + - "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" + - "<TR>\n<TD NOWRAP>\n"); - - Set<String> aliasSet = a.keySet(); - len = aliasSet.size(); - String aliasNames[] = aliasSet.toArray(new String[0]); - for (int i = 0; i < len; i++) { - displayNameList.put(transform(aliasNames[i]), - aliasNames[i]); - } - - o = displayNameList.keySet().toArray(); - len = displayNameList.size(); - for (int i = 0; i < len; i++) { - Object displayName = o[i]; - Object timezoneKey = displayNameList.get(o[i]); - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(displayName + - " (alias for " + - "<A HREF=\"" + timezoneList.get(realName) + - "\" TARGET=\"rightFrame\">" + realName + - "</A>)"); - } else { - out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) + - "\" TARGET=\"rightFrame\">" + displayName + - "</A>"); - } - out1.write("<BR> \n"); - } - - out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates overview-summary.html */ - fw1 = new FileWriter(outputDir + "overview-summary.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "<p>This is the list of time zones generated from <B>" + - Main.getVersionName() + "</B> for Java Platform, " + - "Standard Edition. The source code can be obtained " + - "from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">" + - "ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>" + - len + - "</B> time zones and aliases are supported " + - "in this edition. For the " + - "format of rules and zones, refer to the zic " + - "(zoneinfo compiler) man page on " + - "Solaris or Linux.</p>\n" + - "<p>Note that the time zone data is not " + - "a public interface of the Java Platform. No " + - "applications should rely on the time zone data of " + - "this document. Time zone names and data " + - "may change without any prior notice.</p>\n" + - body2 + footer); - - out1.close(); - fw1.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - String transform(String s) { - int index = s.lastIndexOf("/"); - - /* If the string doesn't include any delimiter, return */ - if (index == -1) { - return s; - } - - int lastIndex = index; - String str = s.substring(index+1); - do { - index = s.substring(0, lastIndex).lastIndexOf('/'); - str += ", " + s.substring(index+1, lastIndex); - lastIndex = index; - } while (index > -1); - - return str; - } - - static class LatitudeAndLongitude { - - private int latDeg, latMin, latSec, longDeg, longMin, longSec; - - LatitudeAndLongitude(String s) { - try { - // First of all, check the string has the correct format: - // either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS - - if (!s.startsWith("+") && !s.startsWith("-")) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - int index; - if (((index = s.lastIndexOf("+")) <= 0) && - ((index = s.lastIndexOf("-")) <= 0)) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - - if (index == 5) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = 0; - } else if (index == 7) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = Integer.parseInt(s.substring(5, 7)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.startsWith("-")){ - latDeg = -latDeg; - latMin = -latMin; - latSec = -latSec; - } - - int len = s.length(); - if (index == 5 && len == 11) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = 0; - } else if (index == 7 && len == 15) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = Integer.parseInt(s.substring(index+6, index+8)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.charAt(index) == '-'){ - longDeg = -longDeg; - longMin = -longMin; - longSec = -longSec; - } - } catch(Exception e) { - Main.warning("LatitudeAndLongitude() Parse error: " + s); - } - } - - int getLatDeg() { - return latDeg; - } - - int getLatMin() { - return latMin; - } - - int getLatSec() { - return latSec; - } - - int getLongDeg() { - return longDeg; - } - - int getLongMin() { - return longMin; - } - - int getLongSec() { - return longSec; - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Main.java b/test/jdk/sun/util/calendar/zi/Main.java deleted file mode 100644 index 8078d7e2425..00000000000 --- a/test/jdk/sun/util/calendar/zi/Main.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Main class for the javazic time zone data compiler. - * - * @since 1.4 - */ -public class Main { - - private static boolean verbose = false; - static boolean outputDoc = false; - - private List<String> ziFiles = new ArrayList<String>(); - private static String zoneNamesFile = null; - private static String versionName = "unknown"; - private static String outputDir = "zoneinfo"; - private static String mapFile = null; - - /** - * Parses the specified arguments and sets up the variables. - * @param argv the arguments - */ - void processArgs(String[] argv) { - for (int i = 0; i < argv.length; i++) { - String arg = argv[i]; - if (arg.startsWith("-h")) { - usage(); - System.exit(0); - } else if (arg.equals("-d")) { - outputDir = argv[++i]; - } else if (arg.equals("-v")) { - verbose = true; - } else if (arg.equals("-V")) { - versionName = argv[++i]; - } else if (arg.equals("-doc")) { - outputDoc = true; - } else if (arg.equals("-map")) { - outputDoc = true; - mapFile = argv[++i]; - } else if (arg.equals("-f")) { - zoneNamesFile = argv[++i]; - } else if (arg.equals("-S")) { - try { - Zoneinfo.setYear(Integer.parseInt(argv[++i])); - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - boolean isStartYear = arg.equals("-s"); - if (isStartYear || arg.equals("-e")) { - try { - int year = Integer.parseInt(argv[++i]); - if (isStartYear) { - Zoneinfo.setStartYear(year); - } else { - Zoneinfo.setEndYear(year); - } - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - // the rest of args are zoneinfo source files - while (i < argv.length) { - ziFiles.add(argv[i++]); - } - } - } - } - } - - /** - * Parses zoneinfo source files - */ - int compile() { - int nFiles = ziFiles.size(); - int status = 0; - Mappings maps = new Mappings(); - BackEnd backend = BackEnd.getBackEnd(); - - for (int i = 0; i < nFiles; i++) { - Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i)); - - for (String key : frontend.getZones().keySet()) { - info(key); - - Timezone tz = frontend.phase2(key); - status |= backend.processZoneinfo(tz); - } - - maps.add(frontend); - } - - // special code for dealing with the conflicting name "MET" - Zone.addMET(); - - maps.resolve(); - - status |= backend.generateSrc(maps); - - return status; - } - - public static void main(String[] argv) { - Main zic = new Main(); - - /* - * Parse args - */ - zic.processArgs(argv); - - /* - * Read target zone names - */ - if (zoneNamesFile != null) { - Zone.readZoneNames(zoneNamesFile); - } - - zic.compile(); - } - - void usage() { - System.err.println("Usage: javazic [options] file...\n"+ - " -f namefile file containing zone names\n"+ - " to be generated (ie, generating subset)\n"+ - " -d dir output directory\n"+ - " -v verbose\n"+ - " -V datavers specifies the tzdata version string\n"+ - " (eg, \"tzdata2000g\")"+ - " -S year output only SimleTimeZone data of that year\n"+ - " -s year start year (default: 1900)\n"+ - " -e year end year (default: 2037)\n"+ - " -doc generates HTML documents\n"+ - " -map mapfile generates HTML documents with map information\n"+ - " file... zoneinfo source file(s)"); - } - - /** - * @return the output directory path name - */ - static String getOutputDir() { - return outputDir; - } - - /** - * @return the map file's path and name - */ - static String getMapFile() { - return mapFile; - } - - /** - * Returns the time zone data version string specified by the -V - * option. If it is not specified, "unknown" is returned. - * @return the time zone data version string - */ - static String getVersionName() { - return versionName; - } - - /** - * Prints out the specified fatal error message and calls {@link - * java.lang.System#exit System.exit(1)}. - * @param msg the fatal error message - */ - static void panic(String msg) { - printMessage("fatal error", msg); - System.exit(1); - } - - /** - * Prints out the specified error message. - * @param msg the error message - */ - static void error(String msg) { - printMessage("error", msg); - } - - /** - * Prints out the specified warning message. - * @param msg the warning message - */ - static void warning(String msg) { - printMessage("warning", msg); - } - - /** - * Prints out the informative message. - * @param msg the informative message - */ - static void info(String msg) { - if (verbose) { - printMessage(null, msg); - } - } - - private static void printMessage(String type, String msg) { - if (type != null) { - type += ": "; - } else { - type = ""; - } - System.err.println("javazic: " + type + msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Mappings.java b/test/jdk/sun/util/calendar/zi/Mappings.java deleted file mode 100644 index 582a9509a51..00000000000 --- a/test/jdk/sun/util/calendar/zi/Mappings.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * <code>Mappings</code> generates two Maps and a List which are used by - * javazic BackEnd. - * - * @since 1.4 - */ -class Mappings { - // All aliases specified by Link statements. It's alias name to - // real name mappings. - private Map<String,String> aliases; - - private List<Integer> rawOffsetsIndex; - - private List<Set<String>> rawOffsetsIndexTable; - - // Zone names to be excluded from rawOffset table. Those have GMT - // offsets to change some future time. - private List<String> excludeList; - - /** - * Constructor creates some necessary instances. - */ - Mappings() { - aliases = new TreeMap<String,String>(); - rawOffsetsIndex = new LinkedList<Integer>(); - rawOffsetsIndexTable = new LinkedList<Set<String>>(); - } - - /** - * Generates aliases and rawOffsets tables. - * @param zi a Zoneinfo containing Zones - */ - void add(Zoneinfo zi) { - Map<String,Zone> zones = zi.getZones(); - - for (String zoneName : zones.keySet()) { - Zone zone = zones.get(zoneName); - String zonename = zone.getName(); - int rawOffset = zone.get(zone.size()-1).getGmtOffset(); - - // If the GMT offset of this Zone will change in some - // future time, this Zone is added to the exclude list. - boolean isExcluded = false; - for (int i = 0; i < zone.size(); i++) { - ZoneRec zrec = zone.get(i); - if ((zrec.getGmtOffset() != rawOffset) - && (zrec.getUntilTime(0) > Time.getCurrentTime())) { - if (excludeList == null) { - excludeList = new ArrayList<String>(); - } - excludeList.add(zone.getName()); - isExcluded = true; - break; - } - } - - if (!rawOffsetsIndex.contains(new Integer(rawOffset))) { - // Find the index to insert this raw offset zones - int n = rawOffsetsIndex.size(); - int i; - for (i = 0; i < n; i++) { - if (rawOffsetsIndex.get(i) > rawOffset) { - break; - } - } - rawOffsetsIndex.add(i, rawOffset); - - Set<String> perRawOffset = new TreeSet<String>(); - if (!isExcluded) { - perRawOffset.add(zonename); - } - rawOffsetsIndexTable.add(i, perRawOffset); - } else if (!isExcluded) { - int i = rawOffsetsIndex.indexOf(new Integer(rawOffset)); - Set<String> perRawOffset = rawOffsetsIndexTable.get(i); - perRawOffset.add(zonename); - } - } - - Map<String,String> a = zi.getAliases(); - // If there are time zone names which refer to any of the - // excluded zones, add those names to the excluded list. - if (excludeList != null) { - for (String zoneName : a.keySet()) { - String realname = a.get(zoneName); - if (excludeList.contains(realname)) { - excludeList.add(zoneName); - } - } - } - aliases.putAll(a); - } - - /** - * Adds valid aliases to one of per-RawOffset table and removes - * invalid aliases from aliases List. Aliases referring to - * excluded zones are not added to a per-RawOffset table. - */ - void resolve() { - int index = rawOffsetsIndexTable.size(); - List<String> toBeRemoved = new ArrayList<String>(); - for (String key : aliases.keySet()) { - boolean validname = false; - for (int j = 0; j < index; j++) { - Set<String> perRO = rawOffsetsIndexTable.get(j); - boolean isExcluded = (excludeList == null) ? - false : excludeList.contains(key); - - if ((perRO.contains(aliases.get(key)) || isExcluded) - && Zone.isTargetZone(key)) { - validname = true; - if (!isExcluded) { - perRO.add(key); - Main.info("Alias <"+key+"> added to the list."); - } - break; - } - } - - if (!validname) { - Main.info("Alias <"+key+"> removed from the list."); - toBeRemoved.add(key); - } - } - - // Remove zones, if any, from the list. - for (String key : toBeRemoved) { - aliases.remove(key); - } - // Eliminate any alias-to-alias mappings. For example, if - // there are A->B and B->C, A->B is changed to A->C. - Map<String, String> newMap = new HashMap<String, String>(); - for (String key : aliases.keySet()) { - String realid = aliases.get(key); - String leaf = realid; - while (aliases.get(leaf) != null) { - leaf = aliases.get(leaf); - } - if (!realid.equals(leaf)) { - newMap.put(key, leaf); - } - } - aliases.putAll(newMap); - } - - Map<String,String> getAliases() { - return(aliases); - } - - List<Integer> getRawOffsetsIndex() { - return(rawOffsetsIndex); - } - - List<Set<String>> getRawOffsetsIndexTable() { - return(rawOffsetsIndexTable); - } - - List<String> getExcludeList() { - return excludeList; - } -} diff --git a/test/jdk/sun/util/calendar/zi/Month.java b/test/jdk/sun/util/calendar/zi/Month.java deleted file mode 100644 index bab909f7637..00000000000 --- a/test/jdk/sun/util/calendar/zi/Month.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 - * 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. - */ - -/** - * Month enum handles month related manipulation. - * - * @since 1.4 - */ -enum Month { - JANUARY("Jan"), - FEBRUARY("Feb"), - MARCH("Mar"), - APRIL("Apr"), - MAY("May"), - JUNE("Jun"), - JULY("Jul"), - AUGUST("Aug"), - SEPTEMBER("Sep"), - OCTOBER("Oct"), - NOVEMBER("Nov"), - DECEMBER("Dec"); - - private final String abbr; - - private Month(String abbr) { - this.abbr = abbr; - } - - int value() { - return ordinal() + 1; - } - - /** - * Parses the specified string as a month abbreviation. - * @param name the month abbreviation - * @return the Month value - */ - static Month parse(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY; - if (name.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY; - if (name.regionMatches(true, 0, "March", 0, len)) return Month.MARCH; - if (name.regionMatches(true, 0, "April", 0, len)) return Month.APRIL; - if (name.regionMatches(true, 0, "May", 0, len)) return Month.MAY; - if (name.regionMatches(true, 0, "June", 0, len)) return Month.JUNE; - if (name.regionMatches(true, 0, "July", 0, len)) return Month.JULY; - if (name.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST; - if (name.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER; - if (name.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER; - if (name.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER; - if (name.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER; - - throw new IllegalArgumentException("Unknown month: " + name); - } - - /** - * @param month the nunmth number (1-based) - * @return the month name in uppercase of the specified month - */ - static String toString(int month) { - if (month >= JANUARY.value() && month <= DECEMBER.value()) { - return "Calendar." + Month.values()[month - 1]; - } - throw new IllegalArgumentException("wrong month number: " + month); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Rule.java b/test/jdk/sun/util/calendar/zi/Rule.java deleted file mode 100644 index 3098dc7e766..00000000000 --- a/test/jdk/sun/util/calendar/zi/Rule.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Rule manipulates Rule records. - * - * @since 1.4 - */ -class Rule { - - private List<RuleRec> list; - private String name; - - /** - * Constructs a Rule which consists of a Rule record list. The - * specified name is given to this Rule. - * @param name the Rule name - */ - Rule(String name) { - this.name = name; - list = new ArrayList<RuleRec>(); - } - - /** - * Added a RuleRec to the Rule record list. - */ - void add(RuleRec rec) { - list.add(rec); - } - - /** - * @return the Rule name - */ - String getName() { - return name; - } - - /** - * Gets all rule records that cover the given year. - * - * @param year the year number for which the rule is applicable. - * @return rules in List that are collated in time. If no rule is found, an empty - * List is returned. - */ - List<RuleRec> getRules(int year) { - List<RuleRec> rules = new ArrayList<RuleRec>(3); - for (RuleRec rec : list) { - if (year >= rec.getFromYear() && year <= rec.getToYear()) { - if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1)) - continue; - rules.add(rec); - } - } - int n = rules.size(); - if (n <= 1) { - return rules; - } - if (n == 2) { - RuleRec rec1 = rules.get(0); - RuleRec rec2 = rules.get(1); - if (rec1.getMonthNum() > rec2.getMonthNum()) { - rules.set(0, rec2); - rules.set(1, rec1); - } else if (rec1.getMonthNum() == rec2.getMonthNum()) { - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(year, rec1.getMonth(), - rec1.getDay(), rec1.getTime().getTime()); - long t2 = Time.getLocalTime(year, rec2.getMonth(), - rec2.getDay(), rec2.getTime().getTime()); - if (t1 > t2) { - rules.set(0, rec2); - rules.set(1, rec1); - } - } - return rules; - } - - final int y = year; - RuleRec[] recs = new RuleRec[rules.size()]; - rules.toArray(recs); - - Arrays.sort(recs, new Comparator<RuleRec>() { - public int compare(RuleRec r1, RuleRec r2) { - int n = r1.getMonthNum() - r2.getMonthNum(); - if (n != 0) { - return n; - } - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(y, r1.getMonth(), - r1.getDay(), r1.getTime().getTime()); - long t2 = Time.getLocalTime(y, r2.getMonth(), - r2.getDay(), r2.getTime().getTime()); - return Long.compare(t1, t2); - } - public boolean equals(Object o) { - return this == o; - } - }); - rules.clear(); - for (int i = 0; i < n; i++) { - if (i != 0 && recs[i -1].getSave() == recs[i].getSave()) { - // we have two recs back to back with same saving for the same year. - if (recs[i].isLastRule()) { - continue; - } else if (recs[i - 1].isLastRule()) { - rules.remove(rules.size() - 1); - } - } - rules.add(recs[i]); - } - return rules; - } - - /** - * Gets rule records that have either "max" or cover the endYear - * value in its DST schedule. - * - * @return rules that contain last DST schedule. An empty - * ArrayList is returned if no last rules are found. - */ - List<RuleRec> getLastRules() { - RuleRec start = null; - RuleRec end = null; - - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (rec.isLastRule()) { - if (rec.getSave() > 0) { - start = rec; - } else { - end = rec; - } - } - } - if (start == null || end == null) { - int endYear = Zoneinfo.getEndYear(); - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) { - if (start == null && rec.getSave() > 0) { - start = rec; - } else { - if (end == null && rec.getSave() == 0) { - end = rec; - } - } - } - } - } - - List<RuleRec> r = new ArrayList<RuleRec>(2); - if (start == null || end == null) { - if (start != null || end != null) { - Main.warning("found last rules for "+name+" inconsistent."); - } - return r; - } - - r.add(start); - r.add(end); - return r; - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleDay.java b/test/jdk/sun/util/calendar/zi/RuleDay.java deleted file mode 100644 index 9cd81c1e524..00000000000 --- a/test/jdk/sun/util/calendar/zi/RuleDay.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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 - * 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. - */ - -/** - * RuleDay class represents the value of the "ON" field. The day of - * week values start from 1 following the {@link java.util.Calendar} - * convention. - * - * @since 1.4 - */ -class RuleDay { - private String dayName = null; - private DayOfWeek dow; - private boolean lastOne = false; - private int soonerOrLater = 0; - private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8") - - RuleDay() { - } - - RuleDay(int day) { - thanDayOfMonth = day; - } - - int getDay() { - return thanDayOfMonth; - } - - /** - * @return the day of week value (1-based) - */ - int getDayOfWeekNum() { - return dow.value(); - } - - /** - * @return true if this rule day represents the last day of - * week. (e.g., lastSun). - */ - boolean isLast() { - return lastOne; - } - - /** - * @return true if this rule day represents the day of week on or - * later than (after) the {@link #getDay}. (e.g., Sun>=1) - */ - boolean isLater() { - return soonerOrLater > 0; - } - - /** - * @return true if this rule day represents the day of week on or - * earlier than (before) the {@link #getDay}. (e.g., Sun<=15) - */ - boolean isEarlier() { - return soonerOrLater < 0; - } - - /** - * @return true if this rule day represents an exact day. - */ - boolean isExact() { - return soonerOrLater == 0; - } - - /** - * Parses the "ON" field and constructs a RuleDay. - * @param day an "ON" field string (e.g., "Sun>=1") - * @return a RuleDay representing the given "ON" field - */ - static RuleDay parse(String day) { - RuleDay d = new RuleDay(); - if (day.startsWith("last")) { - d.lastOne = true; - d.dayName = day.substring(4); - d.dow = getDOW(d.dayName); - } else { - int index; - if ((index = day.indexOf(">=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = 1; // greater or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else if ((index = day.indexOf("<=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = -1; // less or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else { - // it should be an integer value. - d.thanDayOfMonth = Integer.parseInt(day); - } - } - return d; - } - - /** - * Converts this RuleDay to the SimpleTimeZone day rule. - * @return the converted SimpleTimeZone day rule - */ - int getDayForSimpleTimeZone() { - if (isLast()) { - return -1; - } - return isEarlier() ? -getDay() : getDay(); - } - - /** - * Converts this RuleDay to the SimpleTimeZone day-of-week rule. - * @return the SimpleTimeZone day-of-week rule value - */ - int getDayOfWeekForSimpleTimeZoneInt() { - if (isEarlier() || isLater()) { - return -getDayOfWeekNum(); - } - return isLast() ? getDayOfWeekNum() : 0; - } - - /** - * @return the string representation of the {@link - * #getDayOfWeekForSimpleTimeZoneInt} value - */ - String getDayOfWeekForSimpleTimeZone() { - int d = getDayOfWeekForSimpleTimeZoneInt(); - if (d == 0) { - return "0"; - } - String sign = ""; - if (d < 0) { - sign = "-"; - d = -d; - } - return sign + toString(d); - } - - private static DayOfWeek getDOW(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY; - if (name.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY; - if (name.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY; - if (name.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY; - if (name.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY; - if (name.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY; - if (name.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY; - - throw new IllegalArgumentException("Unknown day-of-week: " + name); - } - - /** - * Converts the specified day of week value to the day-of-week - * name defined in {@link java.util.Calendar}. - * @param dow 1-based day of week value - * @return the Calendar day of week name with "Calendar." prefix. - * @throws IllegalArgumentException if the specified dow value is out of range. - */ - static String toString(int dow) { - if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) { - return "Calendar." + DayOfWeek.values()[dow - 1]; - } - throw new IllegalArgumentException("wrong Day_of_Week number: " + dow); - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleRec.java b/test/jdk/sun/util/calendar/zi/RuleRec.java deleted file mode 100644 index e6e18773d16..00000000000 --- a/test/jdk/sun/util/calendar/zi/RuleRec.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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 - * 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.StringTokenizer; - -/** - * RuleRec class represents one record of the Rule set. - * - * @since 1.4 - */ -class RuleRec { - private int fromYear; - private int toYear; - private String type; - private Month inMonth; - private RuleDay onDay; - private Time atTime; - private int save; - private String letters; - private String line; - private boolean isLastRule; - - int getFromYear() { - return fromYear; - } - - int getToYear() { - return toYear; - } - - Month getMonth() { - return inMonth; - } - - int getMonthNum() { - return inMonth.value(); - } - - RuleDay getDay() { - return onDay; - } - - Time getTime() { - return atTime; - } - - int getSave() { - return save; - } - - String getLine() { - return line; - } - - /** - * Sets the line from the text file. - * @param line the text of the line - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if the rule type is "odd". - */ - boolean isOdd() { - return "odd".equals(type); - } - - /** - * @return true if the rule type is "even". - */ - boolean isEven() { - return "even".equals(type); - } - - /** - * Determines if this rule record is the last DST schedule rule. - * - * @return true if this rule record has "max" as TO (year). - */ - boolean isLastRule() { - return isLastRule; - } - - /** - * Determines if the unadjusted until time of the specified ZoneRec - * is the same as the transition time of this rule in the same - * year as the ZoneRec until year. - * - * @param zrec ZoneRec to compare to - * @param save the amount of daylight saving in milliseconds - * @param gmtOffset the GMT offset value in milliseconds - * @return true if the unadjusted until time is the same as rule's - * transition time. - */ - boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) { - long until, transition; - - if (zrec.getUntilTime().getType() != atTime.getType()) { - until = zrec.getLocalUntilTime(save, gmtOffset); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - save, - gmtOffset, - atTime); - } else { - until = zrec.getLocalUntilTime(); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - atTime.getTime()); - } - - return until == transition; - } - - /** - * Parses a Rule line and returns a RuleRec object. - * - * @param tokens a StringTokenizer object that should contain a - * token for the "FROM" field and the rest. - * @return a RuleRec object. - */ - static RuleRec parse(StringTokenizer tokens) { - RuleRec rec = new RuleRec(); - try { - // FROM - String token = tokens.nextToken(); - try { - rec.fromYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - if ("min".equals(token) || "minimum".equals(token)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if ("max".equals(token) || "maximum".equals(token)) { - rec.fromYear = Zoneinfo.getMaxYear(); - } else { - Main.panic("invalid year value: "+token); - } - } - - // TO - token = tokens.nextToken(); - rec.isLastRule = false; - try { - rec.toYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - int len = token.length(); - if (token.regionMatches(true, 0, "minimum", 0, len)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if (token.regionMatches(true, 0, "maximum", 0, len)) { - rec.toYear = Integer.MAX_VALUE; - rec.isLastRule = true; - } else if (token.regionMatches(true, 0, "only", 0, len)) { - rec.toYear = rec.fromYear; - } else { - Main.panic("invalid year value: "+token); - } - } - - // TYPE - rec.type = tokens.nextToken(); - - // IN - rec.inMonth = Month.parse(tokens.nextToken()); - - // ON - rec.onDay = RuleDay.parse(tokens.nextToken()); - - // AT - rec.atTime = Time.parse(tokens.nextToken()); - - // SAVE - rec.save = (int) Time.parse(tokens.nextToken()).getTime(); - - // LETTER/S - rec.letters = tokens.nextToken(); - } catch (Exception e) { - e.printStackTrace(); - } - return rec; - } - - /** - * Calculates the transition time of the given year under this rule. - * @param year the year value - * @param gmtOffset the GMT offset value in milliseconds - * @param save the amount of daylight save time - * @return the transition time in milliseconds of the given year in UTC. - */ - long getTransitionTime(int year, int gmtOffset, int save) { - long time = Time.getLocalTime(year, getMonth(), - getDay(), atTime.getTime()); - if (atTime.isSTD()) { - time -= gmtOffset; - } else if (atTime.isWall()) { - time -= gmtOffset + save; - } - return time; - } - - private static int getInt(StringTokenizer tokens) { - String token = tokens.nextToken(); - return Integer.parseInt(token); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Simple.java b/test/jdk/sun/util/calendar/zi/Simple.java deleted file mode 100644 index 0889155a99e..00000000000 --- a/test/jdk/sun/util/calendar/zi/Simple.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * <code>Simple</code> generates TimeZoneData, which had been used as internal - * data of TimeZone before J2SDK1.3. - * Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance - * of old JDK release. - */ -class Simple extends BackEnd { - - /** - * Zone records which are applied for given year. - */ - private static Map<String,ZoneRec> lastZoneRecs = new HashMap<>(); - - /** - * Rule records which are applied for given year. - */ - private static Map<String,List<RuleRec>> lastRules = new TreeMap<>(); - - /** - * zone IDs sorted by their GMT offsets. If zone's GMT - * offset will change in the future, its last known offset is - * used. - */ - private SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<>(); - - /** - * Sets last Rule records and Zone records for given timezone to - * each Map. - * - * @param tz Timezone object for each zone - * @return always 0 - */ - int processZoneinfo(Timezone tz) { - String zonename = tz.getName(); - - lastRules.put(zonename, tz.getLastRules()); - lastZoneRecs.put(zonename, tz.getLastZoneRec()); - - // Populate zonesByOffset. (Zones that will change their - // GMT offsets are also added to zonesByOffset here.) - int lastKnownOffset = tz.getRawOffset(); - Set<String> set = zonesByOffset.get(lastKnownOffset); - if (set == null) { - set = new TreeSet<>(); - zonesByOffset.put(lastKnownOffset, set); - } - set.add(zonename); - - return 0; - } - - /** - * Generates TimeZoneData to output SimpleTimeZone data. - * @param map Mappings object which is generated by {@link Main#compile}. - * @return 0 if no error occurred, otherwise 1. - */ - int generateSrc(Mappings map) { - try { - File outD = new File(Main.getOutputDir()); - outD.mkdirs(); - - FileWriter fw = - new FileWriter(new File(outD, "TimeZoneData.java"), false); - BufferedWriter out = new BufferedWriter(fw); - - out.write("import java.util.SimpleTimeZone;\n\n"); - out.write(" static SimpleTimeZone zones[] = {\n"); - - Map<String,String> a = map.getAliases(); - List<Integer> roi = map.getRawOffsetsIndex(); - List<Set<String>> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (int offset : zonesByOffset.keySet()) { - int o = roi.get(index); - Set<String> set = zonesByOffset.get(offset); - if (offset == o) { - // Merge aliases into zonesByOffset - set.addAll(roit.get(index)); - } - index++; - - for (String key : set) { - ZoneRec zrec; - String realname; - List<RuleRec> stz; - if ((realname = a.get(key)) != null) { - // if this alias is not targeted, ignore it. - if (!Zone.isTargetZone(key)) { - continue; - } - stz = lastRules.get(realname); - zrec = lastZoneRecs.get(realname); - } else { - stz = lastRules.get(key); - zrec = lastZoneRecs.get(key); - } - - out.write("\t//--------------------------------------------------------------------\n"); - String s = Time.toFormedString(offset); - out.write("\tnew SimpleTimeZone(" + - Time.toFormedString(offset) + ", \"" + key + "\""); - if (realname != null) { - out.write(" /* " + realname + " */"); - } - - if (stz == null) { - out.write("),\n"); - } else { - RuleRec rr0 = stz.get(0); - RuleRec rr1 = stz.get(1); - - out.write(",\n\t " + Month.toString(rr0.getMonthNum()) + - ", " + rr0.getDay().getDayForSimpleTimeZone() + ", " + - rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr0.getTime().getTime()) + ", " + - rr0.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Month.toString(rr1.getMonthNum()) + ", " + - rr1.getDay().getDayForSimpleTimeZone() + ", " + - rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr1.getTime().getTime())+ ", " + - rr1.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Time.toFormedString(rr0.getSave()) + "),\n"); - - out.write("\t// " + rr0.getLine() + "\n"); - out.write("\t// " + rr1.getLine() + "\n"); - } - - String zline = zrec.getLine(); - if (zline.indexOf("Zone") == -1) { - zline = "Zone " + key + "\t" + zline.trim(); - } - out.write("\t// " + zline + "\n"); - } - } - out.write(" };\n"); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java b/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java deleted file mode 100644 index 0b6570b74dc..00000000000 --- a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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 - * 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 8007572 8008161 8157792 8212970 8224560 8324065 - * @summary Test whether the TimeZone generated from JSR310 tzdb is the same - * as the one from the tz data from javazic - * @modules java.base/sun.util.calendar:+open - * @build BackEnd Checksum DayOfWeek Gen GenDoc Main Mappings Month - * Rule RuleDay RuleRec Simple TestZoneInfo310 Time Timezone - * TzIDOldMapping Zone ZoneInfoFile ZoneInfoOld ZoneRec Zoneinfo - * @run main TestZoneInfo310 - */ - -import java.io.File; -import java.lang.reflect.*; -import java.nio.file.*; -import java.util.*; -import java.util.regex.*; -import java.time.zone.*; -import java.time.ZoneId; - -public class TestZoneInfo310 { - - public static void main(String[] args) throws Throwable { - - String TESTDIR = System.getProperty("test.dir", "."); - Path tzdir = Paths.get(System.getProperty("test.root"), - "../../src/java.base/share/data/tzdata"); - String tzfiles = "africa antarctica asia australasia europe northamerica southamerica backward etcetera gmt"; - Path jdk_tzdir = Paths.get(System.getProperty("test.src"), "tzdata_jdk"); - String jdk_tzfiles = "jdk11_backward"; - String zidir = TESTDIR + File.separator + "zi"; - File fZidir = new File(zidir); - if (!fZidir.exists()) { - fZidir.mkdirs(); - } - Matcher m = Pattern.compile("tzdata(?<ver>[0-9]{4}[A-z])") - .matcher(new String(Files.readAllBytes(tzdir.resolve("VERSION")), "ascii")); - String ver = m.find() ? m.group("ver") : "NULL"; - - ArrayList<String> alist = new ArrayList<>(); - alist.add("-V"); - alist.add(ver); - alist.add("-d"); - alist.add(zidir); - for (String f : tzfiles.split(" ")) { - alist.add(tzdir.resolve(f).toString()); - } - for (String f : jdk_tzfiles.split(" ")) { - alist.add(jdk_tzdir.resolve(f).toString()); - } - System.out.println("Compiling tz files!"); - Main.main(alist.toArray(new String[alist.size()])); - - ////////////////////////////////// - System.out.println("testing!"); - ZoneInfoFile.ziDir = zidir; - long t0, t1; - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_old = ZoneInfoOld.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("OLD.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_old.length); - Arrays.sort(zids_old); - - t0 = System.nanoTime(); - String[] alias_old = ZoneInfoOld.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("OLD.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_old.length); - Arrays.sort(alias_old); - - t0 = System.currentTimeMillis(); - for (String zid : zids_old) { - ZoneInfoOld.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("OLD.TotalTZ()=%d (ms)%n", t1 - t0); - -/* - t0 = System.nanoTime(); - ZoneId.of("America/Los_Angeles").getRules(); - t1 = System.nanoTime(); - System.out.printf("NEW.ZoneId.of()[1]=%d%n", (t1 - t0) / 1000); -*/ - t0 = System.nanoTime(); - TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_new = TimeZone.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("NEW.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_new.length); - Arrays.sort(zids_new); - - t0 = System.nanoTime(); - String[] alias_new = sun.util.calendar.ZoneInfo.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("NEW.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_new.length); - Arrays.sort(alias_new); - - t0 = System.currentTimeMillis(); - for (String zid : zids_new) { - TimeZone.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("NEW.TotalTZ()=%d (ms)%n", t1 - t0); - - if (!Arrays.equals(zids_old, zids_new)) { - throw new RuntimeException(" FAILED: availableIds don't match"); - } - - if (!Arrays.equals(alias_old, alias_new)) { - throw new RuntimeException(" FAILED: aliases don't match"); - } - - for (String zid : zids_new) { - ZoneInfoOld zi = toZoneInfoOld(TimeZone.getTimeZone(zid)); - ZoneInfoOld ziOLD = (ZoneInfoOld)ZoneInfoOld.getTimeZone(zid); - /* - * Ignoring the failing TimeZones which have negative DST - * save time in IANA tzdata, as javazic/ZoneInfoOld cannot - * handle the negative DST. - * - * These are the zones/rules that employ negative DST in vanguard - * format (as of 2019a), Palestine added in 2022d: - * - * - Rule "Eire" - * - Rule "Morocco" - * - Rule "Namibia" - * - Rule "Palestine" - * - Zone "Europe/Prague" - */ - if (zid.equals("Africa/Casablanca") || // uses "Morocco" rule - zid.equals("Africa/El_Aaiun") || // uses "Morocco" rule - zid.equals("Africa/Windhoek") || // uses "Namibia" rule - zid.equals("Eire") || - zid.equals("Europe/Bratislava") || // link to "Europe/Prague" - zid.equals("Europe/Dublin") || // uses "Eire" rule - zid.equals("Europe/Prague") || - zid.equals("Asia/Gaza") || // uses "Palestine" rule - zid.equals("Asia/Hebron")) { // uses "Palestine" rule - continue; - } - if (! zi.equalsTo(ziOLD)) { - System.out.println(zi.diffsTo(ziOLD)); - throw new RuntimeException(" FAILED: " + zid); - } - } - delete(fZidir); - - // test tzdb version - if (!ver.equals(sun.util.calendar.ZoneInfoFile.getVersion())) { - System.out.printf(" FAILED: ver=%s, expected=%s%n", - sun.util.calendar.ZoneInfoFile.getVersion(), ver); - throw new RuntimeException("Version test failed"); - } - - // test getAvailableIDs(raw); - zids_new = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_new); - zids_old = ZoneInfoOld.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_old); - if (!Arrays.equals(zids_new, zids_old)) { - System.out.println("------------------------"); - System.out.println("NEW.getAvailableIDs(-8:00)"); - for (String zid : zids_new) { - System.out.println(zid); - } - System.out.println("------------------------"); - System.out.println("OLD.getAvailableIDs(-8:00)"); - for (String zid : zids_old) { - System.out.println(zid); - } - throw new RuntimeException(" FAILED: availableIds(offset) don't match"); - } - } - - private static void delete(File f) { - if (f.isDirectory()) { - for (File f0 : f.listFiles()) { - delete(f0); - } - } - f.delete(); - } - - // to access sun.util.calendar.ZoneInfo's private fields - static Class<?> ziClz; - static Field rawOffset; - static Field checksum; - static Field dstSavings; - static Field transitions; - static Field offsets; - static Field simpleTimeZoneParams; - static Field willGMTOffsetChange; - static { - try { - ziClz = Class.forName("sun.util.calendar.ZoneInfo"); - rawOffset = ziClz.getDeclaredField("rawOffset"); - checksum = ziClz.getDeclaredField("checksum"); - dstSavings = ziClz.getDeclaredField("dstSavings"); - transitions = ziClz.getDeclaredField("transitions"); - offsets = ziClz.getDeclaredField("offsets"); - simpleTimeZoneParams = ziClz.getDeclaredField("simpleTimeZoneParams"); - willGMTOffsetChange = ziClz.getDeclaredField("willGMTOffsetChange"); - rawOffset.setAccessible(true); - checksum.setAccessible(true); - dstSavings.setAccessible(true); - transitions.setAccessible(true); - offsets.setAccessible(true); - simpleTimeZoneParams.setAccessible(true); - willGMTOffsetChange.setAccessible(true); - } catch (Exception x) { - throw new RuntimeException(x); - } - } - - private static ZoneInfoOld toZoneInfoOld(TimeZone tz) throws Exception { - return new ZoneInfoOld(tz.getID(), - rawOffset.getInt(tz), - dstSavings.getInt(tz), - checksum.getInt(tz), - (long[])transitions.get(tz), - (int[])offsets.get(tz), - (int[])simpleTimeZoneParams.get(tz), - willGMTOffsetChange.getBoolean(tz)); - } - -} diff --git a/test/jdk/sun/util/calendar/zi/Time.java b/test/jdk/sun/util/calendar/zi/Time.java deleted file mode 100644 index 66379d29d28..00000000000 --- a/test/jdk/sun/util/calendar/zi/Time.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.Locale; -import sun.util.calendar.CalendarDate; -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.Gregorian; - -/** - * Time class represents the "AT" field and other time related information. - * - * @since 1.4 - */ -class Time { - - static final Gregorian gcal = CalendarSystem.getGregorianCalendar(); - - // type is wall clock time - private static final int WALL = 1; - - // type is standard time - private static final int STD = 2; - - // type is UTC - private static final int UTC = 3; - - // type of representing time - private int type; - - /** - * Time from the EPOCH in milliseconds - */ - private long time; - - /** - * Current time in milliseconds - */ - private static final long currentTime = System.currentTimeMillis(); - - Time() { - time = 0L; - } - - Time(long time) { - this.time = time; - } - - void setType(int type) { - this.type = type; - } - - long getTime() { - return time; - } - - int getType() { - return type; - } - - static long getCurrentTime() { - return currentTime; - } - - /** - * @return true if the time is represented in wall-clock time. - */ - boolean isWall() { - return type == WALL; - } - - /** - * @return true if the time is represented in standard time. - */ - boolean isSTD() { - return type == STD; - } - - /** - * @return true if the time is represented in UTC time. - */ - boolean isUTC() { - return type == UTC; - } - - /** - * Converts the type to a string that represents the type in the - * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME"). - * @return the converted string or null if the type is undefined. - */ - String getTypeForSimpleTimeZone() { - String stz = "SimpleTimeZone."; - if (isWall()) { - return stz+"WALL_TIME"; - } - else if (isSTD()) { - return stz+"STANDARD_TIME"; - } - else if (isUTC()) { - return stz+"UTC_TIME"; - } - else { - return null; - } - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param save the amount of daylight time in milliseconds - * @param gmtOffset the GMT offset in milliseconds - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int save, - int gmtOffset, Time time) { - long t = time.getTime(); - - if (time.isSTD()) - t = time.getTime() + save; - else if (time.isUTC()) - t = time.getTime() + save + gmtOffset; - - return getLocalTime(year, month, day, t); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, long time) { - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month.value(), day); - long millis = gcal.getTime(date); - return millis + time; - } - - /** - * Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>. - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, int time) { - return getLocalTime(year, month, day, (long)time); - } - - /** - * Equivalent to {@link #getLocalTime(int, Month, RuleDay, int) - * getLocalTime(year, month, day, (int) time)}. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, long time) { - return getLocalTime(year, month, day, (int) time); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int time) { - CalendarDate cdate = gcal.newCalendarDate(null); - int monthValue = month.value(); - - if (day.isLast()) { // e.g., "lastSun" - cdate.setDate(year, monthValue, 1); - cdate.setDayOfMonth(gcal.getMonthLength(cdate)); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else if (day.isLater()) { // e.g., "Sun>=1" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate); - } else if (day.isExact()) { - cdate.setDate(year, monthValue, day.getDay()); - } else if (day.isEarlier()) { // e.g., "Sun<=15" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else { - Main.panic("invalid day type: " + day); - } - return gcal.getTime(cdate) + time; - } - - /** - * Parses the given "AT" field and constructs a Time object. - * @param the "AT" field string - * @return the Time object - */ - static Time parse(String time) { - int sign; - int index = 0; - Time tm; - - if (time.charAt(0) == '-') { - sign = -1; - index++; - } else { - sign = 1; - } - int val = 0; - int num = 0; - int countDelim = 0; - while (index < time.length()) { - char c = time.charAt(index++); - if (c == ':') { - val = val * 60 + num; - countDelim++; - num = 0; - continue; - } - int d = Character.digit(c, 10); - if (d == -1) { - --index; - break; - } - num = num * 10 + d; - } - val = val * 60 + num; - // convert val to second - for (; countDelim < 2; countDelim++) { - val *= 60; - } - tm = new Time((long)val * 1000 * sign); - if (index < time.length()) { - char c = time.charAt(index++); - if (c == 's') { - tm.setType(Time.STD); - } else if (c == 'u' || c == 'g' || c == 'z') { - tm.setType(Time.UTC); - } else if (c == 'w') { - tm.setType(Time.WALL); - } else { - Main.panic("unknown time mode: "+c); - } - } else { - tm.setType(Time.WALL); - } - return tm; - } - - /** - * Converts the given milliseconds string to a "[+-]hh:mm" string. - * @param ms the milliseconds string - */ - static String toGMTFormat(String ms) { - long sec = Long.parseLong(ms) / 1000; - char sign; - if (sec < 0) { - sign = '-'; - sec = -sec; - } else { - sign = '+'; - } - return String.format((Locale)null, "%c%02d:%02d", - sign, sec/3600, (sec%3600)/60); - } - - /** - * Converts the given millisecond value to a string for a - * SimpleTimeZone parameter. - * @param ms the millisecond value - * @return the string in a human readable form - */ - static String toFormedString(int ms) { - StringBuilder s = new StringBuilder(); - boolean minus = false; - - if (ms < 0) { - s.append("-"); - minus = true; - ms = -ms; - } else if (ms == 0) { - return "0"; - } - - int hour = ms / (60 * 60 * 1000); - ms %= (60 * 60 * 1000); - int minute = ms / (60 * 1000); - - if (hour != 0) { - if (minus && minute != 0) { - s.append("("); - } - s.append(Integer.toString(hour) + "*ONE_HOUR"); - } - - if (minute != 0) { - if (hour != 0) { - s.append("+"); - } - s.append(Integer.toString(minute) + "*ONE_MINUTE"); - if (minus && hour != 0) { - s.append(")"); - } - } - - return s.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Timezone.java b/test/jdk/sun/util/calendar/zi/Timezone.java deleted file mode 100644 index d4890e8f58b..00000000000 --- a/test/jdk/sun/util/calendar/zi/Timezone.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Timezone represents all information of a single point of time to - * generate its time zone database. - * - * @since 1.4 - */ -class Timezone { - /** - * zone name of this time zone - */ - private String name; - - /** - * transition time values in UTC (millisecond) - */ - private List<Long> transitions; - - /** - * All offset values in millisecond - * @see sun.util.calendar.ZoneInfo - */ - private List<Integer> offsets; - - /** - * Indices of GMT offset values (both raw and raw+saving) - * at transitions - */ - private List<Integer> gmtOffsets; - - /** - * Indices of regular or "direct" saving time values - * at transitions - */ - private List<Integer> dstOffsets; - - /** - * Zone records of this time zone - */ - private List<ZoneRec> usedZoneRecs; - - /** - * Rule records referred to by this time zone - */ - private List<RuleRec> usedRuleRecs; - - /** - * Type of DST rules in this time zone - */ - private int dstType; - static final int UNDEF_DST = 0; // DST type not set yet - static final int NO_DST = 1; // never observed DST - static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only) - static final int X_DST = 3; // used to observe DST - static final int DST = 4; // observing DST regularly - - /** - * Raw GMT offset of this time zone in the last rule - */ - private int rawOffset; - - /** - * The CRC32 value of the transitions data - */ - private int crc32; - - /** - * The last ZoneRec - */ - private ZoneRec lastZoneRec; - - /** - * The last DST rules. lastRules[0] is the DST start - * rule. lastRules[1] is the DST end rules. - */ - private List<RuleRec> lastRules; - - /** - * The amount of DST saving value (millisecond) in the last DST - * rule. - */ - private int lastSaving; - - /** - * true if the raw offset will change in the future time. - */ - private boolean willRawOffsetChange = false; - - - /** - * Constracts a Timezone object with the given zone name. - * @param name the zone name - */ - Timezone(String name) { - this.name = name; - } - - /** - * @return the number of transitions - */ - int getNTransitions() { - if (transitions == null) { - return 0; - } - return transitions.size(); - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Returns the list of all rule records that have been referred to - * by this time zone. - * @return the rule records list - */ - List<RuleRec> getRules() { - return usedRuleRecs; - } - - /** - * Returns the list of all zone records that have been referred to - * by this time zone. - * @return the zone records list - */ - List<ZoneRec> getZones() { - return usedZoneRecs; - } - - /** - * @return the transition table (list) - */ - List<Long> getTransitions() { - return transitions; - } - - /** - * @return the offsets list - */ - List<Integer> getOffsets() { - return offsets; - } - - /** - * @return the DST saving offsets list - */ - List<Integer> getDstOffsets() { - return dstOffsets; - } - - /** - * @return the GMT offsets list - */ - List<Integer> getGmtOffsets() { - return gmtOffsets; - } - - /** - * @return the checksum (crc32) value of the trasition table - */ - int getCRC32() { - return crc32; - } - - /** - * @return true if the GMT offset of this time zone would change - * after the time zone database has been generated, false, otherwise. - */ - boolean willGMTOffsetChange() { - return willRawOffsetChange; - } - - /** - * @return the last known GMT offset value in milliseconds - */ - int getRawOffset() { - return rawOffset; - } - - /** - * Sets time zone's GMT offset to <code>offset</code>. - * @param offset the GMT offset value in milliseconds - */ - void setRawOffset(int offset) { - rawOffset = offset; - } - - /** - * Sets time zone's GMT offset value to <code>offset</code>. If - * <code>startTime</code> is future time, then the {@link - * #willRawOffsetChange} value is set to true. - * @param offset the GMT offset value in milliseconds - * @param startTime the UTC time at which the GMT offset is in effective - */ - void setRawOffset(int offset, long startTime) { - // if this rawOffset is for the future time, let the run-time - // look for the current GMT offset. - if (startTime > Time.getCurrentTime()) { - willRawOffsetChange = true; - } - setRawOffset(offset); - } - - /** - * Adds the specified transition information to the end of the transition table. - * @param time the UTC time at which this transition happens - * @param offset the total amount of the offset from GMT in milliseconds - * @param dstOffset the amount of time in milliseconds saved at this transition - */ - void addTransition(long time, int offset, int dstOffset) { - if (transitions == null) { - transitions = new ArrayList<Long>(); - offsets = new ArrayList<Integer>(); - dstOffsets = new ArrayList<Integer>(); - } - transitions.add(time); - offsets.add(offset); - dstOffsets.add(dstOffset); - } - - /** - * Sets the type of historical daylight saving time - * observation. For example, China used to observed daylight - * saving time, but it no longer does. Then, X_DST is set to the - * China time zone. - * @param type the type of daylight saving time - */ - void setDSTType(int type) { - dstType = type; - } - - /** - * @return the type of historical daylight saving time - * observation. - */ - int getDSTType() { - return dstType; - } - - /** - * Adds the specified zone record to the zone records list. - * @param rec the zone record - */ - void addUsedRec(ZoneRec rec) { - if (usedZoneRecs == null) { - usedZoneRecs = new ArrayList<ZoneRec>(); - } - usedZoneRecs.add(rec); - } - - /** - * Adds the specified rule record to the rule records list. - * @param rec the rule record - */ - void addUsedRec(RuleRec rec) { - if (usedRuleRecs == null) { - usedRuleRecs = new ArrayList<RuleRec>(); - } - // if the last used rec is the same as the given rec, avoid - // putting the same rule. - int n = usedRuleRecs.size(); - for (int i = 0; i < n; i++) { - if (usedRuleRecs.get(i).equals(rec)) { - return; - } - } - usedRuleRecs.add(rec); - } - - /** - * Sets the last zone record for this time zone. - * @param the last zone record - */ - void setLastZoneRec(ZoneRec zrec) { - lastZoneRec = zrec; - } - - /** - * @return the last zone record for this time zone. - */ - ZoneRec getLastZoneRec() { - return lastZoneRec; - } - - /** - * Sets the last rule records for this time zone. Those are used - * for generating SimpleTimeZone parameters. - * @param rules the last rule records - */ - void setLastRules(List<RuleRec> rules) { - int n = rules.size(); - if (n > 0) { - lastRules = rules; - RuleRec rec = rules.get(0); - int offset = rec.getSave(); - if (offset > 0) { - setLastDSTSaving(offset); - } else { - System.err.println("\t No DST starting rule in the last rules."); - } - } - } - - /** - * @return the last rule records for this time zone. - */ - List<RuleRec> getLastRules() { - return lastRules; - } - - /** - * Sets the last daylight saving amount. - * @param the daylight saving amount - */ - void setLastDSTSaving(int offset) { - lastSaving = offset; - } - - /** - * @return the last daylight saving amount. - */ - int getLastDSTSaving() { - return lastSaving; - } - - /** - * Calculates the CRC32 value from the transition table and sets - * the value to <code>crc32</code>. - */ - void checksum() { - if (transitions == null) { - crc32 = 0; - return; - } - Checksum sum = new Checksum(); - for (int i = 0; i < transitions.size(); i++) { - int offset = offsets.get(i); - // adjust back to make the transition in local time - sum.update(transitions.get(i) + offset); - sum.update(offset); - sum.update(dstOffsets.get(i)); - } - crc32 = (int)sum.getValue(); - } - - /** - * Removes unnecessary transitions for Java time zone support. - */ - void optimize() { - // if there is only one offset, delete all transitions. This - // could happen if only time zone abbreviations changed. - if (gmtOffsets.size() == 1) { - transitions = null; - usedRuleRecs = null; - setDSTType(NO_DST); - return; - } - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (transitions.get(i) == transitions.get(i+1)) { - transitions.remove(i); - offsets.remove(i); - dstOffsets.remove(i); - i--; - } - } - - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (offsets.get(i) == offsets.get(i+1) - && dstOffsets.get(i) == dstOffsets.get(i+1)) { - transitions.remove(i+1); - offsets.remove(i+1); - dstOffsets.remove(i+1); - i--; - } - } - } - - /** - * Stores the specified offset value from GMT in the GMT offsets - * table and returns its index. The offset value includes the base - * GMT offset and any additional daylight saving if applicable. If - * the same value as the specified offset is already in the table, - * its index is returned. - * @param offset the offset value in milliseconds - * @return the index to the offset value in the GMT offsets table. - */ - int getOffsetIndex(int offset) { - return getOffsetIndex(offset, 0); - } - - /** - * Stores the specified daylight saving value in the GMT offsets - * table and returns its index. If the same value as the specified - * offset is already in the table, its index is returned. If 0 is - * specified, it's not stored in the table and -1 is returned. - * @param offset the offset value in milliseconds - * @return the index to the specified offset value in the GMT - * offsets table, or -1 if 0 is specified. - */ - int getDstOffsetIndex(int offset) { - if (offset == 0) { - return -1; - } - return getOffsetIndex(offset, 1); - } - - private int getOffsetIndex(int offset, int index) { - if (gmtOffsets == null) { - gmtOffsets = new ArrayList<Integer>(); - } - for (int i = index; i < gmtOffsets.size(); i++) { - if (offset == gmtOffsets.get(i)) { - return i; - } - } - if (gmtOffsets.size() < index) { - gmtOffsets.add(0); - } - gmtOffsets.add(offset); - return gmtOffsets.size() - 1; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java b/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java deleted file mode 100644 index 7e8ce636449..00000000000 --- a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, 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. - */ - -import java.util.Map; -import java.util.HashMap; - -class TzIDOldMapping { - static final Map<String, String> MAP = new HashMap<String, String>(); - static { - String[][] oldmap = { - { "ACT", "Australia/Darwin" }, - { "AET", "Australia/Sydney" }, - { "AGT", "America/Argentina/Buenos_Aires" }, - { "ART", "Africa/Cairo" }, - { "AST", "America/Anchorage" }, - { "BET", "America/Sao_Paulo" }, - { "BST", "Asia/Dhaka" }, - { "CAT", "Africa/Harare" }, - { "CNT", "America/St_Johns" }, - { "CST", "America/Chicago" }, - { "CTT", "Asia/Shanghai" }, - { "EAT", "Africa/Addis_Ababa" }, - { "ECT", "Europe/Paris" }, - { "EST", "America/New_York" }, - { "HST", "Pacific/Honolulu" }, - { "IET", "America/Indianapolis" }, - { "IST", "Asia/Calcutta" }, - { "JST", "Asia/Tokyo" }, - { "MIT", "Pacific/Apia" }, - { "MST", "America/Denver" }, - { "NET", "Asia/Yerevan" }, - { "NST", "Pacific/Auckland" }, - { "PLT", "Asia/Karachi" }, - { "PNT", "America/Phoenix" }, - { "PRT", "America/Puerto_Rico" }, - { "PST", "America/Los_Angeles" }, - { "SST", "Pacific/Guadalcanal" }, - { "VST", "Asia/Saigon" }, - }; - for (String[] pair : oldmap) { - MAP.put(pair[0], pair[1]); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zone.java b/test/jdk/sun/util/calendar/zi/Zone.java deleted file mode 100644 index f1adbf6f938..00000000000 --- a/test/jdk/sun/util/calendar/zi/Zone.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * Zone holds information corresponding to a "Zone" part of a time - * zone definition file. - * - * @since 1.4 - */ -class Zone { - // zone name (e.g., "America/Los_Angeles") - private String name; - - // zone records - private List<ZoneRec> list; - - // target zone names for this compilation - private static Set<String> targetZones; - - /** - * Constructs a Zone with the specified zone name. - * @param name the zone name - */ - Zone(String name) { - this.name = name; - list = new ArrayList<ZoneRec>(); - } - - /** - * Reads time zone names to be generated, called "target zone - * name", from the specified text file and creats an internal hash - * table to keep those names. It's assumed that one text line - * contains a zone name or comments if it starts with - * '#'. Comments can't follow a zone name in a single line. - * @param fileName the text file name - */ - static void readZoneNames(String fileName) { - if (fileName == null) { - return; - } - BufferedReader in = null; - try { - FileReader fr = new FileReader(fileName); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - Main.panic("can't open file: " + fileName); - } - targetZones = new HashSet<String>(); - String line; - - try { - while ((line = in.readLine()) != null) { - line = line.trim(); - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - if (!targetZones.add(line)) { - Main.warning("duplicated target zone name: " + line); - } - } - in.close(); - } catch (IOException e) { - Main.panic("IO error: "+e.getMessage()); - } - } - - /** - * Determines whether the specified zone is one of the target zones. - * If no target zones are specified, this method always returns - * true for any zone name. - * @param zoneName the zone name - * @return true if the specified name is a target zone. - */ - static boolean isTargetZone(String zoneName) { - if (targetZones == null) { - return true; - } - return targetZones.contains(zoneName); - } - - /** - * Forces to add "MET" to the target zone table. This is because - * there is a conflict between Java zone name "WET" and Olson zone - * name. - */ - static void addMET() { - if (targetZones != null) { - targetZones.add("MET"); - } - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Adds the specified zone record to the zone record list. - */ - void add(ZoneRec rec) { - list.add(rec); - } - - /** - * @param index the index at which the zone record in the list is returned. - * @return the zone record specified by the index. - */ - ZoneRec get(int index) { - return list.get(index); - } - - /** - * @return the size of the zone record list - */ - int size() { - return list.size(); - } - - /** - * Resolves the reference to a rule in each zone record. - * @param zi the Zoneinfo object with which the rule reference is - * resolved. - */ - void resolve(Zoneinfo zi) { - for (int i = 0; i < list.size(); i++) { - ZoneRec rec = list.get(i); - rec.resolve(zi); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java b/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java deleted file mode 100644 index 3134a517979..00000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.ref.SoftReference; -import java.nio.file.FileSystems; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import sun.util.calendar.*; - -/** - * <code>ZoneInfoFile</code> reads Zone information files in the - * &lt;java.home&gt;/lib/zi directory and provides time zone - * information in the form of a {@link ZoneInfo} object. Also, it - * reads the ZoneInfoMappings file to obtain time zone IDs information - * that is used by the {@link ZoneInfo} class. The directory layout - * and data file formats are as follows. - * - * <p><strong>Directory layout</strong><p> - * - * All zone data files and ZoneInfoMappings are put under the - * &lt;java.home&gt;/lib/zi directory. A path name for a given time - * zone ID is a concatenation of &lt;java.home&gt;/lib/zi/ and the - * time zone ID. (The file separator is replaced with the platform - * dependent value. e.g., '\' for Win32.) An example layout will look - * like as follows. - * <blockquote> - * <pre> - * &lt;java.home&gt;/lib/zi/Africa/Addis_Ababa - * /Africa/Dakar - * /America/Los_Angeles - * /Asia/Singapore - * /EET - * /Europe/Oslo - * /GMT - * /Pacific/Galapagos - * ... - * /ZoneInfoMappings - * </pre> - * </blockquote> - * - * A zone data file has specific information of each zone. - * <code>ZoneInfoMappings</code> has global information of zone IDs so - * that the information can be obtained without instantiating all time - * zones. - * - * <p><strong>File format</strong><p> - * - * Two binary-file formats based on a simple Tag-Length-Value format are used - * to describe TimeZone information. The generic format of a data file is: - * <blockquote> - * <pre> - * DataFile { - * u1 magic[7]; - * u1 version; - * data_item data[]; - * } - * </pre> - * </blockquote> - * where <code>magic</code> is a magic number identifying a file - * format, <code>version</code> is the format version number, and - * <code>data</code> is one or more <code>data_item</code>s. The - * <code>data_item</code> structure is: - * <blockquote> - * <pre> - * data_item { - * u1 tag; - * u2 length; - * u1 value[length]; - * } - * </pre> - * </blockquote> - * where <code>tag</code> indicates the data type of the item, - * <code>length</code> is a byte count of the following - * <code>value</code> that is the content of item data. - * <p> - * All data is stored in the big-endian order. There is no boundary - * alignment between date items. - * - * <p><strong>1. ZoneInfo data file</strong><p> - * - * Each ZoneInfo data file consists of the following members. - * <br> - * <blockquote> - * <pre> - * ZoneInfoDataFile { - * u1 magic[7]; - * u1 version; - * SET OF<sup>1</sup> { - * transition transitions<sup>2</sup>; - * offset_table offsets<sup>2</sup>; - * simpletimezone stzparams<sup>2</sup>; - * raw_offset rawoffset; - * dstsaving dst; - * checksum crc32; - * gmtoffsetwillchange gmtflag<sup>2</sup>; - * } - * } - * 1: an unordered collection of zero or one occurrences of each item - * 2: optional item - * </pre> - * </blockquote> - * <code>magic</code> is a byte-string constant identifying the - * ZoneInfo data file. This field must be <code>"javazi&#92;0"</code> - * defined as {@link #JAVAZI_LABEL}. - * <p> - * <code>version</code> is the version number of the file format. This - * will be used for compatibility check. This field must be - * <code>0x01</code> in this version. - * <p> - * <code>transition</code>, <code>offset_table</code> and - * <code>simpletimezone</code> have information of time transition - * from the past to the future. Therefore, these structures don't - * exist if the zone didn't change zone names and haven't applied DST in - * the past, and haven't planned to apply it. (e.g. Asia/Tokyo zone) - * <p> - * <code>raw_offset</code>, <code>dstsaving</code> and <code>checksum</code> - * exist in every zoneinfo file. They are used by TimeZone.class indirectly. - * - * <p><strong>1.1 <code>transition</code> structure</strong><p><a name="transition"></a> - * <blockquote> - * <pre> - * transition { - * u1 tag; // 0x04 : constant - * u2 length; // byte length of whole values - * s8 value[length/8]; // transitions in `long' - * } - * </pre> - * </blockquote> - * See {@link ZoneInfo#transitions ZoneInfo.transitions} about the value. - * - * <p><strong>1.2 <code>offset_table</code> structure</strong><p> - * <blockquote> - * <pre> - * offset_table { - * u1 tag; // 0x05 : constant - * u2 length; // byte length of whole values - * s4 value[length/4]; // offset values in `int' - * } - * </pre> - * </blockquote> - * - * <p><strong>1.3 <code>simpletimezone</code> structure</strong><p> - * See {@link ZoneInfo#simpleTimeZoneParams ZoneInfo.simpleTimeZoneParams} - * about the value. - * <blockquote> - * <pre> - * simpletimezone { - * u1 tag; // 0x06 : constant - * u2 length; // byte length of whole values - * s4 value[length/4]; // SimpleTimeZone parameters - * } - * </pre> - * </blockquote> - * See {@link ZoneInfo#offsets ZoneInfo.offsets} about the value. - * - * <p><strong>1.4 <code>raw_offset</code> structure</strong><p> - * <blockquote> - * <pre> - * raw_offset { - * u1 tag; // 0x01 : constant - * u2 length; // must be 4. - * s4 value; // raw GMT offset [millisecond] - * } - * </pre> - * </blockquote> - * See {@link ZoneInfo#rawOffset ZoneInfo.rawOffset} about the value. - * - * <p><strong>1.5 <code>dstsaving</code> structure</strong><p> - * Value has dstSaving in seconds. - * <blockquote> - * <pre> - * dstsaving { - * u1 tag; // 0x02 : constant - * u2 length; // must be 2. - * s2 value; // DST save value [second] - * } - * </pre> - * </blockquote> - * See {@link ZoneInfo#dstSavings ZoneInfo.dstSavings} about value. - * - * <p><strong>1.6 <code>checksum</code> structure</strong><p> - * <blockquote> - * <pre> - * checksum { - * u1 tag; // 0x03 : constant - * u2 length; // must be 4. - * s4 value; // CRC32 value of transitions - * } - * </pre> - * </blockquote> - * See {@link ZoneInfo#checksum ZoneInfo.checksum}. - * - * <p><strong>1.7 <code>gmtoffsetwillchange</code> structure</strong><p> - * This record has a flag value for {@link ZoneInfo#rawOffsetWillChange}. - * If this record is not present in a zoneinfo file, 0 is assumed for - * the value. - * <blockquote> - * <pre> - * gmtoffsetwillchange { - * u1 tag; // 0x07 : constant - * u2 length; // must be 1. - * u1 value; // 1: if the GMT raw offset will change - * // in the future, 0, otherwise. - * } - * </pre> - * </blockquote> - * - * - * <p><strong>2. ZoneInfoMappings file</strong><p> - * - * The ZoneInfoMappings file consists of the following members. - * <br> - * <blockquote> - * <pre> - * ZoneInfoMappings { - * u1 magic[7]; - * u1 version; - * SET OF { - * versionName version; - * zone_id_table zoneIDs; - * raw_offset_table rawoffsets; - * raw_offset_index_table rawoffsetindices; - * alias_table aliases; - * excluded_list excludedList; - * } - * } - * </pre> - * </blockquote> - * - * <code>magic</code> is a byte-string constant which has the file type. - * This field must be <code>"javazm&#92;0"</code> defined as {@link #JAVAZM_LABEL}. - * <p> - * <code>version</code> is the version number of this file - * format. This will be used for compatibility check. This field must - * be <code>0x01</code> in this version. - * <p> - * <code>versionName</code> shows which version of Olson's data has been used - * to generate this ZoneInfoMappings. (e.g. <code>tzdata2000g</code>) <br> - * This field is for trouble-shooting and isn't usually used in runtime. - * <p> - * <code>zone_id_table</code>, <code>raw_offset_index_table</code> and - * <code>alias_table</code> are general information of supported - * zones. - * - * <p><strong>2.1 <code>zone_id_table</code> structure</strong><p> - * The list of zone IDs included in the zi database. The list does - * <em>not</em> include zone IDs, if any, listed in excludedList. - * <br> - * <blockquote> - * <pre> - * zone_id_table { - * u1 tag; // 0x40 : constant - * u2 length; // byte length of whole values - * u2 zone_id_count; - * zone_id value[zone_id_count]; - * } - * - * zone_id { - * u1 byte_length; // byte length of id - * u1 id[byte_length]; // zone name string - * } - * </pre> - * </blockquote> - * - * <p><strong>2.2 <code>raw_offset_table</code> structure</strong><p> - * <br> - * <blockquote> - * <pre> - * raw_offset_table { - * u1 tag; // 0x41 : constant - * u2 length; // byte length of whole values - * s4 value[length/4]; // raw GMT offset in milliseconds - * } - * </pre> - * </blockquote> - * - * <p><strong>2.3 <code>raw_offset_index_table</code> structure</strong><p> - * <br> - * <blockquote> - * <pre> - * raw_offset_index_table { - * u1 tag; // 0x42 : constant - * u2 length; // byte length of whole values - * u1 value[length]; - * } - * </pre> - * </blockquote> - * - * <p><strong>2.4 <code>alias_table</code> structure</strong><p> - * <br> - * <blockquote> - * <pre> - * alias_table { - * u1 tag; // 0x43 : constant - * u2 length; // byte length of whole values - * u2 nentries; // number of id-pairs - * id_pair value[nentries]; - * } - * - * id_pair { - * zone_id aliasname; - * zone_id ID; - * } - * </pre> - * </blockquote> - * - * <p><strong>2.5 <code>versionName</code> structure</strong><p> - * <br> - * <blockquote> - * <pre> - * versionName { - * u1 tag; // 0x44 : constant - * u2 length; // byte length of whole values - * u1 value[length]; - * } - * </pre> - * </blockquote> - * - * <p><strong>2.6 <code>excludeList</code> structure</strong><p> - * The list of zone IDs whose zones will change their GMT offsets - * (a.k.a. raw offsets) some time in the future. Those IDs must be - * added to the list of zone IDs for getAvailableIDs(). Also they must - * be examined for getAvailableIDs(int) to determine the - * <em>current</em> GMT offsets. - * <br> - * <blockquote> - * <pre> - * excluded_list { - * u1 tag; // 0x45 : constant - * u2 length; // byte length of whole values - * u2 nentries; // number of zone_ids - * zone_id value[nentries]; // excluded zone IDs - * } - * </pre> - * </blockquote> - * - * @since 1.4 - */ - -public class ZoneInfoFile { - - /** - * The magic number for the ZoneInfo data file format. - */ - public static final byte[] JAVAZI_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'i', (byte)'\0' - }; - private static final int JAVAZI_LABEL_LENGTH = JAVAZI_LABEL.length; - - /** - * The ZoneInfo data file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZI_VERSION = 0x01; - - /** - * Raw offset data item tag. - */ - public static final byte TAG_RawOffset = 1; - - /** - * Known last Daylight Saving Time save value data item tag. - */ - public static final byte TAG_LastDSTSaving = 2; - - /** - * Checksum data item tag. - */ - public static final byte TAG_CRC32 = 3; - - /** - * Transition data item tag. - */ - public static final byte TAG_Transition = 4; - - /** - * Offset table data item tag. - */ - public static final byte TAG_Offset = 5; - - /** - * SimpleTimeZone parameters data item tag. - */ - public static final byte TAG_SimpleTimeZone = 6; - - /** - * Raw GMT offset will change in the future. - */ - public static final byte TAG_GMTOffsetWillChange = 7; - - - /** - * The ZoneInfoMappings file name. - */ - public static final String JAVAZM_FILE_NAME = "ZoneInfoMappings"; - - /** - * The magic number for the ZoneInfoMappings file format. - */ - public static final byte[] JAVAZM_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'m', (byte)'\0' - }; - private static final int JAVAZM_LABEL_LENGTH = JAVAZM_LABEL.length; - - /** - * The ZoneInfoMappings file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZM_VERSION = 0x01; - - /** - * Time zone IDs data item tag. - */ - public static final byte TAG_ZoneIDs = 64; - - /** - * Raw GMT offsets table data item tag. - */ - public static final byte TAG_RawOffsets = 65; - - /** - * Indices to the raw GMT offset table data item tag. - */ - public static final byte TAG_RawOffsetIndices = 66; - - /** - * Time zone aliases table data item tag. - */ - public static final byte TAG_ZoneAliases = 67; - - /** - * Olson's public zone information version tag. - */ - public static final byte TAG_TZDataVersion = 68; - - /** - * Excluded zones item tag. (Added in Mustang) - */ - public static final byte TAG_ExcludedZones = 69; - - private static Map<String, ZoneInfoOld> zoneInfoObjects = null; - - private static final ZoneInfoOld GMT = new ZoneInfoOld("GMT", 0); - - static String ziDir; - - /** - * Converts the given time zone ID to a platform dependent path - * name. For example, "America/Los_Angeles" is converted to - * "America\Los_Angeles" on Win32. - * @return a modified ID replacing '/' with {@link - * java.io.File#separatorChar File.separatorChar} if needed. - */ - public static String getFileName(String ID) { - if (File.separatorChar == '/') { - return ID; - } - return ID.replace('/', File.separatorChar); - } - - /** - * Gets a ZoneInfo with the given GMT offset. The object - * has its ID in the format of GMT{+|-}hh:mm. - * - * @param originalId the given custom id (before normalized such as "GMT+9") - * @param gmtOffset GMT offset <em>in milliseconds</em> - * @return a ZoneInfo constructed with the given GMT offset - */ - public static ZoneInfoOld getCustomTimeZone(String originalId, int gmtOffset) { - String id = toCustomID(gmtOffset); - - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - zi = new ZoneInfoOld(id, gmtOffset); - zi = addToCache(id, zi); - if (!id.equals(originalId)) { - zi = addToCache(originalId, zi); - } - } - return (ZoneInfoOld) zi.clone(); - } - - public static String toCustomID(int gmtOffset) { - char sign; - int offset = gmtOffset / 60000; - - if (offset >= 0) { - sign = '+'; - } else { - sign = '-'; - offset = -offset; - } - int hh = offset / 60; - int mm = offset % 60; - - char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' }; - if (hh >= 10) { - buf[4] += hh / 10; - } - buf[5] += hh % 10; - if (mm != 0) { - buf[7] += mm / 10; - buf[8] += mm % 10; - } - return new String(buf); - } - - /** - * @return a ZoneInfo instance created for the specified id, or - * null if there is no time zone data file found for the specified - * id. - */ - public static ZoneInfoOld getZoneInfoOld(String id) { - //treat GMT zone as special - if ("GMT".equals(id)) - return (ZoneInfoOld) GMT.clone(); - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - Map<String, String> aliases = ZoneInfoOld.getCachedAliasTable(); - if (aliases != null && aliases.get(id) != null) { - return null; - } - zi = createZoneInfoOld(id); - if (zi == null) { - return null; - } - zi = addToCache(id, zi); - } - return (ZoneInfoOld) zi.clone(); - } - - synchronized static ZoneInfoOld getFromCache(String id) { - if (zoneInfoObjects == null) { - return null; - } - return zoneInfoObjects.get(id); - } - - synchronized static ZoneInfoOld addToCache(String id, ZoneInfoOld zi) { - if (zoneInfoObjects == null) { - zoneInfoObjects = new HashMap<>(); - } else { - ZoneInfoOld zone = zoneInfoObjects.get(id); - if (zone != null) { - return zone; - } - } - zoneInfoObjects.put(id, zi); - return zi; - } - - private static ZoneInfoOld createZoneInfoOld(String id) { - byte[] buf = readZoneInfoFile(getFileName(id)); - if (buf == null) { - return null; - } - - int index = 0; - int filesize = buf.length; - int rawOffset = 0; - int dstSavings = 0; - int checksum = 0; - boolean willGMTOffsetChange = false; - long[] transitions = null; - int[] offsets = null; - int[] simpleTimeZoneParams = null; - - try { - for (index = 0; index < JAVAZI_LABEL.length; index++) { - if (buf[index] != JAVAZI_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + id); - return null; - } - } - if (buf[index++] > JAVAZI_VERSION) { - System.err.println("ZoneInfo: incompatible version (" - + buf[index - 1] + "): " + id); - return null; - } - - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - if (filesize < index+len) { - break; - } - - switch (tag) { - case TAG_CRC32: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - checksum = val; - } - break; - - case TAG_LastDSTSaving: - { - short val = (short)(buf[index++] & 0xff); - val = (short)((val << 8) + (buf[index++] & 0xff)); - dstSavings = val * 1000; - } - break; - - case TAG_RawOffset: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - rawOffset = val; - } - break; - - case TAG_Transition: - { - int n = len / 8; - transitions = new long[n]; - for (int i = 0; i < n; i ++) { - long val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - transitions[i] = val; - } - } - break; - - case TAG_Offset: - { - int n = len / 4; - offsets = new int[n]; - for (int i = 0; i < n; i ++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break; - - case TAG_SimpleTimeZone: - { - if (len != 32 && len != 40) { - System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size"); - return null; - } - int n = len / 4; - simpleTimeZoneParams = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - simpleTimeZoneParams[i] = val; - } - } - break; - - case TAG_GMTOffsetWillChange: - { - if (len != 1) { - System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange"); - } - willGMTOffsetChange = buf[index++] == 1; - } - break; - - default: - System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored."); - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfo: corrupted zoneinfo file: " + id); - return null; - } - - if (index != filesize) { - System.err.println("ZoneInfo: wrong file size: " + id); - return null; - } - - return new ZoneInfoOld(id, rawOffset, dstSavings, checksum, - transitions, offsets, simpleTimeZoneParams, - willGMTOffsetChange); - } - - private volatile static SoftReference<List<String>> zoneIDs = null; - - static List<String> getZoneIDs() { - List<String> ids = null; - SoftReference<List<String>> cache = zoneIDs; - if (cache != null) { - ids = cache.get(); - if (ids != null) { - return ids; - } - } - byte[] buf = null; - buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneIDs: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - ids = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - ids.add(new String(buf, index, m, "UTF-8")); - index += m; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - zoneIDs = new SoftReference<>(ids); - return ids; - } - - /** - * @return an alias table in HashMap where a key is an alias ID - * (e.g., "PST") and its value is a real time zone ID (e.g., - * "America/Los_Angeles"). - */ - static Map<String, String> getZoneAliases() { - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - Map<String, String> aliases = null; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneAliases: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - aliases = new HashMap<>(n); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - m = buf[index++]; - String realName = new String(buf, index, m, "UTF-8"); - index += m; - aliases.put(name, realName); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - return aliases; - } - - private volatile static SoftReference<List<String>> excludedIDs = null; - private volatile static boolean hasNoExcludeList = false; - - /** - * @return a List of zone IDs for zones that will change their GMT - * offsets in some future time. - * - * @since 1.6 - */ - static List<String> getExcludedZones() { - if (hasNoExcludeList) { - return null; - } - - List<String> excludeList = null; - - SoftReference<List<String>> cache = excludedIDs; - if (cache != null) { - excludeList = cache.get(); - if (excludeList != null) { - return excludeList; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ExcludedZones: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - excludeList = new ArrayList<>(); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - excludeList.add(name); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - - if (excludeList != null) { - excludedIDs = new SoftReference<>(excludeList); - } else { - hasNoExcludeList = true; - } - return excludeList; - } - - private volatile static SoftReference<byte[]> rawOffsetIndices = null; - - static byte[] getRawOffsetIndices() { - byte[] indices = null; - - SoftReference<byte[]> cache = rawOffsetIndices; - if (cache != null) { - indices = cache.get(); - if (indices != null) { - return indices; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsetIndices: - { - indices = new byte[len]; - for (int i = 0; i < len; i++) { - indices[i] = buf[index++]; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsetIndices = new SoftReference<>(indices); - return indices; - } - - private volatile static SoftReference<int[]> rawOffsets = null; - - static int[] getRawOffsets() { - int[] offsets = null; - - SoftReference<int[]> cache = rawOffsets; - if (cache != null) { - offsets = cache.get(); - if (offsets != null) { - return offsets; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsets: - { - int n = len/4; - offsets = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsets = new SoftReference<>(offsets); - return offsets; - } - - private volatile static SoftReference<byte[]> zoneInfoMappings = null; - - private static byte[] getZoneInfoOldMappings() { - byte[] data; - SoftReference<byte[]> cache = zoneInfoMappings; - if (cache != null) { - data = cache.get(); - if (data != null) { - return data; - } - } - data = readZoneInfoFile(JAVAZM_FILE_NAME); - if (data == null) { - throw new RuntimeException("ZoneInfoOldMapping " + - JAVAZM_FILE_NAME + " either doesn't exist or doesn't have data"); - } - - int index; - for (index = 0; index < JAVAZM_LABEL.length; index++) { - if (data[index] != JAVAZM_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + JAVAZM_FILE_NAME); - return null; - } - } - if (data[index++] > JAVAZM_VERSION) { - System.err.println("ZoneInfoOld: incompatible version (" - + data[index - 1] + "): " + JAVAZM_FILE_NAME); - return null; - } - - zoneInfoMappings = new SoftReference<>(data); - return data; - } - - /** - * Reads the specified file under &lt;java.home&gt;/lib/zi into a buffer. - * @return the buffer, or null if any I/O error occurred. - */ - private static byte[] readZoneInfoFile(final String fileName) { - if (fileName.indexOf("..") >= 0) { - return null; - } - byte[] buffer = null; - File file = new File(ziDir, fileName); - try { - int filesize = (int)file.length(); - if (filesize > 0) { - FileInputStream fis = new FileInputStream(file); - buffer = new byte[filesize]; - try { - if (fis.read(buffer) != filesize) { - throw new IOException("read error on " + fileName); - } - } finally { - fis.close(); - } - } - } catch (Exception ex) { - if (!(ex instanceof FileNotFoundException) || JAVAZM_FILE_NAME.equals(fileName)) { - System.err.println("ZoneInfoOld: " + ex.getMessage()); - } - } - return buffer; - } - - private ZoneInfoFile() { - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java b/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java deleted file mode 100644 index 300b7f13ddd..00000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * 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 - * 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.ObjectInputStream; -import java.lang.ref.SoftReference; -import java.time.ZoneOffset; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.SimpleTimeZone; -import java.util.TimeZone; - -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.CalendarDate; - -/** - * <code>ZoneInfoOld</code> is an implementation subclass of {@link - * java.util.TimeZone TimeZone} that represents GMT offsets and - * daylight saving time transitions of a time zone. - * <p> - * The daylight saving time transitions are described in the {@link - * #transitions transitions} table consisting of a chronological - * sequence of transitions of GMT offset and/or daylight saving time - * changes. Since all transitions are represented in UTC, in theory, - * <code>ZoneInfoOld</code> can be used with any calendar systems except - * for the {@link #getOffset(int,int,int,int,int,int) getOffset} - * method that takes Gregorian calendar date fields. - * <p> - * This table covers transitions from 1900 until 2100 (as of version - * 23), Before 1900, it assumes that there was no daylight saving - * time and the <code>getOffset</code> methods always return the - * {@link #getRawOffset} value. No Local Mean Time is supported. If a - * specified date is beyond the transition table and this time zone is - * supposed to observe daylight saving time in 2100, it delegates - * operations to a {@link java.util.SimpleTimeZone SimpleTimeZone} - * object created using the daylight saving time schedule as of 2100. - * <p> - * The date items, transitions, GMT offset(s), etc. are read from a database - * file. See {@link ZoneInfoFile} for details. - * @see java.util.SimpleTimeZone - * @since 1.4 - */ - -public class ZoneInfoOld extends TimeZone { - - // The constants assume no leap seconds support. - static final int SECOND_IN_MILLIS = 1000; - static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; - static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60; - static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24; - - private static final int UTC_TIME = 0; - private static final int STANDARD_TIME = 1; - private static final int WALL_TIME = 2; - - private static final long OFFSET_MASK = 0x0fL; - private static final long DST_MASK = 0xf0L; - private static final int DST_NSHIFT = 4; - // this bit field is reserved for abbreviation support - private static final long ABBR_MASK = 0xf00L; - private static final int TRANSITION_NSHIFT = 12; - - // IDs having conflicting data between Olson and JDK 1.1 - static final Map<String, String> conflictingIDs = Map.of( - "EST", "America/Panama", - "MST", "America/Phoenix"); - - private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar(); - - /** - * The raw GMT offset in milliseconds between this zone and GMT. - * Negative offsets are to the west of Greenwich. To obtain local - * <em>standard</em> time, add the offset to GMT time. - * @serial - */ - int rawOffset; - - /** - * Difference in milliseconds from the original GMT offset in case - * the raw offset value has been modified by calling {@link - * #setRawOffset}. The initial value is 0. - * @serial - */ - int rawOffsetDiff = 0; - - /** - * A CRC32 value of all pairs of transition time (in milliseconds - * in <code>long</code>) in local time and its GMT offset (in - * seconds in <code>int</code>) in the chronological order. Byte - * values of each <code>long</code> and <code>int</code> are taken - * in the big endian order (i.e., MSB to LSB). - * @serial - */ - int checksum; - - /** - * The amount of time in milliseconds saved during daylight saving - * time. If <code>useDaylight</code> is false, this value is 0. - * @serial - */ - int dstSavings; - - /** - * This array describes transitions of GMT offsets of this time - * zone, including both raw offset changes and daylight saving - * time changes. - * A long integer consists of four bit fields. - * <ul> - * <li>The most significant 52-bit field represents transition - * time in milliseconds from Gregorian January 1 1970, 00:00:00 - * GMT.</li> - * <li>The next 4-bit field is reserved and must be 0.</li> - * <li>The next 4-bit field is an index value to {@link #offsets - * offsets[]} for the amount of daylight saving at the - * transition. If this value is zero, it means that no daylight - * saving, not the index value zero.</li> - * <li>The least significant 4-bit field is an index value to - * {@link #offsets offsets[]} for <em>total</em> GMT offset at the - * transition.</li> - * </ul> - * If this time zone doesn't observe daylight saving time and has - * never changed any GMT offsets in the past, this value is null. - * @serial - */ - long[] transitions; - - /** - * This array holds all unique offset values in - * milliseconds. Index values to this array are stored in the - * transitions array elements. - * @serial - */ - int[] offsets; - - /** - * SimpleTimeZone parameter values. It has to have either 8 for - * {@link java.util.SimpleTimeZone#SimpleTimeZone(int, String, - * int, int , int , int , int , int , int , int , int) the - * 11-argument SimpleTimeZone constructor} or 10 for {@link - * java.util.SimpleTimeZone#SimpleTimeZone(int, String, int, int, - * int , int , int , int , int , int , int, int, int) the - * 13-argument SimpleTimeZone constructor} parameters. - * @serial - */ - int[] simpleTimeZoneParams; - - /** - * True if the raw GMT offset value would change after the time - * zone data has been generated; false, otherwise. The default - * value is false. - * @serial - */ - boolean willGMTOffsetChange = false; - - /** - * True if the object has been modified after its instantiation. - */ - transient private boolean dirty = false; - - private static final long serialVersionUID = 2653134537216586139L; - - /** - * A constructor. - */ - public ZoneInfoOld() { - } - - /** - * A Constructor for CustomID. - */ - public ZoneInfoOld(String ID, int rawOffset) { - this(ID, rawOffset, 0, 0, null, null, null, false); - } - - /** - * Constructs a ZoneInfoOld instance. - * - * @param ID time zone name - * @param rawOffset GMT offset in milliseconds - * @param dstSavings daylight saving value in milliseconds or 0 - * (zero) if this time zone doesn't observe Daylight Saving Time. - * @param checksum CRC32 value with all transitions table entry - * values - * @param transitions transition table - * @param offsets offset value table - * @param simpleTimeZoneParams parameter values for constructing - * SimpleTimeZone - * @param willGMTOffsetChange the value of willGMTOffsetChange - */ - ZoneInfoOld(String ID, - int rawOffset, - int dstSavings, - int checksum, - long[] transitions, - int[] offsets, - int[] simpleTimeZoneParams, - boolean willGMTOffsetChange) { - setID(ID); - this.rawOffset = rawOffset; - this.dstSavings = dstSavings; - this.checksum = checksum; - this.transitions = transitions; - this.offsets = offsets; - this.simpleTimeZoneParams = simpleTimeZoneParams; - this.willGMTOffsetChange = willGMTOffsetChange; - } - - /** - * Returns the difference in milliseconds between local time and UTC - * of given time, taking into account both the raw offset and the - * effect of daylight savings. - * - * @param date the milliseconds in UTC - * @return the milliseconds to add to UTC to get local wall time - */ - public int getOffset(long date) { - return getOffsets(date, null, UTC_TIME); - } - - public int getOffsets(long utc, int[] offsets) { - return getOffsets(utc, offsets, UTC_TIME); - } - - public int getOffsetsByStandard(long standard, int[] offsets) { - return getOffsets(standard, offsets, STANDARD_TIME); - } - - public int getOffsetsByWall(long wall, int[] offsets) { - return getOffsets(wall, offsets, WALL_TIME); - } - - private int getOffsets(long date, int[] offsets, int type) { - // if dst is never observed, there is no transition. - if (transitions == null) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - date -= rawOffsetDiff; - int index = getTransitionIndex(date, type); - - // prior to the transition table, returns the raw offset. - // FIXME: should support LMT. - if (index < 0) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - if (index < transitions.length) { - long val = transitions[index]; - int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; - if (offsets != null) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : this.offsets[dst]; - offsets[0] = offset - save; - offsets[1] = save; - } - return offset; - } - - // beyond the transitions, delegate to SimpleTimeZone if there - // is a rule; otherwise, return rawOffset. - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - int rawoffset = tz.getRawOffset(); - long msec = date; - if (type != UTC_TIME) { - msec -= rawOffset; - } - int dstoffset = tz.getOffset(msec) - rawOffset; - - // Check if it's in a standard-to-daylight transition. - if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) { - dstoffset = 0; - } - - if (offsets != null) { - offsets[0] = rawoffset; - offsets[1] = dstoffset; - } - return rawoffset + dstoffset; - } - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - private int getTransitionIndex(long date, int type) { - int low = 0; - int high = transitions.length - 1; - - while (low <= high) { - int mid = (low + high) / 2; - long val = transitions[mid]; - long midVal = val >> TRANSITION_NSHIFT; // sign extended - if (type != UTC_TIME) { - midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time - } - if (type == STANDARD_TIME) { - int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL); - if (dstIndex != 0) { - midVal -= offsets[dstIndex]; // make it standard time - } - } - - if (midVal < date) { - low = mid + 1; - } else if (midVal > date) { - high = mid - 1; - } else { - return mid; - } - } - - // if beyond the transitions, returns that index. - if (low >= transitions.length) { - return low; - } - return low - 1; - } - - /** - * Returns the difference in milliseconds between local time and - * UTC, taking into account both the raw offset and the effect of - * daylight savings, for the specified date and time. This method - * assumes that the start and end month are distinct. This method - * assumes a Gregorian calendar for calculations. - * <p> - * <em>Note: In general, clients should use - * {@link Calendar#ZONE_OFFSET Calendar.get(ZONE_OFFSET)} + - * {@link Calendar#DST_OFFSET Calendar.get(DST_OFFSET)} - * instead of calling this method.</em> - * - * @param era The era of the given date. The value must be either - * GregorianCalendar.AD or GregorianCalendar.BC. - * @param year The year in the given date. - * @param month The month in the given date. Month is 0-based. e.g., - * 0 for January. - * @param day The day-in-month of the given date. - * @param dayOfWeek The day-of-week of the given date. - * @param millis The milliseconds in day in <em>standard</em> local time. - * @return The milliseconds to add to UTC to get local time. - */ - public int getOffset(int era, int year, int month, int day, - int dayOfWeek, int milliseconds) { - if (milliseconds < 0 || milliseconds >= DAY_IN_MILLIS) { - throw new IllegalArgumentException(); - } - - if (era == java.util.GregorianCalendar.BC) { // BC - year = 1 - year; - } else if (era != java.util.GregorianCalendar.AD) { - throw new IllegalArgumentException(); - } - - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month + 1, day); - if (gcal.validate(date) == false) { - throw new IllegalArgumentException(); - } - - // bug-for-bug compatible argument checking - if (dayOfWeek < java.util.GregorianCalendar.SUNDAY - || dayOfWeek > java.util.GregorianCalendar.SATURDAY) { - throw new IllegalArgumentException(); - } - - if (transitions == null) { - return getLastRawOffset(); - } - - long dateInMillis = gcal.getTime(date) + milliseconds; - dateInMillis -= (long) rawOffset; // make it UTC - return getOffsets(dateInMillis, null, UTC_TIME); - } - - /** - * Sets the base time zone offset from GMT. This operation - * modifies all the transitions of this ZoneInfoOld object, including - * historical ones, if applicable. - * - * @param offsetMillis the base time zone offset to GMT. - * @see getRawOffset - */ - public synchronized void setRawOffset(int offsetMillis) { - if (offsetMillis == rawOffset + rawOffsetDiff) { - return; - } - rawOffsetDiff = offsetMillis - rawOffset; - if (lastRule != null) { - lastRule.setRawOffset(offsetMillis); - } - dirty = true; - } - - /** - * Returns the GMT offset of the current date. This GMT offset - * value is not modified during Daylight Saving Time. - * - * @return the GMT offset value in milliseconds to add to UTC time - * to get local standard time - */ - public int getRawOffset() { - if (!willGMTOffsetChange) { - return rawOffset + rawOffsetDiff; - } - - int[] offsets = new int[2]; - getOffsets(System.currentTimeMillis(), offsets, UTC_TIME); - return offsets[0]; - } - - public boolean isDirty() { - return dirty; - } - - int getLastRawOffset() { - return rawOffset + rawOffsetDiff; - } - - /** - * Queries if this time zone uses Daylight Saving Time in the last known rule. - */ - public boolean useDaylightTime() { - return (simpleTimeZoneParams != null); - } - - @Override - public boolean observesDaylightTime() { - if (simpleTimeZoneParams != null) { - return true; - } - if (transitions == null) { - return false; - } - - // Look up the transition table to see if it's in DST right - // now or if there's any standard-to-daylight transition at - // any future. - long utc = System.currentTimeMillis() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - for (int i = index; i < transitions.length; i++) { - if ((transitions[i] & DST_MASK) != 0) { - return true; - } - } - // No further DST is observed. - return false; - } - - /** - * Queries if the specified date is in Daylight Saving Time. - */ - public boolean inDaylightTime(Date date) { - if (date == null) { - throw new NullPointerException(); - } - - if (transitions == null) { - return false; - } - - long utc = date.getTime() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - if (index < transitions.length) { - return (transitions[index] & DST_MASK) != 0; - } - - // beyond the transition table - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - return tz.inDaylightTime(date); - } - return false; - } - - /** - * Returns the amount of time in milliseconds that the clock is advanced - * during daylight saving time is in effect in its last daylight saving time rule. - * - * @return the number of milliseconds the time is advanced with respect to - * standard time when daylight saving time is in effect. - */ - public int getDSTSavings() { - return dstSavings; - } - -// /** -// * @return the last year in the transition table or -1 if this -// * time zone doesn't observe any daylight saving time. -// */ -// public int getMaxTransitionYear() { -// if (transitions == null) { -// return -1; -// } -// long val = transitions[transitions.length - 1]; -// int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; -// val = (val >> TRANSITION_NSHIFT) + offset; -// CalendarDate lastDate = Gregorian.getCalendarDate(val); -// return lastDate.getYear(); -// } - - /** - * Returns a string representation of this time zone. - * @return the string - */ - public String toString() { - return getClass().getName() + - "[id=\"" + getID() + "\"" + - ",offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",lastRule=" + (lastRule == null ? getLastRuleInstance() : lastRule) + - "]"; - } - - /** - * Gets all available IDs supported in the Java run-time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs() { - List<String> idList = ZoneInfoFile.getZoneIDs(); - List<String> excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - // List all zones from the idList and excluded lists - List<String> list = new ArrayList<>(idList.size() + excluded.size()); - list.addAll(idList); - list.addAll(excluded); - idList = list; - } - String[] ids = new String[idList.size()]; - return idList.toArray(ids); - } - - /** - * Gets all available IDs that have the same value as the - * specified raw GMT offset. - * - * @param rawOffset the GMT offset in milliseconds. This - * value should not include any daylight saving time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs(int rawOffset) { - String[] result; - List<String> matched = new ArrayList<>(); - List<String> IDs = ZoneInfoFile.getZoneIDs(); - int[] rawOffsets = ZoneInfoFile.getRawOffsets(); - - loop: - for (int index = 0; index < rawOffsets.length; index++) { - if (rawOffsets[index] == rawOffset) { - byte[] indices = ZoneInfoFile.getRawOffsetIndices(); - for (int i = 0; i < indices.length; i++) { - if (indices[i] == index) { - matched.add(IDs.get(i++)); - while (i < indices.length && indices[i] == index) { - matched.add(IDs.get(i++)); - } - break loop; - } - } - } - } - - // We need to add any zones from the excluded zone list that - // currently have the same GMT offset as the specified - // rawOffset. The zones returned by this method may not be - // correct as of return to the caller if any GMT offset - // transition is happening during this GMT offset checking... - List<String> excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - for (String id : excluded) { - TimeZone zi = getTimeZone(id); - if (zi != null && zi.getRawOffset() == rawOffset) { - matched.add(id); - } - } - } - - result = new String[matched.size()]; - matched.toArray(result); - return result; - } - - /** - * Gets the ZoneInfoOld for the given ID. - * - * @param ID the ID for a ZoneInfoOld. See TimeZone for detail. - * - * @return the specified ZoneInfoOld object, or null if there is no - * time zone of the ID. - */ - public static TimeZone getTimeZone(String ID) { - String givenID = null; - - ZoneInfoOld zi = ZoneInfoFile.getZoneInfoOld(ID); - if (zi == null) { - // if we can't create an object for the ID, try aliases. - try { - Map<String, String> map = getAliasTable(); - String alias = ID; - while ((alias = map.get(alias)) != null) { - zi = ZoneInfoFile.getZoneInfoOld(alias); - if (zi != null) { - zi.setID(ID); - zi = ZoneInfoFile.addToCache(ID, zi); - zi = (ZoneInfoOld) zi.clone(); - break; - } - } - } catch (Exception e) { - // ignore exceptions - } - } - - if (givenID != null && zi != null) { - zi.setID(givenID); - } - return zi; - } - - private transient SimpleTimeZone lastRule; - - /** - * Returns a SimpleTimeZone object representing the last GMT - * offset and DST schedule or null if this time zone doesn't - * observe DST. - */ - synchronized SimpleTimeZone getLastRule() { - if (lastRule == null) { - lastRule = getLastRuleInstance(); - } - return lastRule; - } - - /** - * Returns a SimpleTimeZone object that represents the last - * known daylight saving time rules. - * - * @return a SimpleTimeZone object or null if this time zone - * doesn't observe DST. - */ - public SimpleTimeZone getLastRuleInstance() { - if (simpleTimeZoneParams == null) { - return null; - } - if (simpleTimeZoneParams.length == 10) { - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - simpleTimeZoneParams[8], - simpleTimeZoneParams[9], - dstSavings); - } - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - dstSavings); - } - - /** - * Returns a copy of this <code>ZoneInfoOld</code>. - */ - public Object clone() { - ZoneInfoOld zi = (ZoneInfoOld) super.clone(); - zi.lastRule = null; - return zi; - } - - /** - * Returns a hash code value calculated from the GMT offset and - * transitions. - * @return a hash code of this time zone - */ - public int hashCode() { - return getLastRawOffset() ^ checksum; - } - - /** - * Compares the equity of two ZoneInfoOld objects. - * - * @param obj the object to be compared with - * @return true if given object is same as this ZoneInfoOld object, - * false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ZoneInfoOld)) { - return false; - } - ZoneInfoOld that = (ZoneInfoOld) obj; - return (getID().equals(that.getID()) - && (getLastRawOffset() == that.getLastRawOffset()) - && (checksum == that.checksum)); - } - - /** - * Returns true if this zone has the same raw GMT offset value and - * transition table as another zone info. If the specified - * TimeZone object is not a ZoneInfoOld instance, this method returns - * true if the specified TimeZone object has the same raw GMT - * offset value with no daylight saving time. - * - * @param other the ZoneInfoOld object to be compared with - * @return true if the given <code>TimeZone</code> has the same - * GMT offset and transition information; false, otherwise. - */ - public boolean hasSameRules(TimeZone other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof ZoneInfoOld)) { - if (getRawOffset() != other.getRawOffset()) { - return false; - } - // if both have the same raw offset and neither observes - // DST, they have the same rule. - if ((transitions == null) - && (useDaylightTime() == false) - && (other.useDaylightTime() == false)) { - return true; - } - return false; - } - if (getLastRawOffset() != ((ZoneInfoOld)other).getLastRawOffset()) { - return false; - } - return (checksum == ((ZoneInfoOld)other).checksum); - } - - private static SoftReference<Map<String, String>> aliasTable; - - static Map<String, String> getCachedAliasTable() { - Map<String, String> aliases = null; - - SoftReference<Map<String, String>> cache = aliasTable; - if (cache != null) { - aliases = cache.get(); - } - return aliases; - } - - /** - * Returns a Map from alias time zone IDs to their standard - * time zone IDs. - * - * @return the Map that holds the mappings from alias time zone IDs - * to their standard time zone IDs, or null if - * <code>ZoneInfoOldMappings</code> file is not available. - */ - public synchronized static Map<String, String> getAliasTable() { - Map<String, String> aliases = getCachedAliasTable(); - if (aliases == null) { - aliases = ZoneInfoFile.getZoneAliases(); - if (aliases != null) { - // Replace old mappings from `jdk11_backward` - aliases.putAll(conflictingIDs); - aliasTable = new SoftReference<Map<String, String>>(aliases); - } - } - return aliases; - } - - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - // We don't know how this object from 1.4.x or earlier has - // been mutated. So it should always be marked as `dirty'. - dirty = true; - } - - ////////////////////////////////////////////////////////////// - public boolean equalsTo(ZoneInfoOld other) { - return (getID().equals(other.getID()) - && (getLastRawOffset() == other.getLastRawOffset()) - && (dstSavings == other.dstSavings) - && (willGMTOffsetChange == other.willGMTOffsetChange) - && (checksum == other.checksum) - && equalsTransOffsets(other) - && (Arrays.equals(simpleTimeZoneParams, other.simpleTimeZoneParams) || - getLastRule().equals(other.getLastRule()))); - } - - private boolean equalsTransOffsets(ZoneInfoOld other) { - if (transitions == null) { - return (other.transitions == null && - Arrays.equals(offsets, other.offsets)); - } - if (other.transitions == null || - transitions.length != other.transitions.length) { - return false; - } - // if offsets and other.offsets have different order - // the last 4-bit in trans are different. - for (int i = 0; i < transitions.length; i++) { - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - - val = other.transitions[i]; - int dstO = (int)((val >>> DST_NSHIFT) & 0xfL); - int saveO = (dstO == 0) ? 0 : other.offsets[dstO] / 1000; - int offO = other.offsets[(int)(val & OFFSET_MASK)]/1000; - long secondO = (val >> TRANSITION_NSHIFT)/1000; - if ((dst == 0) != (dstO == 0) || save != saveO || off != offO || second != secondO) - return false; - } - return true; - } - - private int transToString(long val, int off_old, int[] offsets, StringBuilder sb) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - ZoneOffset offset_old = ZoneOffset.ofTotalSeconds(off_old); - ZoneOffset offset = ZoneOffset.ofTotalSeconds(off); - sb.append(" " + LocalDateTime.ofEpochSecond(second, 0, offset_old)); - - sb.append(" [utc=" + second + - " raw=" + Long.toHexString(val >> TRANSITION_NSHIFT) + - ", offset=" + off + "/" + offset + ", saving=" + save + "]"); - return off; - } - - public String diffsTo(ZoneInfoOld other) { - - int rawOffset0 = other.rawOffset; - int checksum0 = other.checksum; - int dstSavings0 = other.dstSavings; - long[] transitions0 = other.transitions; - int[] offsets0 = other.offsets; - int[] simpleTimeZoneParams0 = other.simpleTimeZoneParams; - boolean willGMTOffsetChange0 = other.willGMTOffsetChange; - - - //return getClass().getName() + - StringBuilder sb = new StringBuilder(); - sb.append("******************************\n" + - getID() + " : " + other.getID()); - // ROC is excluded by ZoneInfoOld - if ("ROC".equals(getID())) { - return sb.toString(); - } - if (rawOffset != rawOffset0 || - dstSavings != dstSavings0 || - checksum != checksum0 || - willGMTOffsetChange != willGMTOffsetChange0 || - (simpleTimeZoneParams != null ) != (simpleTimeZoneParams0 != null) || - (transitions != null && transitions0 != null && - transitions.length != transitions0.length)) - { - sb.append("\n offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",offsets=" + ((offsets != null) ? offsets.length : 0) + - ",checksum=" + checksum + - ",gmtChanged=" + willGMTOffsetChange) - .append("\n[NG]offset=" + rawOffset0 + - ",dstSavings=" + dstSavings0 + - ",useDaylight=" + (simpleTimeZoneParams != null) + - ",transitions=" + ((transitions0 != null) ? transitions0.length : 0) + - ",offsets=" + ((offsets0 != null) ? offsets0.length : 0) + - ",checksum=" + checksum0 + - ",gmtChanged=" + willGMTOffsetChange0 + - ""); - } - // offsets - if (!Arrays.equals(offsets, offsets0)) { - sb.append("\n offset.len=" + ((offsets != null)? offsets.length : "null") + - " " + ((offsets0 != null)? offsets0.length : "null")); - if (offsets != null && offsets0.length != 0) { - int len = Math.min(offsets.length, offsets0.length); - int i = 0; - for (i = 0; i < len; i++) { - sb.append("\n " + - ZoneOffset.ofTotalSeconds(offsets[i]/1000) + " " + - ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - for (; i < offsets0.length; i++) { - sb.append("\n " + ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - } - } - // trans - int offset = 0; - int offset0 = 0; - if (!equalsTransOffsets(other)) { - sb.append("\n -------------"); - if ((transitions == null) != (transitions0 == null)) { - sb.append("\n (NG) Different trans(null) :" + - transitions + ", " + transitions0); - if (transitions != null) { - for (int i = 0; i < transitions.length; i++) { - sb.append("\n (NG)"); - offset = transToString(transitions[i], offset, offsets, sb); - } - } - } else { - if (transitions.length != transitions0.length) { - sb.append("\n (NG) Different trans size :" + - transitions.length + ", " + transitions0.length); - } - int length = Math.min(transitions.length, transitions0.length); - for (int i = 0; i < length; i++) { - // sb.append("\n[" + i + "] "); - // offset = transToString(transitions[i], offset, offsets, sb); - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - if (transitions0 == null || i >= transitions0.length) { - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - sb.append("\n (NG) trans0 is null or < trans.length"); - } else { - long val0 = transitions0[i]; - int dst0 = (int)((val0 >>> DST_NSHIFT) & 0xfL); - int save0 = (dst0 == 0) ? 0 : offsets0[dst0] / 1000; - int off0 = offsets0[(int)(val0 & OFFSET_MASK)]/1000; - long second0 = (val0 >> TRANSITION_NSHIFT)/1000; - if (save != save0 || off != off0 || second != second0) { - sb.append("\n (NG)"); - } else { - sb.append("\n (OK)"); - } - offset0 = transToString(transitions0[i], offset0, offsets0, sb); - sb.append("\n -----"); - } - } - } - } - SimpleTimeZone stz = getLastRuleInstance(); - if (stz != null) { - SimpleTimeZone stz0 = other.getLastRule(); - if (!stz.hasSameRules(stz0)) { - sb.append("\n -------------") - .append("\n SimpleTimeZone (NG)") - .append("\n stz=" + stz) - .append("\n stz0=" + stz0); - } - } - sb.append("\n -------------"); - return sb.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneRec.java b/test/jdk/sun/util/calendar/zi/ZoneRec.java deleted file mode 100644 index f6bbeb3a199..00000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneRec.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2000, 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. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * ZoneRec hold information of time zone corresponding to each text - * line of the "Zone" part. - * - * @since 1.4 - */ -class ZoneRec { - private int gmtOffset; - private String ruleName; - private int directSave; - private Rule ruleRef; - private String format; - private boolean hasUntil; - private int untilYear; - private Month untilMonth; - private RuleDay untilDay; - private Time untilTime; - private long untilInMillis; - private String line; - - /** - * @return the "UNTIL" value in milliseconds - */ - Time getUntilTime() { - return untilTime; - } - - /** - * @return the GMT offset value in milliseconds - */ - int getGmtOffset() { - return gmtOffset; - } - - /** - * @return the rule name to which this zone record refers - */ - String getRuleName() { - return ruleName; - } - - /** - * @return the amount of saving time directly defined in the - * "RULES/SAVE" field. - */ - int getDirectSave() { - return directSave; - } - - /** - * @return true if this zone record has a reference to a rule - */ - boolean hasRuleReference() { - return ruleRef != null; - } - - /** - * Returns the "FORMAT" field string of this zone record. This - * @return the "FORMAT" field - */ - String getFormat() { - return format; - } - - /** - * @return the year in the "UNTIL" field - */ - int getUntilYear() { - return untilYear; - } - - /** - * Returns the "UNTIL" field value in milliseconds from Janurary - * 1, 1970 0:00 GMT. - * @param currentSave the amount of daylight saving in - * milliseconds that is used to adjust wall-clock time. - * @return the milliseconds value of the "UNTIL" field - */ - long getUntilTime(int currentSave) { - if (untilTime.isWall()) { - return untilInMillis - currentSave; - } - return untilInMillis; - } - - /** - * Returns the "UNTIL" time in milliseconds without adjusting GMT - * offsets or daylight saving. - * @return local "UNTIL" time in milliseconds - */ - long getLocalUntilTime() { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - untilTime.getTime()); - } - - /** - * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving. - * @return the "UNTIL" time after the adjustment - */ - long getLocalUntilTime(int save, int gmtOffset) { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - save, - gmtOffset, - untilTime); - } - - /** - * @return the text line of this zone record - */ - String getLine() { - return line; - } - - /** - * Sets the specified text line to this zone record - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if this zone record has the "UNTIL" field - */ - boolean hasUntil() { - return this.hasUntil; - } - - /** - * Adjusts the "UNTIL" time to GMT offset if this zone record has - * it. <code>untilTime</code> is not adjusted to daylight saving - * in this method. - */ - void adjustTime() { - if (!hasUntil()) { - return; - } - if (untilTime.isSTD() || untilTime.isWall()) { - // adjust to gmt offset only here. adjust to real - // wall-clock time when tracking rules - untilInMillis -= gmtOffset; - } - } - - /** - * @return the reference to the Rule object - */ - Rule getRuleRef() { - return ruleRef; - } - - /** - * Resolves the reference to a Rule and adjusts its "UNTIL" time - * to GMT offset. - */ - void resolve(Zoneinfo zi) { - if (ruleName != null && (!"-".equals(ruleName))) { - ruleRef = zi.getRule(ruleName); - } - adjustTime(); - } - - /** - * Parses a Zone text line that is described by a StringTokenizer. - * @param tokens represents tokens of a Zone text line - * @return the zone record produced by parsing the text - */ - static ZoneRec parse(StringTokenizer tokens) { - ZoneRec rec = new ZoneRec(); - try { - rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime(); - String token = tokens.nextToken(); - char c = token.charAt(0); - if (c >= '0' && c <= '9') { - rec.directSave = (int) Time.parse(token).getTime(); - } else { - rec.ruleName = token; - } - rec.format = tokens.nextToken(); - if (tokens.hasMoreTokens()) { - rec.hasUntil = true; - rec.untilYear = Integer.parseInt(tokens.nextToken()); - if (tokens.hasMoreTokens()) { - rec.untilMonth = Month.parse(tokens.nextToken()); - } else { - rec.untilMonth = Month.JANUARY; - } - if (tokens.hasMoreTokens()) { - rec.untilDay = RuleDay.parse(tokens.nextToken()); - } else { - rec.untilDay = new RuleDay(1); - } - if (tokens.hasMoreTokens()) { - rec.untilTime = Time.parse(tokens.nextToken()); - } else { - rec.untilTime = Time.parse("0:00"); - } - rec.untilInMillis = rec.getLocalUntilTime(); - } - } catch (Exception e) { - // TODO: error reporting - e.printStackTrace(); - } - return rec; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zoneinfo.java b/test/jdk/sun/util/calendar/zi/Zoneinfo.java deleted file mode 100644 index e125ad2cb87..00000000000 --- a/test/jdk/sun/util/calendar/zi/Zoneinfo.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * 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 - * 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.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -/** - * Zoneinfo provides javazic compiler front-end functionality. - * @since 1.4 - */ -class Zoneinfo { - - private static final int minYear = 1900; - private static final int maxYear = 2100; - private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0); - private static int startYear = minYear; - private static int endYear = maxYear; - - /** - * True if javazic should generate a list of SimpleTimeZone - * instances for the SimpleTimeZone-based time zone support. - */ - static boolean isYearForTimeZoneDataSpecified = false; - - /** - * Zone name to Zone mappings - */ - private Map<String,Zone> zones; - - /** - * Rule name to Rule mappings - */ - private Map<String,Rule> rules; - - /** - * Alias name to real name mappings - */ - private Map<String,String> aliases; - - /** - * Constracts a Zoneinfo. - */ - Zoneinfo() { - zones = new HashMap<String,Zone>(); - rules = new HashMap<String,Rule>(); - aliases = new HashMap<String,String>(); - } - - /** - * Adds the given zone to the list of Zones. - * @param zone Zone to be added to the list. - */ - void add(Zone zone) { - String name = zone.getName(); - zones.put(name, zone); - } - - /** - * Adds the given rule to the list of Rules. - * @param rule Rule to be added to the list. - */ - void add(Rule rule) { - String name = rule.getName(); - rules.put(name, rule); - } - - /** - * Puts the specifid name pair to the alias table. - * @param name1 an alias time zone name - * @param name2 the real time zone of the alias name - */ - void putAlias(String name1, String name2) { - aliases.put(name1, name2); - } - - /** - * Sets the given year for SimpleTimeZone list output. - * This method is called when the -S option is specified. - * @param year the year for which SimpleTimeZone list should be generated - */ - static void setYear(int year) { - setStartYear(year); - setEndYear(year); - isYearForTimeZoneDataSpecified = true; - } - - /** - * Sets the start year. - * @param year the start year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the minimum year or greater than the end year. - */ - static void setStartYear(int year) { - if (year < minYear || year > endYear) { - throw new IllegalArgumentException("invalid start year specified: " + year); - } - startYear = year; - } - - /** - * @return the start year value - */ - static int getStartYear() { - return startYear; - } - - /** - * Sets the end year. - * @param year the end year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the start year or greater than the maximum year. - */ - static void setEndYear(int year) { - if (year < startYear || year > maxYear) { - throw new IllegalArgumentException(); - } - endYear = year; - } - - /** - * @return the end year value - */ - static int getEndYear() { - return endYear; - } - - /** - * @return the minimum year value - */ - static int getMinYear() { - return minYear; - } - - /** - * @return the maximum year value - */ - static int getMaxYear() { - return maxYear; - } - - /** - * @return the alias table - */ - Map<String,String> getAliases() { - return aliases; - } - - /** - * @return the Zone list - */ - Map<String,Zone> getZones() { - return zones; - } - - /** - * @return a Zone specified by name. - * @param name a zone name - */ - Zone getZone(String name) { - return zones.get(name); - } - - /** - * @return a Rule specified by name. - * @param name a rule name - */ - Rule getRule(String name) { - return rules.get(name); - } - - private static String line; - - private static int lineNum; - - /** - * Parses the specified time zone data file and creates a Zoneinfo - * that has all Rules, Zones and Links (aliases) information. - * @param fname the time zone data file name - * @return a Zoneinfo object - */ - static Zoneinfo parse(String fname) { - BufferedReader in = null; - try { - FileReader fr = new FileReader(fname); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - panic("can't open file: "+fname); - } - Zoneinfo zi = new Zoneinfo(); - boolean continued = false; - Zone zone = null; - String l; - lineNum = 0; - - try { - while ((line = in.readLine()) != null) { - lineNum++; - // skip blank and comment lines - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - - // trim trailing comments - int rindex = line.lastIndexOf('#'); - if (rindex != -1) { - // take the data part of the line - l = line.substring(0, rindex); - } else { - l = line; - } - - StringTokenizer tokens = new StringTokenizer(l); - if (!tokens.hasMoreTokens()) { - continue; - } - String token = tokens.nextToken(); - int len = token.length(); - - if (continued || token.regionMatches(true, 0, "Zone", 0, len)){ - if (zone == null) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: zone no more token"); - } - token = tokens.nextToken(); - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict. - if (token.startsWith("GMT+") || token.startsWith("GMT-")) { - continue; - } - zone = new Zone(token); - } else { - // no way to push the current token back... - tokens = new StringTokenizer(l); - } - - ZoneRec zrec = ZoneRec.parse(tokens); - zrec.setLine(line); - zone.add(zrec); - if ((continued = zrec.hasUntil()) == false) { - if (Zone.isTargetZone(zone.getName())) { - // zone.resolve(zi); - zi.add(zone); - } - zone = null; - } - } else if (token.regionMatches(true, 0, "Rule", 0, len)) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: rule no more token"); - } - token = tokens.nextToken(); - Rule rule = zi.getRule(token); - if (rule == null) { - rule = new Rule(token); - zi.add(rule); - } - RuleRec rrec = RuleRec.parse(tokens); - rrec.setLine(line); - rule.add(rrec); - } else if (token.regionMatches(true, 0, "Link", 0, len)) { - // Link <newname> <oldname> - try { - String name1 = tokens.nextToken(); - String name2 = tokens.nextToken(); - - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict with - // custom time zones. Also, ignore "ROC" for - // PC-ness. - if (name2.startsWith("GMT+") || name2.startsWith("GMT-") - || "ROC".equals(name2)) { - continue; - } - zi.putAlias(name2, name1); - } catch (Exception e) { - panic("syntax error: no more token for Link"); - } - } - } - in.close(); - } catch (IOException ex) { - panic("IO error: " + ex.getMessage()); - } - - return zi; - } - - /** - * Interprets a zone and constructs a Timezone object that - * contains enough information on GMT offsets and DST schedules to - * generate a zone info database. - * - * @param zoneName the zone name for which a Timezone object is - * constructed. - * - * @return a Timezone object that contains all GMT offsets and DST - * rules information. - */ - Timezone phase2(String zoneName) { - Timezone tz = new Timezone(zoneName); - Zone zone = getZone(zoneName); - zone.resolve(this); - - // TODO: merge phase2's for the regular and SimpleTimeZone ones. - if (isYearForTimeZoneDataSpecified) { - ZoneRec zrec = zone.get(zone.size()-1); - tz.setLastZoneRec(zrec); - tz.setRawOffset(zrec.getGmtOffset()); - if (zrec.hasRuleReference()) { - /* - * This part assumes that the specified year is covered by - * the rules referred to by the last zone record. - */ - List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear); - - if (rrecs.size() == 2) { - // make sure that one is a start rule and the other is - // an end rule. - RuleRec r0 = rrecs.get(0); - RuleRec r1 = rrecs.get(1); - if (r0.getSave() == 0 && r1.getSave() > 0) { - rrecs.set(0, r1); - rrecs.set(1, r0); - } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) { - rrecs = null; - Main.error(zoneName + ": rules for " + startYear + " not found."); - } - } else { - rrecs = null; - } - if (rrecs != null) { - tz.setLastRules(rrecs); - } - } - return tz; - } - - int gmtOffset; - int year = minYear; - int fromYear = year; - long fromTime = Time.getLocalTime(startYear, - Month.JANUARY, - 1, 0); - - // take the index 0 for the GMT offset of the last zone record - ZoneRec zrec = zone.get(zone.size()-1); - tz.getOffsetIndex(zrec.getGmtOffset()); - - int lastGmtOffsetValue = -1; - ZoneRec prevzrec = null; - int currentSave = 0; - boolean usedZone; - for (int zindex = 0; zindex < zone.size(); zindex++) { - zrec = zone.get(zindex); - usedZone = false; - gmtOffset = zrec.getGmtOffset(); - int stdOffset = zrec.getDirectSave(); - - if (gmtOffset != lastGmtOffsetValue) { - tz.setRawOffset(gmtOffset, fromTime); - lastGmtOffsetValue = gmtOffset; - } - // If this is the last zone record, take the last rule info. - if (!zrec.hasUntil()) { - if (zrec.hasRuleReference()) { - tz.setLastRules(zrec.getRuleRef().getLastRules()); - } else if (stdOffset != 0) { - // in case the last rule is all year round DST-only - // (Asia/Amman once announced this rule.) - tz.setLastDSTSaving(stdOffset); - } - } - if (!zrec.hasRuleReference()) { - if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - usedZone = true; - } - currentSave = stdOffset; - // optimization in case the last rule is fixed. - if (!zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - if (stdOffset == 0) { - tz.setDSTType(Timezone.X_DST); - } else { - tz.setDSTType(Timezone.LAST_DST); - } - long time = Time.getLocalTime(maxYear, - Month.JANUARY, 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - tz.addUsedRec(zrec); - } else { - tz.setDSTType(Timezone.NO_DST); - } - break; - } - } else { - Rule rule = zrec.getRuleRef(); - boolean fromTimeUsed = false; - currentSave = 0; - year_loop: - for (year = getMinYear(); year <= endYear; year++) { - if (zrec.hasUntil() && year > zrec.getUntilYear()) { - break; - } - List<RuleRec> rules = rule.getRules(year); - if (rules.size() > 0) { - for (int i = 0; i < rules.size(); i++) { - RuleRec rrec = rules.get(i); - long transition = rrec.getTransitionTime(year, - gmtOffset, - currentSave); - if (zrec.hasUntil()) { - if (transition >= zrec.getUntilTime(currentSave)) { - // If the GMT offset changed from the previous one, - // record fromTime as a transition. - if (!fromTimeUsed && prevzrec != null - && gmtOffset != prevzrec.getGmtOffset()) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; // for consistency - } - break year_loop; - } - } - - if (fromTimeUsed == false) { - if (fromTime <= transition) { - fromTimeUsed = true; - - if (fromTime != minTime) { - int prevsave; - - // See if until time in the previous - // ZoneRec is the same thing as the - // local time in the next rule. - // (examples are Asia/Ashkhabad in 1991, - // Europe/Riga in 1989) - - if (i > 0) { - prevsave = rules.get(i-1).getSave(); - } else { - List<RuleRec> prevrules = rule.getRules(year-1); - - if (prevrules.size() > 0) { - prevsave = prevrules.get(prevrules.size()-1).getSave(); - } else { - prevsave = 0; - } - } - - if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) { - currentSave = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - continue; - } - if (!prevzrec.hasRuleReference() - || rule != prevzrec.getRuleRef() - || (rule == prevzrec.getRuleRef() - && gmtOffset != prevzrec.getGmtOffset())) { - int save = (fromTime == transition) ? rrec.getSave() : currentSave; - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - tz.addUsedRec(rrec); - usedZone = true; - } - } else { // fromTime == minTime - int save = rrec.getSave(); - tz.addTransition(minTime, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - - tz.addUsedRec(rrec); - usedZone = true; - } - } else if (year == fromYear && i == rules.size()-1) { - int save = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - } - } - - currentSave = rrec.getSave(); - if (fromTime < transition) { - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - } - } - } else { - if (year == fromYear) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; - } - if (year == endYear && !zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - // Assume that this Zone stopped DST - tz.setDSTType(Timezone.X_DST); - long time = Time.getLocalTime(maxYear, Month.JANUARY, - 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - usedZone = true; - } else { - tz.setDSTType(Timezone.NO_DST); - } - } - } - } - } - if (usedZone) { - tz.addUsedRec(zrec); - } - if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) { - fromTime = zrec.getUntilTime(currentSave); - fromYear = zrec.getUntilYear(); - year = zrec.getUntilYear(); - } - prevzrec = zrec; - } - - if (tz.getDSTType() == Timezone.UNDEF_DST) { - tz.setDSTType(Timezone.DST); - } - tz.optimize(); - tz.checksum(); - return tz; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward b/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward deleted file mode 100644 index e480a0083be..00000000000 --- a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2000, 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. -# -# JDK 1.1.x compatible time zone IDs -# - -Link Australia/Darwin ACT -Link Australia/Sydney AET -Link America/Argentina/Buenos_Aires AGT -Link Africa/Cairo ART -Link America/Anchorage AST -Link America/Sao_Paulo BET -Link Asia/Dhaka BST -Link Africa/Harare CAT -Link America/St_Johns CNT -Link America/Chicago CST -Link Asia/Shanghai CTT -Link Africa/Addis_Ababa EAT -Link Europe/Paris ECT -Link America/New_York EST -Link Pacific/Honolulu HST -Link America/Indianapolis IET -Link Asia/Calcutta IST -Link Asia/Tokyo JST -Link Pacific/Apia MIT -Link America/Denver MST -Link Asia/Yerevan NET -Link Pacific/Auckland NST -Link Asia/Karachi PLT -Link America/Phoenix PNT -Link America/Puerto_Rico PRT -Link America/Los_Angeles PST -Link Pacific/Guadalcanal SST -Link Asia/Saigon VST - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D -Rule SystemV min 1973 - Oct lastSun 2:00 0 S -Rule SystemV 1974 only - Jan 6 2:00 1:00 D -Rule SystemV 1974 only - Nov lastSun 2:00 0 S -Rule SystemV 1975 only - Feb 23 2:00 1:00 D -Rule SystemV 1975 only - Oct lastSun 2:00 0 S -Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D -Rule SystemV 1976 max - Oct lastSun 2:00 0 S - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone SystemV/AST4ADT -4:00 SystemV A%sT -Zone SystemV/EST5EDT -5:00 SystemV E%sT -Zone SystemV/CST6CDT -6:00 SystemV C%sT -Zone SystemV/MST7MDT -7:00 SystemV M%sT -Zone SystemV/PST8PDT -8:00 SystemV P%sT -Zone SystemV/YST9YDT -9:00 SystemV Y%sT -Zone SystemV/AST4 -4:00 - AST -Zone SystemV/EST5 -5:00 - EST -Zone SystemV/CST6 -6:00 - CST -Zone SystemV/MST7 -7:00 - MST -Zone SystemV/PST8 -8:00 - PST -Zone SystemV/YST9 -9:00 - YST -Zone SystemV/HST10 -10:00 - HST From 7011614640923f81b8679fa40873cf9c024a1133 Mon Sep 17 00:00:00 2001 From: Anna Babu Palathingal <148897727+annaibm@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:23:53 -0500 Subject: [PATCH 67/99] Exclude ExtensiblePolicyWithJarTest for FIPS Strict - Exclude ExtensiblePolicyWithJarTest for FIPS140_3_OpenJCEPlusFIPS.FIPS140-3 related: https://github.ibm.com/runtimes/automation/issues/170 Signed-off-by: anna.bp <anna.bp@ibm.com> --- test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt index eccbdbf3ff7..45d67622b58 100644 --- a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt +++ b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt @@ -208,6 +208,7 @@ java/security/MessageDigest/TestDigestIOStream.java https://github.com/eclipse-o java/security/MessageDigest/TestSameLength.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/MessageDigest/TestSameValue.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java https://github.ibm.com/runtimes/jit-crypto/issues/622 generic-all java/security/Policy/GetInstance/GetInstance.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/GetInstance/GetInstanceSecurity.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/SignedJar/SignedJarTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all From f2f78924f1c0116dfc6ea535c2da73463c667dae Mon Sep 17 00:00:00 2001 From: Leonid Mesnik <lmesnik@openjdk.org> Date: Wed, 8 Jan 2025 20:14:59 +0000 Subject: [PATCH 68/99] 8346998: Test nsk/jvmti/ResourceExhausted/resexhausted003 fails with java.lang.OutOfMemoryError when CDS is off Reviewed-by: dholmes, sspitsyn --- .../ResourceExhausted/resexhausted003/TestDescription.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java index b6ef5ab8487..26cdf4473cf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,7 @@ * /test/lib * @run main/othervm/native * -agentlib:resexhausted=-waittime=5 - * -Xms64m - * -Xmx64m - * -XX:MaxMetaspaceSize=9m - * -XX:-UseGCOverheadLimit + * -XX:MaxMetaspaceSize=20m * nsk.jvmti.ResourceExhausted.resexhausted003 */ From c068f0e76e86e29da5d740fa3e74d739568e934c Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Wed, 8 Jan 2025 20:46:57 +0000 Subject: [PATCH 69/99] 8346671: java/nio/file/Files/probeContentType/Basic.java fails on Windows 2025 Reviewed-by: jpai --- .../java/nio/file/Files/probeContentType/Basic.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 8add9e76104..aee1b19a01d 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import jdk.internal.util.OperatingSystem; import jdk.internal.util.OSVersion; +import jdk.internal.util.StaticProperty; /** * Uses Files.probeContentType to probe html file, custom file type, and minimal @@ -83,7 +84,7 @@ private static int checkContentTypes(String expected, String actual) { if (!expected.equals(actual)) { if (!OperatingSystem.isWindows()) { Path userMimeTypes = - Path.of(System.getProperty("user.home"), ".mime.types"); + Path.of(StaticProperty.userHome(), ".mime.types"); checkMimeTypesFile(userMimeTypes); Path etcMimeTypes = Path.of("/etc/mime.types"); @@ -188,9 +189,10 @@ public static void main(String[] args) throws IOException { exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); exTypes.add(new ExType("wasm", List.of("application/wasm"))); - // extensions with content type that differs on Windows 11+ + // extensions with content type that differs on Windows 11+ and + // Windows Server 2025 if (OperatingSystem.isWindows() && - (System.getProperty("os.name").endsWith("11") || + (StaticProperty.osName().matches("^.*[11|2025]$") || new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { System.out.println("Windows 11+ detected: using different types"); exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); From b40b5b3027493e56e0df546876fa2b27039322c9 Mon Sep 17 00:00:00 2001 From: Chris Plummer <cjplummer@openjdk.org> Date: Wed, 8 Jan 2025 22:52:13 +0000 Subject: [PATCH 70/99] 8347162: Update problemlist CR for vmTestbase/nsk/jdi/VMOutOfMemoryException Reviewed-by: kevinw, amenkov --- test/hotspot/jtreg/ProblemList-Virtual.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index b5bb2c72779..23d21cd0338 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ vmTestbase/nsk/jdi/ExceptionEvent/catchLocation/location002/TestDescription.java # the debuggee, which can lead to I/O poller threads exiting. Because # of this no vthreads can complete their reads, and the test times out as a result. -vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8285417 generic-all +vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8347137 generic-all ### # Fails because resume of a virtual thread is not enough to allow the virtual thread From c4bb2a144ef0b3af473b2dff5dc03950beeed9fb Mon Sep 17 00:00:00 2001 From: Weijun Wang <weijun@openjdk.org> Date: Thu, 9 Jan 2025 01:21:00 +0000 Subject: [PATCH 71/99] 8347289: HKDF delayed provider selection failed with non-extractable PRK Reviewed-by: valeriep --- .../crypto/provider/HKDFKeyDerivation.java | 8 +- .../crypto/provider/KDF/HKDFDelayedPRK.java | 104 ++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java b/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java index a9988bbc115..9b4cf557598 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HKDFKeyDerivation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,8 +180,8 @@ protected byte[] engineDeriveData(AlgorithmParameterSpec derivationSpec) } else if (derivationSpec instanceof HKDFParameterSpec.Expand anExpand) { // set this value in the "if" if ((pseudoRandomKey = anExpand.prk().getEncoded()) == null) { - throw new AssertionError( - "PRK is required for HKDFParameterSpec.Expand"); + throw new InvalidAlgorithmParameterException( + "Cannot retrieve PRK for HKDFParameterSpec.Expand"); } // set this value in the "if" if ((info = anExpand.info()) == null) { @@ -411,4 +411,4 @@ public HKDFSHA512(KDFParameters kdfParameters) } } -} \ No newline at end of file +} diff --git a/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java b/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java new file mode 100644 index 00000000000..50157723416 --- /dev/null +++ b/test/jdk/com/sun/crypto/provider/KDF/HKDFDelayedPRK.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347289 + * @summary make sure DPS works when non-extractable PRK is provided + * @library /test/lib /test/jdk/security/unsignedjce + * @build java.base/javax.crypto.ProviderVerifier + * @enablePreview + * @run main/othervm HKDFDelayedPRK + */ + +import jdk.test.lib.Asserts; + +import javax.crypto.KDF; +import javax.crypto.KDFParameters; +import javax.crypto.KDFSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.HKDFParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidAlgorithmParameterException; +import java.security.Provider; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; + +public class HKDFDelayedPRK { + public static void main(String[] args) throws Exception { + // This is a fake non-extractable key + var prk = new SecretKey() { + @Override + public String getAlgorithm() { + return "PRK"; + } + + @Override + public String getFormat() { + return null; + } + + @Override + public byte[] getEncoded() { + return null; + } + }; + + Security.addProvider(new ProviderImpl()); + var kdf = KDF.getInstance("HKDF-SHA256"); + kdf.deriveData(HKDFParameterSpec.expandOnly(prk, null, 32)); + + // Confirms our own omnipotent impl is selected + Asserts.assertEquals("P", kdf.getProviderName()); + } + + public static class ProviderImpl extends Provider { + public ProviderImpl() { + super("P", "1", "info"); + put("KDF.HKDF-SHA256", KDFImpl.class.getName()); + } + } + + // This HKDF impl accepts everything + public static class KDFImpl extends KDFSpi { + + public KDFImpl(KDFParameters params) throws InvalidAlgorithmParameterException { + super(params); + } + + @Override + protected KDFParameters engineGetParameters() { + return null; + } + + @Override + protected SecretKey engineDeriveKey(String alg, AlgorithmParameterSpec dummy) { + return new SecretKeySpec(new byte[32], alg); + } + + @Override + protected byte[] engineDeriveData(AlgorithmParameterSpec dummy) { + return new byte[32]; + } + } +} From a80ed238128f5196d705abce17fb7e26ee724f93 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Thu, 9 Jan 2025 03:33:21 +0000 Subject: [PATCH 72/99] 8347296: WinInstallerUiTest fails in local test runs if the path to test work directory is longer that regular Reviewed-by: almatvee --- test/jdk/tools/jpackage/windows/WinInstallerUiTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java index c6489ab68cf..7dcf025a506 100644 --- a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java +++ b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,13 +122,13 @@ private void setPackageName(JPackageCommand cmd) { StringBuilder sb = new StringBuilder(cmd.name()); sb.append("With"); if (withDirChooser) { - sb.append("DirChooser"); + sb.append("Dc"); // DirChooser } if (withShortcutPrompt) { - sb.append("ShortcutPrompt"); + sb.append("Sp"); // ShortcutPrompt } if (withLicense) { - sb.append("License"); + sb.append("L"); // License } cmd.setArgumentValue("--name", sb.toString()); } From 2fee5de9d883a3ce9295ce818c89b117130e5ea3 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Thu, 9 Jan 2025 03:35:31 +0000 Subject: [PATCH 73/99] 8347297: Skip the RuntimeImageSymbolicLinksTest test on Windows when it is executed outside of the jtreg Reviewed-by: almatvee --- .../tools/jpackage/share/RuntimeImageSymbolicLinksTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index db74e3456c4..867ea571213 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import static jdk.internal.util.OperatingSystem.WINDOWS; import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; @@ -49,7 +50,7 @@ public class RuntimeImageSymbolicLinksTest { - @Test + @Test(ifNotOS = WINDOWS) public static void test() throws Exception { final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); From f773a50fa1bff931303b2a1527176af03f5bf289 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Thu, 9 Jan 2025 03:42:47 +0000 Subject: [PATCH 74/99] 8347299: Add annotations to test cases in LicenseTest Reviewed-by: almatvee --- .../jdk/tools/jpackage/share/LicenseTest.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/test/jdk/tools/jpackage/share/LicenseTest.java b/test/jdk/tools/jpackage/share/LicenseTest.java index b0eef94fa7c..66cda39eec2 100644 --- a/test/jdk/tools/jpackage/share/LicenseTest.java +++ b/test/jdk/tools/jpackage/share/LicenseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; +import static jdk.internal.util.OperatingSystem.LINUX; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; @@ -67,6 +69,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java + * @requires (jpackage.test.SQETest != null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCommon */ @@ -78,18 +81,14 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java - * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=LicenseTest.testCustomDebianCopyright - * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree2 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree3 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree4 + * --jpt-run=LicenseTest */ public class LicenseTest { + + @Test public static void testCommon() { PackageTest test = new PackageTest().configureHelloApp() .addInitializer(cmd -> { @@ -102,26 +101,32 @@ public static void testCommon() { test.run(); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree() { testLinuxLicenseInUsrTree("/usr"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree2() { testLinuxLicenseInUsrTree("/usr/local"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree3() { testLinuxLicenseInUsrTree("/usr/foo"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree4() { testLinuxLicenseInUsrTree("/usrbuz"); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyright() { new CustomDebianCopyrightTest().run(); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyrightSubst() { new CustomDebianCopyrightTest().withSubstitution(true).run(); } From aaa1c6baf75151f90a1376d0680a88554f259e44 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar <abhiscxk@openjdk.org> Date: Thu, 9 Jan 2025 04:11:54 +0000 Subject: [PATCH 75/99] 8339728: [Accessibility,Windows,JAWS] Bug in the getKeyChar method of the AccessBridge class Reviewed-by: aivanov, psadhukhan, kizune --- .../accessibility/internal/AccessBridge.java | 17 ++- .../include/bridge/AccessBridgePackages.h | 4 +- .../TestJMenuItemShortcutAccessibility.java | 112 ++++++++++++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java diff --git a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index 1f5b5b215fa..021a13fceac 100644 --- a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3904,6 +3904,8 @@ private int controlCode(KeyStroke keyStroke) { return 0; int code = keyStroke.getKeyCode(); switch (code) { + case KeyEvent.VK_TAB: + case KeyEvent.VK_SPACE: case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_DELETE: case KeyEvent.VK_DOWN: @@ -3946,15 +3948,10 @@ private char getKeyChar(KeyStroke keyStroke) { debugString("[INFO]: Shortcut is control character: " + Integer.toHexString(keyCode)); return (char)keyCode; } - String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); - debugString("[INFO]: Shortcut is: " + keyText); - if (keyText != null || keyText.length() > 0) { - CharSequence seq = keyText.subSequence(0, 1); - if (seq != null || seq.length() > 0) { - return seq.charAt(0); - } - } - return 0; + + keyCode = keyStroke.getKeyCode(); + debugString("[INFO]: Shortcut is: " + Integer.toHexString(keyCode)); + return (char)keyCode; } /* diff --git a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h index 27c31be09a8..232cab4b21b 100644 --- a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h +++ b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1108,6 +1108,8 @@ typedef long ABHWND64; #define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. // The supported control code keys are: +#define ACCESSIBLE_VK_TAB 9 +#define ACCESSIBLE_VK_SPACE 32 #define ACCESSIBLE_VK_BACK_SPACE 8 #define ACCESSIBLE_VK_DELETE 127 #define ACCESSIBLE_VK_DOWN 40 diff --git a/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java new file mode 100644 index 00000000000..acd7ec3c64a --- /dev/null +++ b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; + +/* + * @test + * @bug 8339728 + * @summary Tests that JAWS announce the shortcuts for JMenuItems. + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJMenuItemShortcutAccessibility + */ + +public class TestJMenuItemShortcutAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Start the JAWS application + 2. Press Alt + M to open application Menu + 3. Navigate the Menu Items by using UP / DOWN arrow key + 4. Press Pass if you are able to hear correct JAWS announcements + (JAWS should read full shortcut text and not only the 1st + character of shortcut text for each menu item) else Fail + """; + + PassFailJFrame.builder() + .title("TestJMenuItemShortcutAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(TestJMenuItemShortcutAccessibility::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with Menu"); + + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Menu with shortcuts"); + menu.setMnemonic(KeyEvent.VK_M); + menuBar.add(menu); + + KeyStroke keyStroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_F, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_2, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_F1, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke4 = KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke5 = KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, + InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK); + KeyStroke keyStroke6 = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke7 = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + JMenuItem menuItem1 = new JMenuItem("First Menu Item"); + menuItem1.setAccelerator(keyStroke1); + JMenuItem menuItem2 = new JMenuItem("Second Menu Item"); + menuItem2.setAccelerator(keyStroke2); + JMenuItem menuItem3 = new JMenuItem("Third Menu Item"); + menuItem3.setAccelerator(keyStroke3); + JMenuItem menuItem4 = new JMenuItem("Fourth Menu Item"); + menuItem4.setAccelerator(keyStroke4); + JMenuItem menuItem5 = new JMenuItem("Fifth Menu Item"); + menuItem5.setAccelerator(keyStroke5); + JMenuItem menuItem6 = new JMenuItem("Sixth Menu Item"); + menuItem6.setAccelerator(keyStroke6); + JMenuItem menuItem7 = new JMenuItem("Seventh Menu Item"); + menuItem7.setAccelerator(keyStroke7); + + menu.add(menuItem1); + menu.add(menuItem2); + menu.add(menuItem3); + menu.add(menuItem4); + menu.add(menuItem5); + menu.add(menuItem6); + menu.add(menuItem7); + + frame.setJMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } +} From f157763b3e7340c994c0078de7bcd3b15c151b32 Mon Sep 17 00:00:00 2001 From: Dmitry Markov <dmarkov@openjdk.org> Date: Thu, 9 Jan 2025 06:58:31 +0000 Subject: [PATCH 76/99] 8346887: DrawFocusRect() may cause an assertion failure Reviewed-by: aivanov, prr --- .../windows/native/libawt/windows/awt_Button.cpp | 4 ++-- .../windows/native/libawt/windows/awt_Checkbox.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Component.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp index e1dd68a8b50..e59644521ab 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -242,7 +242,7 @@ AwtButton::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) RECT focusRect; VERIFY(::CopyRect(&focusRect, &rect)); VERIFY(::InflateRect(&focusRect,-inf,-inf)); - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp index d038783d5f0..b37207fa2eb 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -290,13 +290,13 @@ AwtCheckbox::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && ((drawInfo.itemAction & ODA_FOCUS)|| (drawInfo.itemAction &ODA_DRAWENTIRE))) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } /* erase focus rect */ else if (!(drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & ODA_FOCUS)) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index c49c2265ca3..b67c5dfcf8d 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4465,7 +4465,7 @@ void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { if (!unfocusableChoice){ - if(::DrawFocusRect(hDC, &rect) == 0) + if (!::IsRectEmpty(&rect) && (::DrawFocusRect(hDC, &rect) == 0)) VERIFY(::GetLastError() == 0); } } From d0cc7994ea67c56ce181da0503bdbf7fccc6f493 Mon Sep 17 00:00:00 2001 From: Ramkumar Sunderbabu <rsunderbabu@openjdk.org> Date: Thu, 9 Jan 2025 07:50:42 +0000 Subject: [PATCH 77/99] 8347083: Incomplete logging in nsk/jvmti/ResourceExhausted/resexhausted00* tests Reviewed-by: dholmes, sspitsyn, lmesnik --- .../nsk/jvmti/ResourceExhausted/resexhausted001.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted002.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted003.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java index b147757f9e0..1009f2d3538 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ public static int run(String args[], PrintStream out) { makeThread(); } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + System.out.println("Test resexhausted001: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + " threadCount=" + threadCount.get()); throw new SkippedException("Test did not get an OutOfMemory error"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java index 46832df7dc3..c1a6e111c9f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted002: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java index f336c1bf3d5..8cc997fa4ab 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted003: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { From d1c97601796a0aba974ea133110e8ca8ca2a74ca Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Thu, 9 Jan 2025 09:49:14 +0000 Subject: [PATCH 78/99] 8347126: gc/stress/TestStressG1Uncommit.java gets OOM-killed Reviewed-by: tschatzl, gli --- test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java index d04f1acf206..0006ad5ad13 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java @@ -57,6 +57,7 @@ public static void main(String[] args) throws Exception { Collections.addAll(options, "-Xlog:gc,gc+heap+region=debug", "-XX:+UseG1GC", + "-Xmx1g", StressUncommit.class.getName() ); OutputAnalyzer output = ProcessTools.executeLimitedTestJava(options); @@ -79,9 +80,9 @@ public static void main(String args[]) throws InterruptedException { // Leave 20% head room to try to avoid Full GCs. long allocationSize = (long) (Runtime.getRuntime().maxMemory() * 0.8); - // Figure out suitable number of workers (~1 per gig). - int gigsOfAllocation = (int) Math.ceil((double) allocationSize / G); - int numWorkers = Math.min(gigsOfAllocation, Runtime.getRuntime().availableProcessors()); + // Figure out suitable number of workers (~1 per 100M). + int allocationChunks = (int) Math.ceil((double) allocationSize / (100 * M)); + int numWorkers = Math.min(allocationChunks, Runtime.getRuntime().availableProcessors()); long workerAllocation = allocationSize / numWorkers; log("Using " + numWorkers + " workers, each allocating: ~" + (workerAllocation / M) + "M"); From 441de37536558cd42b62d22f59378fc04f4de527 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Thu, 9 Jan 2025 10:18:08 +0000 Subject: [PATCH 79/99] 8341097: GHA: Demote Mac x86 jobs to build only Reviewed-by: kbarrett, prr, ihse --- .github/workflows/main.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 210d53be658..3ea07501477 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -325,17 +325,6 @@ jobs: bootjdk-platform: linux-x64 runs-on: ubuntu-22.04 - test-macos-x64: - name: macos-x64 - needs: - - build-macos-x64 - uses: ./.github/workflows/test.yml - with: - platform: macos-x64 - bootjdk-platform: macos-x64 - runs-on: macos-13 - xcode-toolset-version: '14.3.1' - test-macos-aarch64: name: macos-aarch64 needs: From ef8e4af116a82cc20f71bf15e58cca0020e8e660 Mon Sep 17 00:00:00 2001 From: Robbin Ehn <rehn@openjdk.org> Date: Thu, 9 Jan 2025 11:25:37 +0000 Subject: [PATCH 80/99] 8346706: RISC-V: Add available registers to hs_err Reviewed-by: mli, fyang, ihse --- make/autoconf/flags-cflags.m4 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index d33f1885922..c1b873ed0ab 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -830,6 +830,22 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], FLAGS_SETUP_BRANCH_PROTECTION + if test "x$FLAGS_CPU" = xriscv64; then + AC_MSG_CHECKING([if RVV/vector sigcontext supported]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <linux/ptrace.h>], + [ + return (int)sizeof(struct __riscv_v_ext_state); + ])], + [ + AC_MSG_RESULT([yes]) + ], + [ + $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -DNO_RVV_SIGCONTEXT" + AC_MSG_RESULT([no]) + ] + ) + fi + # EXPORT to API CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \ $TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \ From c8259b9c546183e8458523181836f25f51d381e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= <hannesw@openjdk.org> Date: Thu, 9 Jan 2025 11:49:18 +0000 Subject: [PATCH 81/99] 8347121: Add missing @serial tags to module java.base Reviewed-by: alanb --- .../lang/EnumConstantNotPresentException.java | 6 +-- .../classes/java/lang/StackTraceElement.java | 18 ++++----- .../java/lang/TypeNotPresentException.java | 4 +- .../AnnotationTypeMismatchException.java | 4 +- .../IncompleteAnnotationException.java | 6 +-- .../java/lang/invoke/SerializedLambda.java | 22 +++++----- .../classes/java/net/HttpRetryException.java | 6 +-- .../classes/java/net/URISyntaxException.java | 6 +-- .../share/classes/java/net/URLPermission.java | 4 +- .../nio/charset/MalformedInputException.java | 4 +- .../charset/UnmappableCharacterException.java | 4 +- .../java/nio/file/FileSystemException.java | 6 +-- .../java/nio/file/InvalidPathException.java | 6 +-- .../UserPrincipalNotFoundException.java | 4 +- .../java/security/AccessControlException.java | 4 +- .../classes/java/security/AllPermission.java | 4 +- .../classes/java/security/GuardedObject.java | 6 +-- .../share/classes/java/security/KeyPair.java | 6 +-- .../classes/java/security/Permission.java | 4 +- .../java/security/PermissionCollection.java | 4 +- .../classes/java/security/Permissions.java | 3 +- .../classes/java/security/SignedObject.java | 8 ++-- .../classes/java/security/cert/CertPath.java | 6 +-- .../java/security/cert/Certificate.java | 6 +-- .../share/classes/java/text/DateFormat.java | 4 +- .../share/classes/java/time/Duration.java | 6 +-- .../share/classes/java/time/Instant.java | 6 +-- .../share/classes/java/time/LocalDate.java | 8 ++-- .../classes/java/time/LocalDateTime.java | 6 +-- .../share/classes/java/time/LocalTime.java | 10 ++--- .../share/classes/java/time/MonthDay.java | 6 +-- .../classes/java/time/OffsetDateTime.java | 6 +-- .../share/classes/java/time/OffsetTime.java | 6 +-- .../share/classes/java/time/Period.java | 8 ++-- .../share/classes/java/time/Year.java | 4 +- .../share/classes/java/time/YearMonth.java | 6 +-- .../share/classes/java/time/ZoneOffset.java | 4 +- .../classes/java/time/ZonedDateTime.java | 8 ++-- .../time/format/DateTimeParseException.java | 6 +-- .../java/time/temporal/ValueRange.java | 10 ++--- .../java/time/temporal/WeekFields.java | 6 +-- .../java/time/zone/ZoneOffsetTransition.java | 10 ++--- .../time/zone/ZoneOffsetTransitionRule.java | 20 +++++----- .../classes/java/time/zone/ZoneRules.java | 14 +++---- .../share/classes/java/util/AbstractMap.java | 6 ++- .../share/classes/java/util/Arrays.java | 3 +- .../share/classes/java/util/Collections.java | 40 +++++++++++++++++-- .../util/DuplicateFormatFlagsException.java | 3 +- ...ormatFlagsConversionMismatchException.java | 4 +- .../util/IllegalFormatCodePointException.java | 3 +- .../IllegalFormatConversionException.java | 4 +- .../util/IllegalFormatFlagsException.java | 3 +- .../util/IllegalFormatPrecisionException.java | 3 +- .../util/IllegalFormatWidthException.java | 3 +- .../java/util/IllformedLocaleException.java | 3 +- .../util/MissingFormatArgumentException.java | 3 +- .../util/MissingFormatWidthException.java | 3 +- .../classes/java/util/PriorityQueue.java | 6 +-- .../share/classes/java/util/TreeMap.java | 13 ++++-- .../share/classes/java/util/UUID.java | 14 +++---- .../UnknownFormatConversionException.java | 3 +- .../util/UnknownFormatFlagsException.java | 3 +- .../util/concurrent/ArrayBlockingQueue.java | 14 +++---- .../util/concurrent/ConcurrentHashMap.java | 1 + .../concurrent/ConcurrentSkipListMap.java | 12 +++--- .../concurrent/ConcurrentSkipListSet.java | 2 +- .../util/concurrent/CopyOnWriteArraySet.java | 1 + .../util/concurrent/CountedCompleter.java | 4 +- .../java/util/concurrent/ForkJoinTask.java | 1 + .../util/concurrent/LinkedBlockingDeque.java | 8 ++-- .../util/concurrent/LinkedBlockingQueue.java | 12 +++--- .../concurrent/PriorityBlockingQueue.java | 6 +-- .../java/util/concurrent/RecursiveTask.java | 2 +- .../java/util/concurrent/Semaphore.java | 2 +- .../util/concurrent/SynchronousQueue.java | 3 ++ .../util/concurrent/atomic/AtomicBoolean.java | 1 + .../util/concurrent/atomic/AtomicInteger.java | 1 + .../concurrent/atomic/AtomicIntegerArray.java | 1 + .../util/concurrent/atomic/AtomicLong.java | 1 + .../concurrent/atomic/AtomicLongArray.java | 1 + .../concurrent/atomic/AtomicReference.java | 1 + .../atomic/AtomicReferenceArray.java | 1 + .../concurrent/atomic/DoubleAccumulator.java | 2 + .../concurrent/atomic/LongAccumulator.java | 2 + .../locks/AbstractQueuedLongSynchronizer.java | 2 +- .../locks/AbstractQueuedSynchronizer.java | 2 +- .../util/concurrent/locks/ReentrantLock.java | 2 +- .../locks/ReentrantReadWriteLock.java | 8 ++-- .../util/regex/PatternSyntaxException.java | 5 ++- 89 files changed, 301 insertions(+), 222 deletions(-) diff --git a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java index 4ba7cd3b175..cdab2081181 100644 --- a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java +++ b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,12 +42,12 @@ public class EnumConstantNotPresentException extends RuntimeException { private static final long serialVersionUID = -6046998521960521108L; /** - * The type of the missing enum constant. + * @serial The type of the missing enum constant. */ private Class<? extends Enum> enumType; /** - * The name of the missing enum constant. + * @serial The name of the missing enum constant. */ private String constantName; diff --git a/src/java.base/share/classes/java/lang/StackTraceElement.java b/src/java.base/share/classes/java/lang/StackTraceElement.java index ed8d47a4e50..70219a7f6ec 100644 --- a/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,35 +64,35 @@ public final class StackTraceElement implements java.io.Serializable { // Normally initialized by VM /** - * The name of the class loader. + * @serial The name of the class loader. */ private String classLoaderName; /** - * The module name. + * @serial The module name. */ private String moduleName; /** - * The module version. + * @serial The module version. */ private String moduleVersion; /** - * The declaring class. + * @serial The declaring class. */ private String declaringClass; /** - * The method name. + * @serial The method name. */ private String methodName; /** - * The source file name. + * @serial The source file name. */ private String fileName; /** - * The source line number. + * @serial The source line number. */ private int lineNumber; /** - * Control to show full or partial module, package, and class names. + * @serial Control to show full or partial module, package, and class names. */ private byte format = 0; // Default to show all diff --git a/src/java.base/share/classes/java/lang/TypeNotPresentException.java b/src/java.base/share/classes/java/lang/TypeNotPresentException.java index c5a899ef285..5ba43efbc09 100644 --- a/src/java.base/share/classes/java/lang/TypeNotPresentException.java +++ b/src/java.base/share/classes/java/lang/TypeNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ public class TypeNotPresentException extends RuntimeException { private static final long serialVersionUID = -5101214195716534496L; /** - * The type name or the name of a type variable. + * @serial The type name or the name of a type variable. */ private String typeName; diff --git a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index 6a9ea51d10b..83054044b60 100644 --- a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ public class AnnotationTypeMismatchException extends RuntimeException { private final transient Method element; /** - * The (erroneous) type of data found in the annotation. This string + * @serial The (erroneous) type of data found in the annotation. This string * may, but is not required to, contain the value as well. The exact * format of the string is unspecified. */ diff --git a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java index 921d4b92fcd..02f2638c370 100644 --- a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java +++ b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,11 +43,11 @@ public class IncompleteAnnotationException extends RuntimeException { private static final long serialVersionUID = 8445097402741811912L; /** - * The annotation interface. + * @serial The annotation interface. */ private Class<? extends Annotation> annotationType; /** - * The element name. + * @serial The element name. */ private String elementName; diff --git a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java index 3767bf23388..3ffe3c9a9f2 100644 --- a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java +++ b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,43 +65,43 @@ public final class SerializedLambda implements Serializable { @java.io.Serial private static final long serialVersionUID = 8025925345765570181L; /** - * The capturing class. + * @serial The capturing class. */ private final Class<?> capturingClass; /** - * The functional interface class. + * @serial The functional interface class. */ private final String functionalInterfaceClass; /** - * The functional interface method name. + * @serial The functional interface method name. */ private final String functionalInterfaceMethodName; /** - * The functional interface method signature. + * @serial The functional interface method signature. */ private final String functionalInterfaceMethodSignature; /** - * The implementation class. + * @serial The implementation class. */ private final String implClass; /** - * The implementation method name. + * @serial The implementation method name. */ private final String implMethodName; /** - * The implementation method signature. + * @serial The implementation method signature. */ private final String implMethodSignature; /** - * The implementation method kind. + * @serial The implementation method kind. */ private final int implMethodKind; /** - * The instantiated method type. + * @serial The instantiated method type. */ private final String instantiatedMethodType; /** - * The captured arguments. + * @serial The captured arguments. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object[] capturedArgs; diff --git a/src/java.base/share/classes/java/net/HttpRetryException.java b/src/java.base/share/classes/java/net/HttpRetryException.java index fefeb9bb687..6d41ac3b563 100644 --- a/src/java.base/share/classes/java/net/HttpRetryException.java +++ b/src/java.base/share/classes/java/net/HttpRetryException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,12 +40,12 @@ public class HttpRetryException extends IOException { private static final long serialVersionUID = -9186022286469111381L; /** - * The response code. + * @serial The response code. */ private final int responseCode; /** - * The URL to be redirected to. + * @serial The URL to be redirected to. */ private String location; diff --git a/src/java.base/share/classes/java/net/URISyntaxException.java b/src/java.base/share/classes/java/net/URISyntaxException.java index 3b9889cd1b4..c0b0cbdd234 100644 --- a/src/java.base/share/classes/java/net/URISyntaxException.java +++ b/src/java.base/share/classes/java/net/URISyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,12 +42,12 @@ public class URISyntaxException private static final long serialVersionUID = 2137979680897488891L; /** - * The input string. + * @serial The input string. */ private final String input; /** - * The index at which the parse error occurred, + * @serial The index at which the parse error occurred, * or {@code -1} if the index is not known. */ private final int index; diff --git a/src/java.base/share/classes/java/net/URLPermission.java b/src/java.base/share/classes/java/net/URLPermission.java index d48f784ff84..daf3e99a6a0 100644 --- a/src/java.base/share/classes/java/net/URLPermission.java +++ b/src/java.base/share/classes/java/net/URLPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,7 +168,7 @@ public final class URLPermission extends Permission { // serialized field /** - * The actions string + * @serial The actions string */ private String actions; diff --git a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java index c36f81f9153..a4e7f31fc2c 100644 --- a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java +++ b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class MalformedInputException private static final long serialVersionUID = -3438823399834806194L; /** - * The length of the input. + * @serial The length of the input. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java index 857c519974d..8f79a232f03 100644 --- a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java +++ b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class UnmappableCharacterException private static final long serialVersionUID = -7026962371537706123L; /** - * The length of the input character (or byte) sequence. + * @serial The length of the input character (or byte) sequence. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/file/FileSystemException.java b/src/java.base/share/classes/java/nio/file/FileSystemException.java index a03a2708ce6..43887756b15 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystemException.java +++ b/src/java.base/share/classes/java/nio/file/FileSystemException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,12 @@ public class FileSystemException static final long serialVersionUID = -3055425747967319812L; /** - * String identifying the file or {@code null} if not known. + * @serial String identifying the file or {@code null} if not known. */ private final String file; /** - * String identifying the other file or {@code null} if there isn't + * @serial String identifying the other file or {@code null} if there isn't * another file or if not known. */ private final String other; diff --git a/src/java.base/share/classes/java/nio/file/InvalidPathException.java b/src/java.base/share/classes/java/nio/file/InvalidPathException.java index bb28b61b83b..495d087a39d 100644 --- a/src/java.base/share/classes/java/nio/file/InvalidPathException.java +++ b/src/java.base/share/classes/java/nio/file/InvalidPathException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,12 +40,12 @@ public class InvalidPathException static final long serialVersionUID = 4355821422286746137L; /** - * The input string. + * @serial The input string. */ private String input; /** - * The index of the input string at which the error occurred or + * @serial The index of the input string at which the error occurred or * {@code -1} if not known. */ private int index; diff --git a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java index 209453cdaad..9baca303ef0 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java +++ b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ public class UserPrincipalNotFoundException static final long serialVersionUID = -5369283889045833024L; /** - * The user principal name. + * @serial The user principal name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/AccessControlException.java b/src/java.base/share/classes/java/security/AccessControlException.java index 4d46cd6887e..d423d95513d 100644 --- a/src/java.base/share/classes/java/security/AccessControlException.java +++ b/src/java.base/share/classes/java/security/AccessControlException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class AccessControlException extends SecurityException { private static final long serialVersionUID = 5138225684096988535L; /** - * The permission that caused the exception to be thrown. + * @serial The permission that caused the exception to be thrown. */ private Permission perm; diff --git a/src/java.base/share/classes/java/security/AllPermission.java b/src/java.base/share/classes/java/security/AllPermission.java index 15a4f78123f..23c55085ec3 100644 --- a/src/java.base/share/classes/java/security/AllPermission.java +++ b/src/java.base/share/classes/java/security/AllPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -151,7 +151,7 @@ final class AllPermissionCollection private static final long serialVersionUID = -4023755556366636806L; /** - * True if any {@code AllPermissionCollection} objects have been added. + * @serial True if any {@code AllPermissionCollection} objects have been added. */ private boolean all_allowed; diff --git a/src/java.base/share/classes/java/security/GuardedObject.java b/src/java.base/share/classes/java/security/GuardedObject.java index 2c9d1a345dc..fedb0eeae1d 100644 --- a/src/java.base/share/classes/java/security/GuardedObject.java +++ b/src/java.base/share/classes/java/security/GuardedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,13 +55,13 @@ public class GuardedObject implements java.io.Serializable { private static final long serialVersionUID = -5240450096227834308L; /** - * The object we are guarding. + * @serial The object we are guarding. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object object; /** - * The guard object. + * @serial The guard object. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Guard guard; diff --git a/src/java.base/share/classes/java/security/KeyPair.java b/src/java.base/share/classes/java/security/KeyPair.java index 61c1121bdee..cc648a677dd 100644 --- a/src/java.base/share/classes/java/security/KeyPair.java +++ b/src/java.base/share/classes/java/security/KeyPair.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,10 +42,10 @@ public final class KeyPair implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -7565189502268009837L; - /** The private key. */ + /** @serial The private key. */ private final PrivateKey privateKey; - /** The public key. */ + /** @serial The public key. */ private final PublicKey publicKey; /** diff --git a/src/java.base/share/classes/java/security/Permission.java b/src/java.base/share/classes/java/security/Permission.java index 71bad14e395..e066bc0e591 100644 --- a/src/java.base/share/classes/java/security/Permission.java +++ b/src/java.base/share/classes/java/security/Permission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ public abstract class Permission implements Guard, java.io.Serializable { private static final long serialVersionUID = -5636570222231596674L; /** - * The permission name. + * @serial The permission name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/PermissionCollection.java b/src/java.base/share/classes/java/security/PermissionCollection.java index d287a685059..3718744c349 100644 --- a/src/java.base/share/classes/java/security/PermissionCollection.java +++ b/src/java.base/share/classes/java/security/PermissionCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,7 +103,7 @@ public abstract class PermissionCollection implements java.io.Serializable { private static final long serialVersionUID = -6727011328946861783L; /** - * Whether this permission collection is read-only. + * @serial Whether this permission collection is read-only. * <p> * If set, the {@code add} method will throw an exception. */ diff --git a/src/java.base/share/classes/java/security/Permissions.java b/src/java.base/share/classes/java/security/Permissions.java index 3bdeac6f929..ecb18aca8bb 100644 --- a/src/java.base/share/classes/java/security/Permissions.java +++ b/src/java.base/share/classes/java/security/Permissions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,6 +92,7 @@ public final class Permissions extends PermissionCollection // checked private transient boolean hasUnresolved = false; + /** @serial */ // optimization. keep track of the AllPermission collection // - package private for ProtectionDomain optimization PermissionCollection allPermission; diff --git a/src/java.base/share/classes/java/security/SignedObject.java b/src/java.base/share/classes/java/security/SignedObject.java index f65300fc808..d1b203c3aea 100644 --- a/src/java.base/share/classes/java/security/SignedObject.java +++ b/src/java.base/share/classes/java/security/SignedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,18 +122,18 @@ public final class SignedObject implements Serializable { private static final long serialVersionUID = 720502720485447167L; /** - * The original content is "deep copied" in its serialized format + * @serial The original content is "deep copied" in its serialized format * and stored in a byte array. */ private byte[] content; /** - * The signature field is stored as a byte array. + * @serial The signature field is stored as a byte array. */ private byte[] signature; /** - * The algorithm used to sign the object. + * @serial The algorithm used to sign the object. */ private String thealgorithm; diff --git a/src/java.base/share/classes/java/security/cert/CertPath.java b/src/java.base/share/classes/java/security/cert/CertPath.java index 80e68d1c598..ffbbf0291b1 100644 --- a/src/java.base/share/classes/java/security/cert/CertPath.java +++ b/src/java.base/share/classes/java/security/cert/CertPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -301,9 +301,9 @@ protected static class CertPathRep implements Serializable { @java.io.Serial private static final long serialVersionUID = 3015633072427920915L; - /** The type of {@code Certificate}s in the {@code CertPath}. */ + /** @serial The type of {@code Certificate}s in the {@code CertPath}. */ private final String type; - /** The encoded form of the {@code CertPath}. */ + /** @serial The encoded form of the {@code CertPath}. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/security/cert/Certificate.java b/src/java.base/share/classes/java/security/cert/Certificate.java index 1e212f644b3..618026c894d 100644 --- a/src/java.base/share/classes/java/security/cert/Certificate.java +++ b/src/java.base/share/classes/java/security/cert/Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -244,10 +244,10 @@ protected static class CertificateRep implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -8563758940495660020L; - /** The standard name of the certificate type. */ + /** @serial The standard name of the certificate type. */ private final String type; - /** The certificate data. */ + /** @serial The certificate data. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/text/DateFormat.java b/src/java.base/share/classes/java/text/DateFormat.java index e29b3f0509f..af756289086 100644 --- a/src/java.base/share/classes/java/text/DateFormat.java +++ b/src/java.base/share/classes/java/text/DateFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -953,7 +953,7 @@ public static class Field extends Format.Field { private static final Field[] calendarToFieldMapping = new Field[Calendar.FIELD_COUNT]; - /** Calendar field. */ + /** @serial Calendar field. */ private int calendarField; /** diff --git a/src/java.base/share/classes/java/time/Duration.java b/src/java.base/share/classes/java/time/Duration.java index 402ecba7728..d640121f32d 100644 --- a/src/java.base/share/classes/java/time/Duration.java +++ b/src/java.base/share/classes/java/time/Duration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,11 +158,11 @@ private static class Lazy { } /** - * The number of seconds in the duration. + * @serial The number of seconds in the duration. */ private final long seconds; /** - * The number of nanoseconds in the duration, expressed as a fraction of the + * @serial The number of nanoseconds in the duration, expressed as a fraction of the * number of seconds. This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/Instant.java b/src/java.base/share/classes/java/time/Instant.java index 05358cc4f3c..82ff18c1421 100644 --- a/src/java.base/share/classes/java/time/Instant.java +++ b/src/java.base/share/classes/java/time/Instant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,11 +252,11 @@ public final class Instant private static final long serialVersionUID = -665713676816604388L; /** - * The number of seconds from the epoch of 1970-01-01T00:00:00Z. + * @serial The number of seconds from the epoch of 1970-01-01T00:00:00Z. */ private final long seconds; /** - * The number of nanoseconds, later along the time-line, from the seconds field. + * @serial The number of nanoseconds, later along the time-line, from the seconds field. * This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/LocalDate.java b/src/java.base/share/classes/java/time/LocalDate.java index 2d71fb1ceca..caf6ccd6641 100644 --- a/src/java.base/share/classes/java/time/LocalDate.java +++ b/src/java.base/share/classes/java/time/LocalDate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,15 +174,15 @@ public final class LocalDate static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year. + * @serial The month-of-year. */ private final short month; /** - * The day-of-month. + * @serial The day-of-month. */ private final short day; diff --git a/src/java.base/share/classes/java/time/LocalDateTime.java b/src/java.base/share/classes/java/time/LocalDateTime.java index cea9123258c..f8c814957dc 100644 --- a/src/java.base/share/classes/java/time/LocalDateTime.java +++ b/src/java.base/share/classes/java/time/LocalDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,11 +158,11 @@ public final class LocalDateTime private static final long serialVersionUID = 6207766400415563566L; /** - * The date part. + * @serial The date part. */ private final LocalDate date; /** - * The time part. + * @serial The time part. */ private final LocalTime time; diff --git a/src/java.base/share/classes/java/time/LocalTime.java b/src/java.base/share/classes/java/time/LocalTime.java index f28f8d3c599..06f408350ca 100644 --- a/src/java.base/share/classes/java/time/LocalTime.java +++ b/src/java.base/share/classes/java/time/LocalTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,19 +228,19 @@ public final class LocalTime private static final long serialVersionUID = 6414437269572265201L; /** - * The hour. + * @serial The hour. */ private final byte hour; /** - * The minute. + * @serial The minute. */ private final byte minute; /** - * The second. + * @serial The second. */ private final byte second; /** - * The nanosecond. + * @serial The nanosecond. */ private final int nano; diff --git a/src/java.base/share/classes/java/time/MonthDay.java b/src/java.base/share/classes/java/time/MonthDay.java index acb3087a5e5..1de4fa84d3e 100644 --- a/src/java.base/share/classes/java/time/MonthDay.java +++ b/src/java.base/share/classes/java/time/MonthDay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,11 +144,11 @@ public final class MonthDay .toFormatter(); /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; /** - * The day-of-month. + * @serial The day-of-month. */ private final int day; diff --git a/src/java.base/share/classes/java/time/OffsetDateTime.java b/src/java.base/share/classes/java/time/OffsetDateTime.java index fd8355e36cd..6f7005b9fa4 100644 --- a/src/java.base/share/classes/java/time/OffsetDateTime.java +++ b/src/java.base/share/classes/java/time/OffsetDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -190,11 +190,11 @@ private static int compareInstant(OffsetDateTime datetime1, OffsetDateTime datet private static final long serialVersionUID = 2287754244819255394L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/OffsetTime.java b/src/java.base/share/classes/java/time/OffsetTime.java index 1f6feb4180f..ad9781e2459 100644 --- a/src/java.base/share/classes/java/time/OffsetTime.java +++ b/src/java.base/share/classes/java/time/OffsetTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,11 +143,11 @@ public final class OffsetTime private static final long serialVersionUID = 7264499704384272492L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalTime time; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/Period.java b/src/java.base/share/classes/java/time/Period.java index 40cad4cac59..5ee80710edb 100644 --- a/src/java.base/share/classes/java/time/Period.java +++ b/src/java.base/share/classes/java/time/Period.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,15 +155,15 @@ public final class Period private static final List<TemporalUnit> SUPPORTED_UNITS = List.of(YEARS, MONTHS, DAYS); /** - * The number of years. + * @serial The number of years. */ private final int years; /** - * The number of months. + * @serial The number of months. */ private final int months; /** - * The number of days. + * @serial The number of days. */ private final int days; diff --git a/src/java.base/share/classes/java/time/Year.java b/src/java.base/share/classes/java/time/Year.java index cdcaa390320..97264ab8c1c 100644 --- a/src/java.base/share/classes/java/time/Year.java +++ b/src/java.base/share/classes/java/time/Year.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,7 +159,7 @@ public final class Year .toFormatter(); /** - * The year being represented. + * @serial The year being represented. */ private final int year; diff --git a/src/java.base/share/classes/java/time/YearMonth.java b/src/java.base/share/classes/java/time/YearMonth.java index 201c01a2193..8ad1172811f 100644 --- a/src/java.base/share/classes/java/time/YearMonth.java +++ b/src/java.base/share/classes/java/time/YearMonth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,11 +147,11 @@ public final class YearMonth .toFormatter(); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 520a0e0b9a1..48f2a2ded22 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -163,7 +163,7 @@ public final class ZoneOffset public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS); /** - * The total offset in seconds. + * @serial The total offset in seconds. */ private final int totalSeconds; /** diff --git a/src/java.base/share/classes/java/time/ZonedDateTime.java b/src/java.base/share/classes/java/time/ZonedDateTime.java index b1426efc914..135d1a16ae7 100644 --- a/src/java.base/share/classes/java/time/ZonedDateTime.java +++ b/src/java.base/share/classes/java/time/ZonedDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,15 +172,15 @@ public final class ZonedDateTime private static final long serialVersionUID = -6260982410461394882L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; /** - * The time-zone. + * @serial The time-zone. */ private final ZoneId zone; diff --git a/src/java.base/share/classes/java/time/format/DateTimeParseException.java b/src/java.base/share/classes/java/time/format/DateTimeParseException.java index e9dd56b02ff..4bf69fdeb12 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeParseException.java +++ b/src/java.base/share/classes/java/time/format/DateTimeParseException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,11 +82,11 @@ public class DateTimeParseException extends DateTimeException { private static final long serialVersionUID = 4304633501674722597L; /** - * The text that was being parsed. + * @serial The text that was being parsed. */ private final String parsedString; /** - * The error index in the text. + * @serial The error index in the text. */ private final int errorIndex; diff --git a/src/java.base/share/classes/java/time/temporal/ValueRange.java b/src/java.base/share/classes/java/time/temporal/ValueRange.java index 78a13420877..442cf0a2509 100644 --- a/src/java.base/share/classes/java/time/temporal/ValueRange.java +++ b/src/java.base/share/classes/java/time/temporal/ValueRange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,19 +96,19 @@ public final class ValueRange implements Serializable { private static final long serialVersionUID = -7317881728594519368L; /** - * The smallest minimum value. + * @serial The smallest minimum value. */ private final long minSmallest; /** - * The largest minimum value. + * @serial The largest minimum value. */ private final long minLargest; /** - * The smallest maximum value. + * @serial The smallest maximum value. */ private final long maxSmallest; /** - * The largest maximum value. + * @serial The largest maximum value. */ private final long maxLargest; diff --git a/src/java.base/share/classes/java/time/temporal/WeekFields.java b/src/java.base/share/classes/java/time/temporal/WeekFields.java index 9b687017a36..bbad365553d 100644 --- a/src/java.base/share/classes/java/time/temporal/WeekFields.java +++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -247,11 +247,11 @@ public final class WeekFields implements Serializable { private static final long serialVersionUID = -1177360819670808121L; /** - * The first day-of-week. + * @serial The first day-of-week. */ private final DayOfWeek firstDayOfWeek; /** - * The minimal number of days in the first week. + * @serial The minimal number of days in the first week. */ private final int minimalDays; /** diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java index f5d27a0cae0..1e358b9295d 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,19 +104,19 @@ public final class ZoneOffsetTransition */ private static final long serialVersionUID = -6946044323557704546L; /** - * The transition epoch-second. + * @serial The transition epoch-second. */ private final long epochSecond; /** - * The local transition date-time at the transition. + * @serial The local transition date-time at the transition. */ private final LocalDateTime transition; /** - * The offset before transition. + * @serial The offset before transition. */ private final ZoneOffset offsetBefore; /** - * The offset after transition. + * @serial The offset after transition. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java index 8eb232075fe..129aae8c27f 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,12 +105,12 @@ public final class ZoneOffsetTransitionRule implements Serializable { private static final long serialVersionUID = 6889046316657758795L; /** - * The month of the month-day of the first day of the cutover week. + * @serial The month of the month-day of the first day of the cutover week. * The actual date will be adjusted by the dowChange field. */ private final Month month; /** - * The day-of-month of the month-day of the cutover week. + * @serial The day-of-month of the month-day of the cutover week. * If positive, it is the start of the week where the cutover can occur. * If negative, it represents the end of the week where cutover can occur. * The value is the number of days from the end of the month, such that @@ -119,31 +119,31 @@ public final class ZoneOffsetTransitionRule implements Serializable { */ private final byte dom; /** - * The cutover day-of-week, null to retain the day-of-month. + * @serial The cutover day-of-week, null to retain the day-of-month. */ private final DayOfWeek dow; /** - * The cutover time in the 'before' offset. + * @serial The cutover time in the 'before' offset. */ private final LocalTime time; /** - * Whether the cutover time is midnight at the end of day. + * @serial Whether the cutover time is midnight at the end of day. */ private final boolean timeEndOfDay; /** - * The definition of how the local time should be interpreted. + * @serial The definition of how the local time should be interpreted. */ private final TimeDefinition timeDefinition; /** - * The standard offset at the cutover. + * @serial The standard offset at the cutover. */ private final ZoneOffset standardOffset; /** - * The offset before the cutover. + * @serial The offset before the cutover. */ private final ZoneOffset offsetBefore; /** - * The offset after the cutover. + * @serial The offset after the cutover. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneRules.java b/src/java.base/share/classes/java/time/zone/ZoneRules.java index 5945e801f15..788c080fc17 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneRules.java +++ b/src/java.base/share/classes/java/time/zone/ZoneRules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,29 +118,29 @@ public final class ZoneRules implements Serializable { private static final int LAST_CACHED_YEAR = 2100; /** - * The transitions between standard offsets (epoch seconds), sorted. + * @serial The transitions between standard offsets (epoch seconds), sorted. */ private final long[] standardTransitions; /** - * The standard offsets. + * @serial The standard offsets. */ private final ZoneOffset[] standardOffsets; /** - * The transitions between instants (epoch seconds), sorted. + * @serial The transitions between instants (epoch seconds), sorted. */ private final long[] savingsInstantTransitions; /** - * The transitions between local date-times, sorted. + * @serial The transitions between local date-times, sorted. * This is a paired array, where the first entry is the start of the transition * and the second entry is the end of the transition. */ private final LocalDateTime[] savingsLocalTransitions; /** - * The wall offsets. + * @serial The wall offsets. */ private final ZoneOffset[] wallOffsets; /** - * The last rule. + * @serial The last rule. */ private final ZoneOffsetTransitionRule[] lastRules; /** diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index c5ea53e17db..7c0b4d9dd1b 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -587,8 +587,10 @@ public static class SimpleEntry<K,V> @java.io.Serial private static final long serialVersionUID = -8499721149061103585L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private V value; @@ -733,8 +735,10 @@ public static class SimpleImmutableEntry<K,V> @java.io.Serial private static final long serialVersionUID = 7138329143949025153L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final V value; diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 03fdf7a3c99..657b8123ec5 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4189,6 +4189,7 @@ private static class ArrayList<E> extends AbstractList<E> { @java.io.Serial private static final long serialVersionUID = -2764017481108945198L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E[] a; diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 4ec5756f712..2afb94af114 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1054,6 +1054,7 @@ static class UnmodifiableCollection<E> implements Collection<E>, Serializable { @java.io.Serial private static final long serialVersionUID = 1820017752578914078L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection<? extends E> c; @@ -1337,6 +1338,7 @@ static class UnmodifiableSortedSet<E> implements SortedSet<E>, Serializable { @java.io.Serial private static final long serialVersionUID = -4929149591599911165L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet<E> ss; @@ -1419,7 +1421,7 @@ public EmptyNavigableSet() { new EmptyNavigableSet<>(); /** - * The instance we are protecting. + * @serial The instance we are protecting. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet<E> ns; @@ -1488,6 +1490,7 @@ static class UnmodifiableList<E> extends UnmodifiableCollection<E> @java.io.Serial private static final long serialVersionUID = -283967356065247728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List<? extends E> list; @@ -1641,6 +1644,7 @@ private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable { @java.io.Serial private static final long serialVersionUID = -1034234728574286014L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map<? extends K, ? extends V> m; @@ -2068,6 +2072,7 @@ static class UnmodifiableSortedMap<K,V> @java.io.Serial private static final long serialVersionUID = -8806743815996713206L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap<K, ? extends V> sm; @@ -2149,7 +2154,7 @@ public NavigableSet<K> navigableKeySet() new EmptyNavigableMap<>(); /** - * The instance we wrap and protect. + * @serial The instance we wrap and protect. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap<K, ? extends V> nm; @@ -2283,8 +2288,10 @@ static class SynchronizedCollection<E> implements Collection<E>, Serializable { @java.io.Serial private static final long serialVersionUID = 3053995032091335093L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection<E> c; // Backing Collection + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -2487,6 +2494,7 @@ static class SynchronizedSortedSet<E> @java.io.Serial private static final long serialVersionUID = 8695801310862127406L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet<E> ss; @@ -2583,6 +2591,7 @@ static class SynchronizedNavigableSet<E> @java.io.Serial private static final long serialVersionUID = -5505529816273629798L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet<E> ns; @@ -2694,6 +2703,7 @@ static class SynchronizedList<E> @java.io.Serial private static final long serialVersionUID = -7754090372962971524L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List<E> list; @@ -2862,8 +2872,10 @@ private static class SynchronizedMap<K,V> @java.io.Serial private static final long serialVersionUID = 1978198479659022715L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map<K,V> m; // Backing Map + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -3061,6 +3073,7 @@ static class SynchronizedSortedMap<K,V> @java.io.Serial private static final long serialVersionUID = -8798146769416483793L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap<K,V> sm; @@ -3165,6 +3178,7 @@ static class SynchronizedNavigableMap<K,V> @java.io.Serial private static final long serialVersionUID = 699392247599746807L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap<K,V> nm; @@ -3345,8 +3359,10 @@ static class CheckedCollection<E> implements Collection<E>, Serializable { @java.io.Serial private static final long serialVersionUID = 1578914078182001775L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection<E> c; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class<E> type; @@ -3403,6 +3419,7 @@ public void forEachRemaining(Consumer<? super E> action) { public boolean add(E e) { return c.add(typeCheck(e)); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private E[] zeroLengthElementArray; // Lazily initialized @@ -3497,6 +3514,7 @@ static class CheckedQueue<E> { @java.io.Serial private static final long serialVersionUID = 1433151992604707767L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Queue<E> queue; @@ -3602,6 +3620,7 @@ static class CheckedSortedSet<E> extends CheckedSet<E> @java.io.Serial private static final long serialVersionUID = 1599911165492914959L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet<E> ss; @@ -3667,6 +3686,7 @@ static class CheckedNavigableSet<E> extends CheckedSortedSet<E> @java.io.Serial private static final long serialVersionUID = -5429120189805438922L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet<E> ns; @@ -3751,6 +3771,7 @@ static class CheckedList<E> { @java.io.Serial private static final long serialVersionUID = 65247728283967356L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List<E> list; @@ -3901,10 +3922,13 @@ private static class CheckedMap<K,V> @java.io.Serial private static final long serialVersionUID = 5742860141034234728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map<K, V> m; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class<K> keyType; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class<V> valueType; @@ -4301,6 +4325,7 @@ static class CheckedSortedMap<K,V> extends CheckedMap<K,V> @java.io.Serial private static final long serialVersionUID = 1599671320688067438L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap<K, V> sm; @@ -4377,6 +4402,7 @@ static class CheckedNavigableMap<K,V> extends CheckedSortedMap<K,V> @java.io.Serial private static final long serialVersionUID = -4852462692372534096L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap<K, V> nm; @@ -5108,6 +5134,7 @@ private static class SingletonSet<E> @java.io.Serial private static final long serialVersionUID = 3193687207550431679L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5163,6 +5190,7 @@ private static class SingletonList<E> @java.io.Serial private static final long serialVersionUID = 3093736618740652951L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5233,8 +5261,10 @@ private static class SingletonMap<K,V> @java.io.Serial private static final long serialVersionUID = -6979724477215052911L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K k; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V v; @@ -5373,7 +5403,9 @@ private static class CopiesList<E> @java.io.Serial private static final long serialVersionUID = 2739099268398711800L; + /** @serial */ final int n; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final E element; @@ -5914,6 +5946,7 @@ public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { private static class SetFromMap<E> extends AbstractSet<E> implements Set<E>, Serializable { + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map<E, Boolean> m; // The backing map private transient Set<E> s; // Its keySet @@ -6088,6 +6121,7 @@ static class AsLIFOQueue<E> extends AbstractQueue<E> implements Queue<E>, Serializable { @java.io.Serial private static final long serialVersionUID = 1802017725587941708L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Deque<E> q; AsLIFOQueue(Deque<E> q) { this.q = q; } diff --git a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java index ebeb3d5c44c..e84cd9d52e6 100644 --- a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ public non-sealed class DuplicateFormatFlagsException extends IllegalFormatExcep @java.io.Serial private static final long serialVersionUID = 18890531L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java index cca7b3eb553..77d52c5e2ba 100644 --- a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java +++ b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,10 @@ public non-sealed class FormatFlagsConversionMismatchException @java.io.Serial private static final long serialVersionUID = 19120414L; + /** @serial */ private String f; + /** @serial */ private char c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java index 2f1803d220e..c928cd0a3d4 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ public non-sealed class IllegalFormatCodePointException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 19080630L; + /** @serial */ private int c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java index 67237f63cdf..3f2b4512dc6 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,9 @@ public non-sealed class IllegalFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 17000126L; + /** @serial */ private char c; + /** @serial */ private Class<?> arg; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java index 408fa1efa5c..c0770b7153c 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 790824L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java index 4527953790c..dbfb712683f 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatPrecisionException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 18711008L; + /** @serial */ private int p; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java index df8d59b9e81..f22bc61a091 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ public non-sealed class IllegalFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 16660902L; + /** @serial */ private int w; /** diff --git a/src/java.base/share/classes/java/util/IllformedLocaleException.java b/src/java.base/share/classes/java/util/IllformedLocaleException.java index 47febaae018..f4cafe0a943 100644 --- a/src/java.base/share/classes/java/util/IllformedLocaleException.java +++ b/src/java.base/share/classes/java/util/IllformedLocaleException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ public class IllformedLocaleException extends RuntimeException { @java.io.Serial private static final long serialVersionUID = -5245986824925681401L; + /** @serial */ private int _errIdx = -1; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java index 6363566216b..42d15559415 100644 --- a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java +++ b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ public non-sealed class MissingFormatArgumentException extends IllegalFormatExce @java.io.Serial private static final long serialVersionUID = 19190115L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatWidthException.java b/src/java.base/share/classes/java/util/MissingFormatWidthException.java index b553a3876ac..47f787a0c7b 100644 --- a/src/java.base/share/classes/java/util/MissingFormatWidthException.java +++ b/src/java.base/share/classes/java/util/MissingFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class MissingFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 15560123L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 332effeb44b..bacce5ef97e 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,12 +103,12 @@ public class PriorityQueue<E> extends AbstractQueue<E> transient Object[] queue; // non-private to simplify nested class access /** - * The number of elements in the priority queue. + * @serial The number of elements in the priority queue. */ int size; /** - * The comparator, or null if priority queue uses elements' + * @serial The comparator, or null if priority queue uses elements' * natural ordering. */ @SuppressWarnings("serial") // Conditionally serializable diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 1e61136bee4..ab565f371a9 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1656,12 +1656,12 @@ abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V> @java.io.Serial private static final long serialVersionUID = -2102997345730753016L; /** - * The backing map. + * @serial The backing map. */ final TreeMap<K,V> m; /** - * Endpoints are represented as triples (fromStart, lo, + * @serial Endpoints are represented as triples (fromStart, lo, * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is * true, then the low (absolute) bound is the start of the * backing map, and the other values are ignored. Otherwise, @@ -1670,9 +1670,12 @@ abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V> */ @SuppressWarnings("serial") // Conditionally serializable final K lo; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final K hi; + /** @serial */ final boolean fromStart, toEnd; + /** @serial */ final boolean loInclusive, hiInclusive; NavigableSubMap(TreeMap<K,V> m, @@ -2288,6 +2291,7 @@ static final class DescendingSubMap<K,V> extends NavigableSubMap<K,V> { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Comparator<? super K> reverseComparator = Collections.reverseOrder(m.comparator); @@ -2376,9 +2380,12 @@ private class SubMap extends AbstractMap<K,V> implements SortedMap<K,V>, java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -6520786458950516097L; + /** @serial */ private boolean fromStart = false, toEnd = false; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K fromKey; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K toKey; @java.io.Serial diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index e334f7263e4..db0dbe28802 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,17 +83,13 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> { @java.io.Serial private static final long serialVersionUID = -4856846361193249489L; - /* - * The most significant 64 bits of this UUID. - * - * @serial + /** + * @serial The most significant 64 bits of this UUID. */ private final long mostSigBits; - /* - * The least significant 64 bits of this UUID. - * - * @serial + /** + * @serial The least significant 64 bits of this UUID. */ private final long leastSigBits; diff --git a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java index 13d428e0b60..992d9106644 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 19060418L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java index 93eaf85b389..bcd228b7d0f 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 19370506L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index b16f3459601..854bf927464 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -100,17 +100,17 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> */ private static final long serialVersionUID = -817911632652898426L; - /** The queued items */ + /** @serial The queued items */ @SuppressWarnings("serial") // Conditionally serializable final Object[] items; - /** items index for next take, poll, peek or remove */ + /** @serial items index for next take, poll, peek or remove */ int takeIndex; - /** items index for next put, offer, or add */ + /** @serial items index for next put, offer, or add */ int putIndex; - /** Number of elements in the queue */ + /** @serial Number of elements in the queue */ int count; /* @@ -118,14 +118,14 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * found in any textbook. */ - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock; - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty; - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 53919011c6f..0cabc63f36e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4611,6 +4611,7 @@ public final boolean retainAll(Collection<?> c) { public static final class KeySetView<K,V> extends CollectionView<K,V,K> implements Set<K>, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V value; KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 6a60a2397ce..bcfdd997102 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -2401,19 +2401,19 @@ static final class SubMap<K,V> extends AbstractMap<K,V> implements ConcurrentNavigableMap<K,V>, Serializable { private static final long serialVersionUID = -7647078645895051609L; - /** Underlying map */ + /** @serial Underlying map */ final ConcurrentSkipListMap<K,V> m; - /** lower bound key, or null if from start */ + /** @serial lower bound key, or null if from start */ @SuppressWarnings("serial") // Conditionally serializable private final K lo; - /** upper bound key, or null if to end */ + /** @serial upper bound key, or null if to end */ @SuppressWarnings("serial") // Conditionally serializable private final K hi; - /** inclusion flag for lo */ + /** @serial inclusion flag for lo */ private final boolean loInclusive; - /** inclusion flag for hi */ + /** @serial inclusion flag for hi */ private final boolean hiInclusive; - /** direction */ + /** @serial direction */ final boolean isDescending; // Lazily initialized view holders diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 0bcb7978e90..649eaa563c7 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -99,7 +99,7 @@ public class ConcurrentSkipListSet<E> private static final long serialVersionUID = -2479143111061671589L; /** - * The underlying map. Uses Boolean.TRUE as value for each + * @serial The underlying map. Uses Boolean.TRUE as value for each * element. This field is declared final for the sake of thread * safety, which entails some ugliness in clone(). */ diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index ab48a44c97a..cef1682b0b1 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -99,6 +99,7 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E> implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; + /** @serial */ private final CopyOnWriteArrayList<E> al; /** diff --git a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java index 7884a131ffb..3ca7a5ab9c9 100644 --- a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java +++ b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java @@ -427,9 +427,9 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> { private static final long serialVersionUID = 5232453752276485070L; - /** This task's completer, or null if none */ + /** @serial This task's completer, or null if none */ final CountedCompleter<?> completer; - /** The number of pending tasks until completion */ + /** @serial The number of pending tasks until completion */ volatile int pending; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java index 7c1e974aafa..6062a0f6455 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java @@ -278,6 +278,7 @@ final boolean casNext(Aux c, Aux v) { // used only in cancellation static final int UNCOMPENSATE = 1 << 16; // helpJoin sentinel // Fields + /** @serial */ volatile int status; // accessed directly by pool and workers private transient volatile Aux aux; // either waiters or thrown Exception diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 7b6523021dc..b22786a09f6 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -152,17 +152,17 @@ static final class Node<E> { /** Number of items in the deque */ private transient int count; - /** Maximum number of items in the deque */ + /** @serial Maximum number of items in the deque */ private final int capacity; - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock = new ReentrantLock(); - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = lock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index a67be9a987d..4f627d0ff5e 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -134,10 +134,10 @@ static class Node<E> { Node(E x) { item = x; } } - /** The capacity bound, or Integer.MAX_VALUE if none */ + /** @serial The capacity bound, or Integer.MAX_VALUE if none */ private final int capacity; - /** Current number of elements */ + /** @serial Current number of elements */ private final AtomicInteger count = new AtomicInteger(); /** @@ -152,17 +152,17 @@ static class Node<E> { */ private transient Node<E> last; - /** Lock held by take, poll, etc */ + /** @serial Lock held by take, poll, etc */ private final ReentrantLock takeLock = new ReentrantLock(); - /** Wait queue for waiting takes */ + /** @serial Wait queue for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = takeLock.newCondition(); - /** Lock held by put, offer, etc */ + /** @serial Lock held by put, offer, etc */ private final ReentrantLock putLock = new ReentrantLock(); - /** Wait queue for waiting puts */ + /** @serial Wait queue for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = putLock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index f51e356736d..ebaecaa525d 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -160,12 +160,12 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E> private transient Comparator<? super E> comparator; /** - * Lock used for all public operations. + * @serial Lock used for all public operations. */ private final ReentrantLock lock = new ReentrantLock(); /** - * Condition for blocking when empty. + * @serial Condition for blocking when empty. */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); @@ -176,7 +176,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E> private transient volatile int allocationSpinLock; /** - * A plain PriorityQueue used only for serialization, + * @serial A plain PriorityQueue used only for serialization, * to maintain compatibility with previous versions * of this class. Non-null only during serialization/deserialization. */ diff --git a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java index e143760bbc7..4760234c25e 100644 --- a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java +++ b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java @@ -84,7 +84,7 @@ public abstract class RecursiveTask<V> extends ForkJoinTask<V> { public RecursiveTask() {} /** - * The result of the computation. + * @serial The result of the computation. */ @SuppressWarnings("serial") // Conditionally serializable V result; diff --git a/src/java.base/share/classes/java/util/concurrent/Semaphore.java b/src/java.base/share/classes/java/util/concurrent/Semaphore.java index 5c299659d6a..0e7a9ccc0b3 100644 --- a/src/java.base/share/classes/java/util/concurrent/Semaphore.java +++ b/src/java.base/share/classes/java/util/concurrent/Semaphore.java @@ -161,7 +161,7 @@ */ public class Semaphore implements java.io.Serializable { private static final long serialVersionUID = -3222578661600680210L; - /** All mechanics via AbstractQueuedSynchronizer subclass */ + /** @serial All mechanics via AbstractQueuedSynchronizer subclass */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index f5a2ce4d9b4..49efe5d5c2c 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -555,8 +555,11 @@ static class LifoWaitQueue extends WaitQueue { static class FifoWaitQueue extends WaitQueue { private static final long serialVersionUID = -3623113410248163686L; } + /** @serial */ private ReentrantLock qlock; + /** @serial */ private WaitQueue waitingProducers; + /** @serial */ private WaitQueue waitingConsumers; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index fb171e9c1d9..0cae4266b42 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -55,6 +55,7 @@ public class AtomicBoolean implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", int.class); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 4ebd758ccc7..90b4791f05a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -63,6 +63,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index 7e253ead335..3757f30372f 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -51,6 +51,7 @@ public class AtomicIntegerArray implements java.io.Serializable { private static final long serialVersionUID = 2862133569453604235L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(int[].class); + /** @serial */ private final int[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java index d0e50b0fda8..81c60305a2a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -63,6 +63,7 @@ public class AtomicLong extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicLong.class, "value"); + /** @serial */ private volatile long value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index 2145c795799..1486b309640 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -51,6 +51,7 @@ public class AtomicLongArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(long[].class); + /** @serial */ private final long[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java index 1d7268609d7..27df942134c 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -55,6 +55,7 @@ public class AtomicReference<V> implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", Object.class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private volatile V value; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index dbec6b81dd9..ff4e9fa7355 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -55,6 +55,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { private static final long serialVersionUID = -6209656149925076980L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(Object[].class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Object[] array; // must have exact type Object[] diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java index eb837a0fd29..47da669acce 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java @@ -84,8 +84,10 @@ public class DoubleAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final DoubleBinaryOperator function; + /** @serial */ private final long identity; // use long representation /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java index 0d48a686cf2..20e69a5f0ce 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java @@ -82,8 +82,10 @@ public class LongAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final LongBinaryOperator function; + /** @serial */ private final long identity; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 95ac1b2e46f..bdb81f3cb60 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -152,7 +152,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile long state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 6794bab3110..5d899ffb0c5 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -532,7 +532,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile int state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java index 3378ce3983a..d0ad4cae428 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java @@ -108,7 +108,7 @@ */ public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; - /** Synchronizer providing all implementation mechanics */ + /** @serial Synchronizer providing all implementation mechanics */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index 517708e70f3..cc9b75a7e37 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -217,11 +217,11 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; - /** Inner class providing readlock */ + /** @serial Inner class providing readlock */ private final ReentrantReadWriteLock.ReadLock readerLock; - /** Inner class providing writelock */ + /** @serial Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; - /** Performs all synchronization mechanics */ + /** @serial Performs all synchronization mechanics */ final Sync sync; /** @@ -713,6 +713,7 @@ final boolean readerShouldBlock() { */ public static class ReadLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -5992448646407690164L; + /** @serial */ private final Sync sync; /** @@ -927,6 +928,7 @@ public String toString() { */ public static class WriteLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -4992448646407690164L; + /** @serial */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java index 2b5da62f5bd..578a97754df 100644 --- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java +++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,11 @@ public class PatternSyntaxException @java.io.Serial private static final long serialVersionUID = -3864639126226059218L; + /** @serial */ private final String desc; + /** @serial */ private final String pattern; + /** @serial */ private final int index; /** From 4a082c8930ad63d172f0fcdc215903a7d942433e Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn <sspitsyn@openjdk.org> Date: Thu, 9 Jan 2025 12:02:25 +0000 Subject: [PATCH 82/99] 8346460: NotifyFramePop should return JVMTI_ERROR_DUPLICATE Reviewed-by: cjplummer, amenkov --- .../MethodExitTest/libMethodExitTest.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp index b7077b10c81..f5e2b267a9f 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -452,13 +452,25 @@ VirtualThreadMount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", ++vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_mounted_count, cname, mname, (void*)thread); + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); err = jvmti->NotifyFramePop(thread, 0); check_jvmti_status(jni, err, "VirtualThreadMount: error in JVMTI NotifyFramePop"); - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling duplicated FramePop for method: %s::%s on virtual thread: %p\n", + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); + + err = jvmti->NotifyFramePop(thread, 0); + if (err == JVMTI_ERROR_DUPLICATE) { + LOG("NotifyFramePop at VirtualThreadUnmount event returned expected JVMTI_ERROR_DUPLICATE\n"); + } else { + LOG("Failed: NotifyFramePop at VirtualThreadUnmount returned %s(%d) instead of expected JVMTI_ERROR_DUPLICATE\n", + TranslateError(err), err); + jni->FatalError("NotifyFramePop error: expected error code JVMTI_ERROR_DUPLICATE"); + } // Test SetThreadLocalStorage for virtual thread. err = jvmti->SetThreadLocalStorage(thread, tls_data2); @@ -497,13 +509,7 @@ VirtualThreadUnmount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); - LOG("\nHit #%d: VirtualThreadUnmount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_unmounted_count, cname, mname, (void*)thread); - - err = jvmti->NotifyFramePop(thread, 0); - check_jvmti_status(jni, err, "VirtualThreadUnmount: error in JVMTI NotifyFramePop"); - - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", vthread_unmounted_count); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", ++vthread_unmounted_count); deallocate(jvmti, jni, (void*)mname); deallocate(jvmti, jni, (void*)cname); From 972c881bfa95f104572ac0acc3acb8e2f8892df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nordstr=C3=B6m?= <jnordstrom@openjdk.org> Date: Thu, 9 Jan 2025 12:41:52 +0000 Subject: [PATCH 83/99] 8345782: Refining the cases that libjsig deprecation warning is issued Reviewed-by: dholmes, kevinw --- src/java.base/unix/native/libjsig/jsig.c | 23 ++++-- test/hotspot/jtreg/runtime/signal/README | 5 +- .../jtreg/runtime/signal/SigTestDriver.java | 72 +++++++++++++++---- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/java.base/unix/native/libjsig/jsig.c b/src/java.base/unix/native/libjsig/jsig.c index ebb4d698946..5dfc56208c1 100644 --- a/src/java.base/unix/native/libjsig/jsig.c +++ b/src/java.base/unix/native/libjsig/jsig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,6 +47,7 @@ #define MAX_SIGNALS NSIG static struct sigaction sact[MAX_SIGNALS]; /* saved signal handlers */ +static bool deprecated_usage[MAX_SIGNALS]; /* usage of signal/sigset */ static sigset_t jvmsigs; /* Signals used by jvm. */ @@ -69,6 +70,7 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ static bool jvm_signal_installing = false; static bool jvm_signal_installed = false; +static bool warning_printed = false; static void signal_lock() { @@ -89,15 +91,20 @@ static void signal_unlock() { pthread_mutex_unlock(&mutex); } +static void print_deprecation_warning() { + if (!warning_printed) { + warning_printed = true; + fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " + "for signal chaining was deprecated in version 16.0 and will " + "be removed in a future release. Use sigaction() instead.\n"); + } +} + static sa_handler_t call_os_signal(int sig, sa_handler_t disp, bool is_sigset) { sa_handler_t res; if (os_signal == NULL) { - // Deprecation warning first time through - fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " - "for signal chaining was deprecated in version 16.0 and will " - "be removed in a future release. Use sigaction() instead.\n"); if (!is_sigset) { os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal"); } else { @@ -140,8 +147,11 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { signal_lock(); + deprecated_usage[sig] = true; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { + print_deprecation_warning(); /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ if (is_sigset) { @@ -250,6 +260,9 @@ JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction * * within the JVM_begin_signal_setting-JVM_end_signal_setting-window. There can be any number of non-modifying * calls, but they will only return the expected preexisting handler if executed before the modifying call. */ + if (deprecated_usage[sig] == true) { + print_deprecation_warning(); + } res = call_os_sigaction(sig, act, &oldAct); if (res == 0) { if (act != NULL) { diff --git a/test/hotspot/jtreg/runtime/signal/README b/test/hotspot/jtreg/runtime/signal/README index 7109a0bed5b..d051bbd0ed0 100644 --- a/test/hotspot/jtreg/runtime/signal/README +++ b/test/hotspot/jtreg/runtime/signal/README @@ -1,4 +1,4 @@ -Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,9 @@ Also 2 different ways of setting signal handlers are tested: sigaction, sigset. For 'postpre' and 'postpro' libjsig.so is used to chain signal handlers behind VM installed ones. +When libjsig.so is used, the warning for deprecated usage of signal/sigset is checked. For this +purpose, all scenarios are also run once with libjsig preloaded. + => Current tests cover the following cases (don't count 'nojvm' scenario): 1. Support for pre-installed signal handlers when the HotSpot VM is created. 2. Support for signal handler installation after the HotSpot VM is created inside JNI code diff --git a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java index f2b37af1c39..58c8d40f09c 100644 --- a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java +++ b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,12 +91,16 @@ public static void main(String[] args) { .subList(1, args.length); cmd.addAll(argList); + String failureMessage = null; boolean passed = true; for (String mode : new String[] {"sigset", "sigaction"}) { - for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre", "postpost"}) { + // Scenarios postpre and postpost requires libjsig. + // The other scenarios are run with libjsig to validate the deprecation warning. + for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre#libjsig", "postpost#libjsig", + "nojvm#libjsig", "prepre#libjsig", "prepost#libjsig", }) { cmd.set(modeIdx, mode); - cmd.set(scenarioIdx, scenario); + cmd.set(scenarioIdx, scenario.replace("#libjsig", "")); System.out.printf("START TESTING: SIGNAL = %s, MODE = %s, SCENARIO=%s%n", signame, mode, scenario); System.out.printf("Do execute: %s%n", cmd.toString()); @@ -105,12 +109,10 @@ public static void main(String[] args) { (x, y) -> y + File.pathSeparator + x); pb.environment().put("CLASSPATH", Utils.TEST_CLASS_PATH); - switch (scenario) { - case "postpre": - case "postpost": { - pb.environment().merge("LD_PRELOAD", libjsig().toString(), - (x, y) -> y + File.pathSeparator + x); - } + boolean useLibjsig = scenario.endsWith("#libjsig"); + if (useLibjsig) { + pb.environment().merge("LD_PRELOAD", libjsig().toString(), + (x, y) -> y + File.pathSeparator + x); } try { @@ -118,11 +120,35 @@ public static void main(String[] args) { oa.reportDiagnosticSummary(); int exitCode = oa.getExitValue(); if (exitCode == 0) { - System.out.println("PASSED with exit code 0"); + // Skip deprecation warning check on MacOSX (see JDK-8346381) + if (useLibjsig && !Platform.isOSX()) { + // verify that deprecation warning for sigset/signal is printed + // only in the correct scenarios + boolean deprecatedSigFunctionUsed = mode.equals("sigset"); + boolean jvmInvolved = !scenario.contains("nojvm"); + boolean warningPrinted = oa.contains("VM warning"); + boolean sigUsedByJVM = sigIsUsedByJVM(signame); + if (deprecatedSigFunctionUsed && jvmInvolved && sigUsedByJVM) { + if (!warningPrinted) { + failureMessage = "FAILED: Missing deprecation warning for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else if (warningPrinted) { + failureMessage = "FAILED: Deprecation warning shouldn't be printed for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else { + System.out.println("PASSED with exit code 0"); + } } else { - System.out.println("FAILED with exit code " + exitCode); + failureMessage = "FAILED with exit code " + exitCode; passed = false; } + if (!passed) { + System.out.println(failureMessage); + } } catch (Exception e) { throw new Error("execution failed", e); } @@ -130,7 +156,7 @@ public static void main(String[] args) { } if (!passed) { - throw new Error("test failed"); + throw new Error(failureMessage != null ? failureMessage : "test failed"); } } @@ -146,4 +172,26 @@ private static List<String> vmargs() { private static Path libjsig() { return Platform.jvmLibDir().resolve(Platform.buildSharedLibraryName("jsig")); } + + /** + * Return true for the chainable signals that are used by the JVM. + * See src/hotspot/os/posix/signals_posix.cpp + * @param signame + * @return true if signal is used by JVM, false otherwise + */ + private static boolean sigIsUsedByJVM(String signame) { + switch(signame) { + case "SIGSEGV": + case "SIGPIPE": + case "SIGBUS": + case "SIGILL": + case "SIGFPE": + case "SIGXFSZ": + return true; + case "SIGTRAP": + return Platform.isPPC(); + default: + return false; + } + } } From e35e294265fb39600b2cc807bfaa116adcc7bbff Mon Sep 17 00:00:00 2001 From: Andrey Turbanov <aturbanov@openjdk.org> Date: Thu, 9 Jan 2025 12:47:47 +0000 Subject: [PATCH 84/99] 8346036: Unnecessary Hashtable usage in javax.swing.text.html.parser.Entity Reviewed-by: aivanov, azvegint --- .../javax/swing/text/html/parser/Entity.java | 41 +++++++------------ 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java index 8631a6897a7..0b2a9b013af 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,7 @@ package javax.swing.text.html.parser; -import java.util.Hashtable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.CharArrayReader; -import java.net.URL; +import java.util.Map; /** * An entity is described in a DTD using the ENTITY construct. @@ -40,8 +34,7 @@ * @see DTD * @author Arthur van Hoff */ -public final -class Entity implements DTDConstants { +public final class Entity implements DTDConstants { /** * The name of the entity. */ @@ -117,20 +110,17 @@ public String getString() { return new String(data); } - - static Hashtable<String, Integer> entityTypes = new Hashtable<String, Integer>(); - - static { - entityTypes.put("PUBLIC", Integer.valueOf(PUBLIC)); - entityTypes.put("CDATA", Integer.valueOf(CDATA)); - entityTypes.put("SDATA", Integer.valueOf(SDATA)); - entityTypes.put("PI", Integer.valueOf(PI)); - entityTypes.put("STARTTAG", Integer.valueOf(STARTTAG)); - entityTypes.put("ENDTAG", Integer.valueOf(ENDTAG)); - entityTypes.put("MS", Integer.valueOf(MS)); - entityTypes.put("MD", Integer.valueOf(MD)); - entityTypes.put("SYSTEM", Integer.valueOf(SYSTEM)); - } + private static final Map<String, Integer> entityTypes = Map.of( + "PUBLIC", PUBLIC, + "CDATA", CDATA, + "SDATA", SDATA, + "PI", PI, + "STARTTAG", STARTTAG, + "ENDTAG", ENDTAG, + "MS", MS, + "MD", MD, + "SYSTEM", SYSTEM + ); /** * Converts <code>nm</code> string to the corresponding @@ -144,7 +134,6 @@ public String getString() { * to "CDATA", if none exists */ public static int name2type(String nm) { - Integer i = entityTypes.get(nm); - return (i == null) ? CDATA : i.intValue(); + return entityTypes.getOrDefault(nm, CDATA); } } From ef56cf08cf88d0d375dbccbbf9b12a539718c2c7 Mon Sep 17 00:00:00 2001 From: Joachim Kern <jkern@openjdk.org> Date: Thu, 9 Jan 2025 14:24:12 +0000 Subject: [PATCH 85/99] 8346880: [aix] java/lang/ProcessHandle/InfoTest.java still fails: "reported cputime less than expected" Reviewed-by: mdoerr, clanger, mbaesken --- .../native/libjava/ProcessHandleImpl_aix.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c index 3568af24ce4..d2c63d31308 100644 --- a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c +++ b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c @@ -162,7 +162,24 @@ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, } pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { - return unix_getParentPidAndTimings(env, pid, total, start); + pid_t the_pid = pid; + struct procentry64 ProcessBuffer; + + if (getprocs64(&ProcessBuffer, sizeof(ProcessBuffer), NULL, sizeof(struct fdsinfo64), &the_pid, 1) <= 0) { + return -1; + } + + // Validate the pid before returning the info + if (kill(pid, 0) < 0) { + return -1; + } + + *total = ((ProcessBuffer.pi_ru.ru_utime.tv_sec + ProcessBuffer.pi_ru.ru_stime.tv_sec) * 1000000000L) + + ((ProcessBuffer.pi_ru.ru_utime.tv_usec + ProcessBuffer.pi_ru.ru_stime.tv_usec)); + + *start = ProcessBuffer.pi_start * (jlong)1000; + + return (pid_t) ProcessBuffer.pi_ppid; } void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { From 56b99d39cbb8c6e9fd35aca8afcb7d94ef70e4b6 Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Thu, 9 Jan 2025 14:46:13 +0000 Subject: [PATCH 86/99] 8347141: Several javac tests compile with an unnecessary -Xlint:-path flag Reviewed-by: vromero, darcy --- test/langtools/tools/javac/6304921/T6304921.java | 2 +- test/langtools/tools/javac/T5048776.java | 4 ++-- test/langtools/tools/javac/T6245591.java | 2 +- test/langtools/tools/javac/T6247324.java | 2 +- test/langtools/tools/javac/processing/TestWarnErrorCount.java | 4 ++-- test/langtools/tools/javac/warnings/DivZero.java | 2 +- test/langtools/tools/javac/warnings/FallThrough.java | 2 +- test/langtools/tools/javac/warnings/Unchecked.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/langtools/tools/javac/6304921/T6304921.java b/test/langtools/tools/javac/6304921/T6304921.java index 51967b69033..feaf568ee90 100644 --- a/test/langtools/tools/javac/6304921/T6304921.java +++ b/test/langtools/tools/javac/6304921/T6304921.java @@ -1,7 +1,7 @@ /* * @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/ * @bug 6304921 - * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java + * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all -Werror T6304921.java */ import java.util.ArrayList; diff --git a/test/langtools/tools/javac/T5048776.java b/test/langtools/tools/javac/T5048776.java index ff3305a9b34..30795020c5a 100644 --- a/test/langtools/tools/javac/T5048776.java +++ b/test/langtools/tools/javac/T5048776.java @@ -1,8 +1,8 @@ /* * @test /nodynamiccopyright/ * @bug 5048776 - * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java - * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all,-path T5048776.java + * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java + * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all T5048776.java */ class A1 { void foo(Object[] args) { } diff --git a/test/langtools/tools/javac/T6245591.java b/test/langtools/tools/javac/T6245591.java index 7e51e37eab8..8b190dfcdc1 100644 --- a/test/langtools/tools/javac/T6245591.java +++ b/test/langtools/tools/javac/T6245591.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6245591 - * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all,-path T6245591.java + * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all T6245591.java */ enum Season { /** @deprecated */ diff --git a/test/langtools/tools/javac/T6247324.java b/test/langtools/tools/javac/T6247324.java index ae971350c47..264827d6dc0 100644 --- a/test/langtools/tools/javac/T6247324.java +++ b/test/langtools/tools/javac/T6247324.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6247324 - * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint -Xlint:-path T6247324.java + * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint T6247324.java */ class Pair<X,Y> { private X x; diff --git a/test/langtools/tools/javac/processing/TestWarnErrorCount.java b/test/langtools/tools/javac/processing/TestWarnErrorCount.java index 1ea2b803609..957bafdab7f 100644 --- a/test/langtools/tools/javac/processing/TestWarnErrorCount.java +++ b/test/langtools/tools/javac/processing/TestWarnErrorCount.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) { "-d", testDir.getPath(), "-processor", myName, // "-XprintRounds", - "-Xlint:all,-path", + "-Xlint:all", "-AerrKind=" + ek, "-AmsgrWarnKind=" + mwk, "-AjavaWarnKind=" + jwk)); diff --git a/test/langtools/tools/javac/warnings/DivZero.java b/test/langtools/tools/javac/warnings/DivZero.java index 2a965f3fbaf..3df7db166d7 100644 --- a/test/langtools/tools/javac/warnings/DivZero.java +++ b/test/langtools/tools/javac/warnings/DivZero.java @@ -3,7 +3,7 @@ * @bug 4759494 4986256 * @compile/ref=DivZero.noLint.out -XDrawDiagnostics DivZero.java * @compile/ref=DivZero.lint.out -Xlint:divzero -XDrawDiagnostics DivZero.java - * @compile/ref=DivZero.lint.out -Xlint:all,-path -XDrawDiagnostics DivZero.java + * @compile/ref=DivZero.lint.out -Xlint:all -XDrawDiagnostics DivZero.java */ class DivZero diff --git a/test/langtools/tools/javac/warnings/FallThrough.java b/test/langtools/tools/javac/warnings/FallThrough.java index 6e5a5eb8bc9..6185c3e0df9 100644 --- a/test/langtools/tools/javac/warnings/FallThrough.java +++ b/test/langtools/tools/javac/warnings/FallThrough.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 4986256 * @compile/ref=FallThrough.noLint.out -XDrawDiagnostics FallThrough.java - * @compile/ref=FallThrough.lintAll.out -Xlint:all,-path -XDrawDiagnostics FallThrough.java + * @compile/ref=FallThrough.lintAll.out -Xlint:all -XDrawDiagnostics FallThrough.java * @compile/ref=FallThrough.lintFallThrough.out -Xlint:fallthrough -XDrawDiagnostics FallThrough.java */ diff --git a/test/langtools/tools/javac/warnings/Unchecked.java b/test/langtools/tools/javac/warnings/Unchecked.java index e64fd760a07..7cd8cbfdfd0 100644 --- a/test/langtools/tools/javac/warnings/Unchecked.java +++ b/test/langtools/tools/javac/warnings/Unchecked.java @@ -3,7 +3,7 @@ * @bug 4986256 * @compile/ref=Unchecked.noLint.out -XDrawDiagnostics Unchecked.java * @compile/ref=Unchecked.lintUnchecked.out -Xlint:unchecked -XDrawDiagnostics Unchecked.java - * @compile/ref=Unchecked.lintAll.out -Xlint:all,-path -XDrawDiagnostics Unchecked.java + * @compile/ref=Unchecked.lintAll.out -Xlint:all -XDrawDiagnostics Unchecked.java */ import java.util.ArrayList; From 6dfa4038c850add90d75d956ecef3316f869bfaa Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Thu, 9 Jan 2025 14:58:12 +0000 Subject: [PATCH 87/99] 8346705: SNI not sent with Java 22+ using java.net.http.HttpClient.Builder#sslParameters Reviewed-by: dfuchs, michaelm --- .../net/http/AbstractAsyncSSLConnection.java | 56 ++++- .../net/httpclient/HttpClientSNITest.java | 214 ++++++++++++++++++ .../test/lib/common/ServerNameMatcher.java | 10 + 3 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/net/httpclient/HttpClientSNITest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java index 7d583266bd3..20f727a9932 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package jdk.internal.net.http; import java.net.InetSocketAddress; +import java.net.http.HttpClient; import java.util.Arrays; import java.util.ArrayDeque; import java.util.List; @@ -75,7 +76,7 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection ServerName serverName, int port, String[] alpn) { super(addr, client); - this.sniServerNames = formSNIServerNames(serverName); + this.sniServerNames = formSNIServerNames(serverName, client); SSLContext context = client.theSSLContext(); sslParameters = createSSLParameters(client, this.sniServerNames, alpn); Log.logParams(sslParameters); @@ -102,6 +103,20 @@ private static boolean contains(String[] rr, String target) { return false; } + /** + * Returns the {@link SSLParameters} to be used by the {@link SSLEngine} for this connection. + * <p> + * The returned {@code SSLParameters} will have its {@link SNIServerName}s set to the given + * {@code sniServerNames}. If {@code alpn} is non-null then the returned {@code SSLParameters} + * will have its {@linkplain SSLParameters#getApplicationProtocols() application layer protocols} + * set to this value. All other parameters in the returned {@code SSLParameters} will be + * copied over from {@link HttpClient#sslParameters()} of the given {@code client}. + * + * @param client the HttpClient + * @param sniServerNames the SNIServerName(s) + * @param alpn the application layer protocols + * @return the SSLParameters to be set on the SSLEngine used by this connection. + */ private static SSLParameters createSSLParameters(HttpClientImpl client, List<SNIServerName> sniServerNames, String[] alpn) { @@ -132,22 +147,39 @@ private static SSLParameters createSSLParameters(HttpClientImpl client, return sslParameters; } - private static List<SNIServerName> formSNIServerNames(final ServerName serverName) { - if (serverName == null) { - return List.of(); - } - if (!serverName.isLiteral()) { - String name = serverName.name(); - if (name != null && name.length() > 0) { + /** + * Returns a list of {@link SNIServerName}s that are expected to be used to + * configure the {@link SSLEngine} used by this connection. + * <p> + * The given {@code serverName} is given preference, and if it is not null and + * is not an IP address literal, then the returned list will contain only one + * {@code SNIServerName} formed out of the {@code serverName}. If {@code serverName} + * is null or is an IP address literal then the {@code SNIServerName}(s) + * configured through {@link HttpClient#sslParameters()} will be returned. If none have + * been configured, then an empty list is returned. + * + * @param serverName the {@link ServerName}, typically computed based on the request URI + * @param client the {@code HttpClient} + * @return a list of {@code SNIServerName}s to be used by the {@code SSLEngine} + * of this connection. + */ + private static List<SNIServerName> formSNIServerNames(final ServerName serverName, + final HttpClientImpl client) { + if (serverName != null && !serverName.isLiteral()) { + final String name = serverName.name(); + if (name != null && !name.isEmpty()) { return List.of(new SNIHostName(name)); } } - return List.of(); + // fallback on any SNIServerName(s) configured through HttpClient.sslParameters() + final SSLParameters clientSSLParams = client.sslParameters(); + final List<SNIServerName> clientConfigured = clientSSLParams.getServerNames(); + return clientConfigured != null ? clientConfigured : List.of(); } - private static SSLEngine createEngine(SSLContext context, String serverName, int port, + private static SSLEngine createEngine(SSLContext context, String peerHost, int port, SSLParameters sslParameters) { - SSLEngine engine = context.createSSLEngine(serverName, port); + SSLEngine engine = context.createSSLEngine(peerHost, port); engine.setUseClientMode(true); engine.setSSLParameters(sslParameters); diff --git a/test/jdk/java/net/httpclient/HttpClientSNITest.java b/test/jdk/java/net/httpclient/HttpClientSNITest.java new file mode 100644 index 00000000000..1505a216593 --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpClientSNITest.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.List; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.httpclient.test.lib.common.ServerNameMatcher; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8346705 + * @summary verify the behaviour of java.net.http.HttpClient + * when sending a Server Name Indication in the TLS + * connections that it establishes for the requests + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.net.URIBuilder + * @run junit HttpClientSNITest + */ +public class HttpClientSNITest { + private static final String RESP_BODY_TEXT = "hello world"; + + private static SSLContext sslContext; + + private static final class Handler implements HttpTestHandler { + + @Override + public void handle(final HttpTestExchange exch) throws IOException { + System.out.println("handling request " + exch.getRequestURI()); + final byte[] respBody = RESP_BODY_TEXT.getBytes(US_ASCII); + exch.sendResponseHeaders(200, respBody.length); + try (final OutputStream os = exch.getResponseBody()) { + os.write(respBody); + } + } + } + + @BeforeAll + static void beforeAll() throws Exception { + sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "could not create a SSLContext"); + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a IP address literal as the host. For one of the request, the HttpClient + * is configured with specific ServerName(s) through HttpClient.sslParameters() + * and for the other request, it isn't. + * The test then verifies that for such requests with a IP address literal as the host, + * the HttpClient sends across the ServerName(s) if any has been configured on the client. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exception { + final String expectedSNI = "non-dns-resolvable.foo.bar.localhost"; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName(expectedSNI))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final String ipLiteral = InetAddress.getLoopbackAddress().getHostAddress(); + final URI reqURI = URIBuilder.newBuilder() + .host(ipLiteral) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse<String> resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + if (sniConfiguredOnClient) { + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } else { + assertFalse(matcher.wasInvoked(), "SNIMatcher was unexpectedly invoked" + + " on the server"); + } + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a hostname (i.e. not a IP address literal) as the host. For one of the request, + * the HttpClient is configured with specific ServerName(s) through + * HttpClient.sslParameters() and for the other request, it isn't. + * The test then verifies that for such requests with a hostname + * (i.e. not a IP address literal) in the request URI, + * the HttpClient never sends ServerName(s) that may have been configured on the + * client and instead it sends the hostname (from the request URI) as the ServerName + * for each of the request. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestResolvedHostName(final boolean sniConfiguredOnClient) throws Exception { + final String resolvedHostName = InetAddress.getLoopbackAddress().getHostName(); + final String expectedSNI = resolvedHostName; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName("does-not-matter"))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final URI reqURI = URIBuilder.newBuilder() + .host(resolvedHostName) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse<String> resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates a HttpsServer configured to use the given SNIMatcher + */ + private static HttpTestServer createServer(final SNIMatcher matcher) throws Exception { + final InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + final int backlog = 0; + final HttpsServer httpsServer = HttpsServer.create(addr, backlog); + final HttpsConfigurator configurator = new HttpsConfigurator(sslContext) { + @Override + public void configure(final HttpsParameters params) { + final SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + // add the SNIMatcher + sslParameters.setSNIMatchers(List.of(matcher)); + params.setSSLParameters(sslParameters); + System.out.println("configured HttpsServer with SNIMatcher: " + matcher); + } + }; + httpsServer.setHttpsConfigurator(configurator); + final HttpTestServer server = HttpTestServer.of(httpsServer); + server.addHandler(new Handler(), "/"); + server.start(); + System.out.println("server started at " + server.getAddress()); + return server; + } +} diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java index 5e7a5790807..47353927e9c 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java @@ -58,6 +58,7 @@ public class ServerNameMatcher extends SNIMatcher { private final Logger debug; private final boolean attemptDNSResolution; private final Set<String> recognizedSNINames; + private volatile boolean invoked; /** * Creates a ServerNameMatcher which recognizes the passed {@code recognizedSNIName} @@ -97,6 +98,7 @@ public ServerNameMatcher(final boolean attemptDNSResolution, */ @Override public boolean matches(final SNIServerName clientRequestedSNI) { + this.invoked = true; Objects.requireNonNull(clientRequestedSNI); if (!SNIHostName.class.isInstance(clientRequestedSNI)) { if (debug.on()) { @@ -128,6 +130,14 @@ public boolean matches(final SNIServerName clientRequestedSNI) { return false; } + /** + * @return true if the {@link #matches(SNIServerName)} method of this SNIMatcher instance + * was invoked at least once, false otherwise. + */ + public boolean wasInvoked() { + return this.invoked; + } + private boolean matchesAfterDNSResolution(final String clientRequestedSNI) { final InetAddress clientRequestedAddr; try { From 2ff1ff3e538e8f0e6abbf69099cd2c5e0c231cfa Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Thu, 9 Jan 2025 15:26:38 +0000 Subject: [PATCH 88/99] 8347171: (dc) java/nio/channels/DatagramChannel/InterruptibleOrNot.java fails with virtual thread factory Reviewed-by: alanb, lmesnik --- .../java/nio/channels/DatagramChannel/InterruptibleOrNot.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java index 794ede84a92..e6fde147bd9 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java +++ b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.function.Executable; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; public class InterruptibleOrNot { // DatagramChannel implementation class @@ -98,6 +99,7 @@ public void testInterruptDuringInterruptibleReceive() throws Exception { */ @Test public void testInterruptBeforeUninterruptibleReceive() throws Exception { + assumeFalse(Thread.currentThread().isVirtual()); try (DatagramChannel dc = boundDatagramChannel(false)) { ByteBuffer buf = ByteBuffer.allocate(100); onReceive(() -> { From dca900ab5ef5db0f510dadc6cc1e6d4c76281d04 Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Thu, 9 Jan 2025 17:34:20 +0000 Subject: [PATCH 89/99] 8283795: Add TLSv1.3 and CNSA 1.0 algorithms to implementation requirements Reviewed-by: jnimeh --- .../classes/java/security/AlgorithmParameters.java | 11 +++++++++-- .../share/classes/java/security/KeyFactory.java | 3 +++ .../classes/java/security/KeyPairGenerator.java | 12 ++++++++---- .../share/classes/java/security/MessageDigest.java | 3 ++- .../share/classes/java/security/Signature.java | 10 +++++++++- src/java.base/share/classes/javax/crypto/Cipher.java | 3 ++- .../share/classes/javax/crypto/KeyAgreement.java | 7 +++++-- .../share/classes/javax/crypto/KeyGenerator.java | 3 ++- .../share/classes/javax/net/ssl/SSLContext.java | 5 +++-- 9 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/java/security/AlgorithmParameters.java b/src/java.base/share/classes/java/security/AlgorithmParameters.java index 1fdb47077cf..7747d642c20 100644 --- a/src/java.base/share/classes/java/security/AlgorithmParameters.java +++ b/src/java.base/share/classes/java/security/AlgorithmParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,12 +48,19 @@ * obtained via a call to {@code getEncoded}. * * <p> Every implementation of the Java platform is required to support the - * following standard {@code AlgorithmParameters} algorithms: + * following standard {@code AlgorithmParameters} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For the + * "RSASSA-PSS" algorithm, implementations must support the parameters in + * parentheses. * <ul> * <li>{@code AES}</li> + * <li>{@code ChaCha20-Poly1305}</li> * <li>{@code DESede}</li> * <li>{@code DiffieHellman}</li> * <li>{@code DSA}</li> + * <li>{@code EC} (secp256r1, secp384r1)</li> + * <li>{@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)</li> * </ul> * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#algorithmparameters-algorithms"> diff --git a/src/java.base/share/classes/java/security/KeyFactory.java b/src/java.base/share/classes/java/security/KeyFactory.java index 5a9394d283b..7c51faf6aa2 100644 --- a/src/java.base/share/classes/java/security/KeyFactory.java +++ b/src/java.base/share/classes/java/security/KeyFactory.java @@ -72,7 +72,10 @@ * <ul> * <li>{@code DiffieHellman}</li> * <li>{@code DSA}</li> + * <li>{@code EC}</li> * <li>{@code RSA}</li> + * <li>{@code RSASSA-PSS}</li> + * <li>{@code X25519}</li> * </ul> * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms"> diff --git a/src/java.base/share/classes/java/security/KeyPairGenerator.java b/src/java.base/share/classes/java/security/KeyPairGenerator.java index 31c3d8d382f..3583248f81e 100644 --- a/src/java.base/share/classes/java/security/KeyPairGenerator.java +++ b/src/java.base/share/classes/java/security/KeyPairGenerator.java @@ -113,12 +113,16 @@ * supply their own implementations of key pair generators. * * <p> Every implementation of the Java platform is required to support the - * following standard {@code KeyPairGenerator} algorithms and keysizes in - * parentheses: + * following standard {@code KeyPairGenerator} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For other + * algorithms, implementations must support the key sizes in parentheses. * <ul> - * <li>{@code DiffieHellman} (1024, 2048, 4096)</li> + * <li>{@code DiffieHellman} (1024, 2048, 3072, 4096)</li> * <li>{@code DSA} (1024, 2048)</li> - * <li>{@code RSA} (1024, 2048, 4096)</li> + * <li>{@code EC} (secp256r1, secp384r1)</li> + * <li>{@code RSA} (1024, 2048, 3072, 4096)</li> + * <li>{@code RSASSA-PSS} (2048, 3072, 4096)</li> + * <li>{@code X25519}</li> * </ul> * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms"> diff --git a/src/java.base/share/classes/java/security/MessageDigest.java b/src/java.base/share/classes/java/security/MessageDigest.java index 46455e184b0..f83c4ed6d3b 100644 --- a/src/java.base/share/classes/java/security/MessageDigest.java +++ b/src/java.base/share/classes/java/security/MessageDigest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,6 +87,7 @@ * <ul> * <li>{@code SHA-1}</li> * <li>{@code SHA-256}</li> + * <li>{@code SHA-384}</li> * </ul> * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms"> diff --git a/src/java.base/share/classes/java/security/Signature.java b/src/java.base/share/classes/java/security/Signature.java index 482db8d4015..006188aac61 100644 --- a/src/java.base/share/classes/java/security/Signature.java +++ b/src/java.base/share/classes/java/security/Signature.java @@ -100,12 +100,20 @@ * supply their own implementations of digital signature algorithms. * * <p> Every implementation of the Java platform is required to support the - * following standard {@code Signature} algorithms: + * following standard {@code Signature} algorithms. For the "RSASSA-PSS" + * algorithm, implementations must support the parameters in parentheses. For + * the "SHA256withECDSA" and "SHA384withECDSA" algorithms, implementations must + * support the curves in parentheses. * <ul> + * <li>{@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)</li> * <li>{@code SHA1withDSA}</li> * <li>{@code SHA256withDSA}</li> + * <li>{@code SHA256withECDSA} (secp256r1)</li> + * <li>{@code SHA384withECDSA} (secp384r1)</li> * <li>{@code SHA1withRSA}</li> * <li>{@code SHA256withRSA}</li> + * <li>{@code SHA384withRSA}</li> * </ul> * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#signature-algorithms"> diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 2cfdcf55823..8187f863b5c 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -148,7 +148,8 @@ * <li>{@code AES/CBC/PKCS5Padding} (128)</li> * <li>{@code AES/ECB/NoPadding} (128)</li> * <li>{@code AES/ECB/PKCS5Padding} (128)</li> - * <li>{@code AES/GCM/NoPadding} (128)</li> + * <li>{@code AES/GCM/NoPadding} (128, 256)</li> + * <li>{@code ChaCha20-Poly1305}</li> * <li>{@code DESede/CBC/NoPadding} (168)</li> * <li>{@code DESede/CBC/PKCS5Padding} (168)</li> * <li>{@code DESede/ECB/NoPadding} (168)</li> diff --git a/src/java.base/share/classes/javax/crypto/KeyAgreement.java b/src/java.base/share/classes/javax/crypto/KeyAgreement.java index 8a055b6d809..5e2ceb185aa 100644 --- a/src/java.base/share/classes/javax/crypto/KeyAgreement.java +++ b/src/java.base/share/classes/javax/crypto/KeyAgreement.java @@ -57,11 +57,14 @@ * specific or as specified by the standard key agreement algorithm. * * <p> Every implementation of the Java platform is required to support the - * following standard {@code KeyAgreement} algorithm: + * following standard {@code KeyAgreement} algorithms. For the "ECDH" + * algorithm, implementations must support the curves in parentheses. * <ul> * <li>{@code DiffieHellman}</li> + * <li>{@code ECDH} (secp256r1, secp384r1)</li> + * <li>{@code X25519}</li> * </ul> - * This algorithm is described in the <a href= + * These algorithms are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#keyagreement-algorithms"> * KeyAgreement section</a> of the * Java Security Standard Algorithm Names Specification. diff --git a/src/java.base/share/classes/javax/crypto/KeyGenerator.java b/src/java.base/share/classes/javax/crypto/KeyGenerator.java index 0826bf2adb5..ad112e6ffeb 100644 --- a/src/java.base/share/classes/javax/crypto/KeyGenerator.java +++ b/src/java.base/share/classes/javax/crypto/KeyGenerator.java @@ -96,7 +96,8 @@ * following standard {@code KeyGenerator} algorithms with the keysizes in * parentheses: * <ul> - * <li>{@code AES} (128)</li> + * <li>{@code AES} (128, 256)</li> + * <li>{@code ChaCha20}</li> * <li>{@code DESede} (168)</li> * <li>{@code HmacSHA1}</li> * <li>{@code HmacSHA256}</li> diff --git a/src/java.base/share/classes/javax/net/ssl/SSLContext.java b/src/java.base/share/classes/javax/net/ssl/SSLContext.java index 0c2087efa88..861c7645b73 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLContext.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLContext.java @@ -39,11 +39,12 @@ * secure random bytes. * * <p> Every implementation of the Java platform is required to support the - * following standard {@code SSLContext} protocol: + * following standard {@code SSLContext} protocols: * <ul> * <li>{@code TLSv1.2}</li> + * <li>{@code TLSv1.3}</li> * </ul> - * This protocol is described in the <a href= + * These protocols are described in the <a href= * "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms"> * SSLContext section</a> of the * Java Security Standard Algorithm Names Specification. From a7a88cdbc527beac029317869c146e4e5ab5d427 Mon Sep 17 00:00:00 2001 From: Henry Jen <henryjen@openjdk.org> Date: Thu, 9 Jan 2025 17:36:15 +0000 Subject: [PATCH 90/99] 8321413: IllegalArgumentException: Code length outside the allowed range while creating a jlink image Reviewed-by: mchung --- .../jdk/tools/jlink/internal/Snippets.java | 464 ++++++++ .../plugins/ModuleDescriptorBuilder.java | 389 +++++++ .../internal/plugins/SystemModulesPlugin.java | 990 ++++-------------- test/jdk/tools/jlink/JLink20000Packages.java | 129 +++ test/jdk/tools/jlink/SnippetsTest.java | 271 +++++ 5 files changed, 1475 insertions(+), 768 deletions(-) create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java create mode 100644 test/jdk/tools/jlink/JLink20000Packages.java create mode 100644 test/jdk/tools/jlink/SnippetsTest.java diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java new file mode 100644 index 00000000000..d662e297f9a --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jlink.internal; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +import static java.lang.classfile.ClassFile.ACC_STATIC; +import java.lang.classfile.TypeKind; +import java.lang.constant.ConstantDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_Set; +import static java.lang.constant.ConstantDescs.CD_int; +import java.util.function.Function; + +public class Snippets { + /** + * Snippet of bytecodes + */ + @FunctionalInterface + public interface Snippet { + /** + * Emit the bytecode snippet to the CodeBuilder. + * + * @param cob The CodeBuilder + */ + void emit(CodeBuilder cob); + + /** + * Load a constant onto the operand stack. + */ + static <T extends ConstantDesc> Snippet loadConstant(T v) { + return cob -> cob.loadConstant(v); + } + + /** + * Load an enum constant onto the operand stack. + */ + static Snippet loadEnum(Enum<?> e) { + var classDesc = e.getClass().describeConstable().get(); + return cob -> cob.getstatic(classDesc, e.name(), classDesc); + } + + /** + * Load an Integer, boxed int value onto the operand stack. + */ + static Snippet loadInteger(int value) { + return cob -> + cob.loadConstant(value) + .invokestatic(CD_Integer, "valueOf", MethodTypeDesc.of(CD_Integer, CD_int)); + } + + /** + * Build snippets each to process the corresponding element. + * @param elements The elements to be processed + * @param fn The snippet building function for a given element + * @return Snippets + */ + static <T> Snippet[] buildAll(Collection<T> elements, Function<T, Snippet> fn) { + return elements.stream() + .map(fn) + .toArray(Snippet[]::new); + } + } + + /** + * Describe an operand that can be load onto the operand stack. + * For example, an array of string can be described as a Loadable. + * + * @param classDesc The type of the operand + * @param load The snippet to load the operand onto the operand stack + */ + public record Loadable(ClassDesc classDesc, Snippet load) implements Snippet { + /** + * Generate the bytecode to load the Loadable onto the operand stack. + * @param cob The CodeBuilder to add the bytecode for loading + */ + @Override + public void emit(CodeBuilder cob) { + load.emit(cob); + } + } + + /** + * Build a snippet for an element with a given index. Typically used for elements in a + * collection to identify the specific element. + */ + @FunctionalInterface + public interface IndexedElementSnippetBuilder<T> { + /** + * Build a snippet for the element at the index. + * @param element The element + * @param index The index of the element in the containing collection + * @return A snippet of bytecodes to process the element + */ + Snippet build(T element, int index); + + default Snippet[] buildAll(Collection<T> elements) { + var loadElementSnippets = new ArrayList<Snippet>(elements.size()); + for (var element: elements) { + loadElementSnippets.add(build(element, loadElementSnippets.size())); + } + + assert(loadElementSnippets.size() == elements.size()); + return loadElementSnippets.toArray(Snippet[]::new); + } + } + + /** + * Some basic information about pagination. + * @param total The total count of elements + * @param pageSize the number or elements to be included in a page + */ + public static record PagingContext(int total, int pageSize) { + /** + * If the last page has less elements than given page size. + */ + public boolean isLastPagePartial() { + return (total % pageSize) != 0; + } + + /** + * The number of pages. + */ + public int pageCount() { + var pages = total / pageSize; + return isLastPagePartial() ? pages + 1 : pages; + } + + /** + * The number of elements in the last page. + */ + public int lastPageSize() { + if (total == 0) return 0; + var remaining = total % pageSize; + return remaining == 0 ? pageSize : remaining; + } + } + + /** + * Generate bytecodes for loading a collection of elements, support using pagination to avoid + * overloading the 64k code limit. + */ + public static abstract class CollectionSnippetBuilder { + /** + * Default page size of string array + */ + public static final int STRING_PAGE_SIZE = 8000; + + /** + * Default page size of enum array + */ + public static final int ENUM_PAGE_SIZE = 5000; + + /** + * Good enough for average ~30 bytes per element + */ + public static final int DEFAULT_PAGE_SIZE = 2000; + + /** + * Default threshold based on 15K code size on ~30 bytes per element + */ + protected static final int DEFAULT_THRESHOLD = 512; + + protected ClassDesc elementType; + protected ClassDesc ownerClassDesc; + protected ClassBuilder clb; + + // Default values, disable pagination by default + protected String methodNamePrefix = null; + protected int activatePagingThreshold = -1; + protected int pageSize = DEFAULT_PAGE_SIZE; + + /** + * @param elementType The element type + */ + protected CollectionSnippetBuilder(ClassDesc elementType) { + this.elementType = Objects.requireNonNull(elementType); + } + + /** + * Enable pagination if the count of elements is larger than the given threshold. + * + * @param methodNamePrefix The method name prefix for generated paging helper methods + * @param pageSize The page size + * @param threshold The element count to actiave the pagination + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize, int threshold) { + return this.pageSize(pageSize) + .activatePagingThreshold(threshold) + .methodNamePrefix(methodNamePrefix); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize) { + return enablePagination(methodNamePrefix, pageSize, Math.min(pageSize, DEFAULT_THRESHOLD)); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + * with page size DEFAULT_PAGE_SIZE. + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix) { + return enablePagination(methodNamePrefix, DEFAULT_PAGE_SIZE, DEFAULT_THRESHOLD); + } + + /** + * Disable pagination. Generated bytecode will always try to construct the collection inline. + */ + public CollectionSnippetBuilder disablePagination() { + this.activatePagingThreshold = -1; + this.methodNamePrefix = null; + return this; + } + + /** + * Set the threshold of element count to enable pagination. + * + * @param activatePagingThreshold Use pagination methods if the count of elements is larger + * than the given value + */ + public CollectionSnippetBuilder activatePagingThreshold(int activatePagingThreshold) { + if (activatePagingThreshold <= 0) { + throw new IllegalArgumentException(); + } + this.activatePagingThreshold = activatePagingThreshold; + return this; + } + + /** + * Set the owner class host the pagination methods. + * + * @param ownerClassDesc The owner class for the pagination methods + */ + public CollectionSnippetBuilder ownerClassDesc(ClassDesc ownerClassDesc) { + this.ownerClassDesc = Objects.requireNonNull(ownerClassDesc); + return this; + } + + /** + * Set the method name prefix for the pagination methods. + * @param methodNamePrefix The method name prefix. Generated method will have the name of + * this value appended with page number + */ + public CollectionSnippetBuilder methodNamePrefix(String methodNamePrefix) { + this.methodNamePrefix = Objects.requireNonNull(methodNamePrefix); + if (methodNamePrefix.isBlank()) { + throw new IllegalArgumentException(); + } + return this; + } + + /** + * Set the page size. The max page size is STRING_PAGE_SIZE. + * @param pageSize The count of elements per page* + */ + public CollectionSnippetBuilder pageSize(int pageSize) { + // ldc is likely the smallest element snippet + if (pageSize <= 0 || pageSize > STRING_PAGE_SIZE) { + throw new IllegalArgumentException(); + } + + this.pageSize = pageSize; + return this; + } + + /** + * Set the class builder used to generate the pagination methods. + * + * This value must be set if pagination is needed, otherwise the build + * would lead to NullPointerException. + */ + public CollectionSnippetBuilder classBuilder(ClassBuilder clb) { + this.clb = Objects.requireNonNull(clb); + return this; + } + + protected boolean shouldPaginate(int length) { + return methodNamePrefix != null && activatePagingThreshold > 0 && length > activatePagingThreshold; + } + + /** + * Build the Loadable snippet to load the collection of elements onto + * the operand stack. When pagination is enabled and needed as the total + * count of elements is larger than the given threshold, missing + * required field will lead to NullPointerException. + * + * @param loadElementSnippets The array of Snippets used to load individual + * element in the collection. + * @return The Loadable snippet + * @throws NullPointerException + */ + abstract public Loadable build(Snippet[] loadElementSnippets); + } + + /** + * Generate bytecode to load an array of the given referene type onto the operand stack. + * + * The generated code will create an array inline, and then populate the array either inline or + * by invoking the first pagination method if pagination is activated. + * + * If pagination is activated, pagination methods are generated with the given ClassBuilder + * with method name formatted with the methodNamePrefix appended with page numberand. + * Each pagination method will assign value to the corresponding page and chain calling next page. + * + * Effectively as + * methodNamePrefix_0(new T[elements.size()]); + * + * where + * T[] methodNamePrefix_0(T[] ar) { + * ar[0] = elements[0]; + * ar[1] = elements[1]; + * ... + * ar[pageSize-1] = elements[pageSize - 1]; + * methodNamePrefix_1(ar); + * return ar; + * } + * and the last page will stop the chain and can be partial instead of full page size. + */ + public static class ArraySnippetBuilder extends CollectionSnippetBuilder { + final MethodTypeDesc MTD_PageHelper; + final ClassDesc classDesc; + Snippet[] loadElementSnippets; + + public ArraySnippetBuilder(ClassDesc elementType) { + super(elementType); + classDesc = elementType.arrayType(); + MTD_PageHelper = MethodTypeDesc.of(classDesc, classDesc); + } + + protected void fill(CodeBuilder cob, int fromIndex, int toIndex) { + for (var index = fromIndex; index < toIndex; index++) { + cob.dup() // arrayref + .loadConstant(index); + loadElementSnippets[index].emit(cob); // value + cob.aastore(); + } + } + + private void invokePageHelper(CodeBuilder cob) { + // Invoke the first page, which will call next page until fulfilled + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType) + .invokestatic(ownerClassDesc, methodNamePrefix + "_0", MTD_PageHelper); + } + + private void newArray(CodeBuilder cob) { + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType); + fill(cob, 0, loadElementSnippets.length); + } + + /** + * Generate helper methods to fill each page + */ + private void setupHelpers() { + Objects.requireNonNull(clb); + Objects.requireNonNull(methodNamePrefix); + Objects.requireNonNull(ownerClassDesc); + var lastPageNo = new PagingContext(loadElementSnippets.length, pageSize).pageCount() - 1; + for (int pageNo = 0; pageNo <= lastPageNo; pageNo++) { + genFillPageHelper(pageNo, pageNo < lastPageNo); + } + } + + // each helper function is T[] methodNamePrefix_{pageNo}(T[]) + // fill the page portion and chain calling to fill next page + private void genFillPageHelper(int pageNo, boolean hasNextPage) { + var fromIndex = pageSize * pageNo; + var toIndex = hasNextPage ? (fromIndex + pageSize) : loadElementSnippets.length; + clb.withMethodBody(methodNamePrefix + "_" + pageNo, + MTD_PageHelper, + ACC_STATIC, + cob -> { + cob.aload(0); // arrayref + fill(cob, fromIndex, toIndex); + if (hasNextPage) { + cob.invokestatic( + ownerClassDesc, + methodNamePrefix + "_" + (pageNo + 1), + MTD_PageHelper); + } + cob.return_(TypeKind.from(classDesc)); + }); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + this.loadElementSnippets = Objects.requireNonNull(loadElementSnippets); + if (shouldPaginate(loadElementSnippets.length)) { + setupHelpers(); + return new Loadable(classDesc, this::invokePageHelper); + } else { + return new Loadable(classDesc, this::newArray); + } + } + } + + /** + * Generate bytecodes to load a set onto the operand stack. + * + * The Set is constructed with Set::of method. When there are more than 2 + * elements in the set, an array is constructed. + */ + public static class SetSnippetBuilder extends ArraySnippetBuilder { + public SetSnippetBuilder(ClassDesc elementType) { + super(elementType); + } + + private void buildTinySet(CodeBuilder cob) { + for (var snippet: loadElementSnippets) { + snippet.emit(cob); + } + var mtdArgs = new ClassDesc[loadElementSnippets.length]; + Arrays.fill(mtdArgs, CD_Object); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, mtdArgs), true); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + if (loadElementSnippets.length <= 2) { + this.loadElementSnippets = loadElementSnippets; + return new Loadable(CD_Set, this::buildTinySet); + } else { + var array = super.build(loadElementSnippets); + return new Loadable(CD_Set, cob -> { + array.emit(cob); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, CD_Object.arrayType()), true); + }); + } + } + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java new file mode 100644 index 00000000000..dac50c86161 --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jlink.internal.plugins; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.*; + +import java.lang.constant.MethodTypeDesc; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Exports; +import java.lang.module.ModuleDescriptor.Opens; +import java.lang.module.ModuleDescriptor.Provides; +import java.lang.module.ModuleDescriptor.Requires; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.ModuleInfo; +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.SystemModulesClassGenerator.DedupSnippets; + +/** + * Build a Snippet to load a ModuleDescriptor onto the operand stack. + */ +class ModuleDescriptorBuilder implements IndexedElementSnippetBuilder<ModuleInfo> { + private static final ClassDesc CD_MODULE_DESCRIPTOR = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); + private static final ClassDesc CD_MODULE_BUILDER = + ClassDesc.ofInternalName("jdk/internal/module/Builder"); + + private final DedupSnippets dedupSnippets; + private final ClassDesc ownerClassDesc; + private final ClassBuilder clb; + + ModuleDescriptorBuilder(ClassBuilder clb, DedupSnippets dedupSnippets, ClassDesc ownerClassDesc) { + this.clb = clb; + this.dedupSnippets = dedupSnippets; + this.ownerClassDesc = ownerClassDesc; + } + + @Override + public Snippet build(ModuleInfo moduleInfo, int index) { + return new ModuleDescriptorSnippet(clb, moduleInfo.descriptor(), moduleInfo.packages(), index); + } + + class ModuleDescriptorSnippet implements Snippet { + static final ClassDesc CD_EXPORTS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); + static final ClassDesc CD_OPENS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); + static final ClassDesc CD_PROVIDES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); + static final ClassDesc CD_REQUIRES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); + + // method signature for static Builder::newExports, newOpens, + // newProvides, newRequires methods + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); + static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = + MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); + + // method signature for Builder instance methods that + // return this Builder instance + static final MethodTypeDesc MTD_EXPORTS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); + static final MethodTypeDesc MTD_OPENS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); + static final MethodTypeDesc MTD_PROVIDES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); + static final MethodTypeDesc MTD_REQUIRES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); + static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); + static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); + static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); + static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); + static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); + static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); + + final ModuleDescriptor md; + final int index; + final Snippet requiresArray; + final Snippet exportsArray; + final Snippet opensArray; + final Snippet providesArray; + final Snippet packagesSet; + + ModuleDescriptorSnippet(ClassBuilder clb, ModuleDescriptor md, Set<String> packages, int index) { + if (md.isAutomatic()) { + throw new InternalError("linking automatic module is not supported"); + } + + this.md = md; + this.index = index; + requiresArray = buildRequiresArray(clb); + exportsArray = buildExportsArray(clb); + opensArray = buildOpensArray(clb); + providesArray = buildProvidesArray(clb); + packagesSet = buildPackagesSet(clb, packages); + } + + /* + * Invoke Builder.newRequires(Set<Modifier> mods, String mn, String compiledVersion) + * + * Set<Modifier> mods = ... + * Builder.newRequires(mods, mn, compiledVersion); + */ + Snippet loadRequire(Requires require) { + return cob -> { + dedupSnippets.requiresModifiersSets().get(require.modifiers()).emit(cob); + cob.loadConstant(require.name()); + if (require.compiledVersion().isPresent()) { + cob.loadConstant(require.compiledVersion().get().toString()) + .invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING_STRING); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING); + } + }; + } + + private Snippet buildRequiresArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_REQUIRES) + .enablePagination("module" + index + "Requires") + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .build(Snippet.buildAll(sorted(md.requires()), this::loadRequire)); + } + + /* + * Invoke + * Builder.newExports(Set<Exports.Modifier> ms, String pn, + * Set<String> targets) + * or + * Builder.newExports(Set<Exports.Modifier> ms, String pn) + * + * ms = export.modifiers() + * pn = export.source() + * targets = export.targets() + */ + Snippet loadExports(Exports export) { + return cob -> { + dedupSnippets.exportsModifiersSets().get(export.modifiers()).emit(cob); + cob.loadConstant(export.source()); + var targets = export.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildExportsArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_EXPORTS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Exports") + .build(Snippet.buildAll(sorted(md.exports()), this::loadExports)); + } + + /* + * Invoke + * Builder.newOpens(Set<Opens.Modifier> ms, String pn, + * Set<String> targets) + * or + * Builder.newOpens(Set<Opens.Modifier> ms, String pn) + * + * ms = open.modifiers() + * pn = open.source() + * targets = open.targets() + * Builder.newOpens(mods, pn, targets); + */ + Snippet loadOpens(Opens open) { + return cob -> { + dedupSnippets.opensModifiersSets().get(open.modifiers()).emit(cob); + cob.loadConstant(open.source()); + var targets = open.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildOpensArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_OPENS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Opens") + .build(Snippet.buildAll(sorted(md.opens()), this::loadOpens)); + } + + /* + * Invoke Builder.newProvides(String service, List<String> providers) + * + * service = provide.service() + * providers = List.of(new String[] { provide.providers() } + * Builder.newProvides(service, providers); + */ + private Snippet loadProvides(ClassBuilder clb, Provides provide, int offset) { + return cob -> { + var providersArray = new ArraySnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provider" + offset) + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(provide.providers(), Snippet::loadConstant)); + + cob.loadConstant(provide.service()); + providersArray.emit(cob); + cob.invokestatic(CD_List, + "of", + MTD_List_ObjectArray, + true) + .invokestatic(CD_MODULE_BUILDER, + "newProvides", + MTD_PROVIDES_STRING_LIST); + }; + } + + private Snippet buildProvidesArray(ClassBuilder clb) { + IndexedElementSnippetBuilder<Provides> builder = (e, i) -> loadProvides(clb, e, i); + return new ArraySnippetBuilder(CD_PROVIDES) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provides") + .build(builder.buildAll(md.provides())); + } + + private Snippet buildPackagesSet(ClassBuilder clb, Collection<String> packages) { + return new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Packages") + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(sorted(packages), Snippet::loadConstant)); + } + + @Override + public void emit(CodeBuilder cob) { + // new jdk.internal.module.Builder + cob.new_(CD_MODULE_BUILDER) + .dup() + .loadConstant(md.name()) + .invokespecial(CD_MODULE_BUILDER, + INIT_NAME, + MTD_void_String); + if (md.isOpen()) { + setModuleBit(cob, "open", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { + setModuleBit(cob, "synthetic", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { + setModuleBit(cob, "mandated", true); + } + + // requires + requiresArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "requires", + MTD_REQUIRES_ARRAY); + + // exports + exportsArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "exports", + MTD_EXPORTS_ARRAY); + + // opens + opensArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "opens", + MTD_OPENS_ARRAY); + + // uses + dedupSnippets.stringSets().get(md.uses()).emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "uses", + MTD_SET); + + // provides + providesArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "provides", + MTD_PROVIDES_ARRAY); + + // all packages + packagesSet.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "packages", + MTD_SET); + + // version + md.version().ifPresent(v -> setModuleProperty(cob, "version", v.toString())); + + // main class + md.mainClass().ifPresent(cn -> setModuleProperty(cob, "mainClass", cn)); + + cob.loadConstant(md.hashCode()) + .invokevirtual(CD_MODULE_BUILDER, + "build", + MTD_ModuleDescriptor_int); + } + + /* + * Invoke Builder.<methodName>(boolean value) + */ + void setModuleBit(CodeBuilder cob, String methodName, boolean value) { + cob.loadConstant(value ? 1 : 0) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_BOOLEAN); + } + + void setModuleProperty(CodeBuilder cob, String methodName, String value) { + cob.loadConstant(value) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_STRING); + } + } + + /** + * Returns a sorted copy of a collection. + * + * This is useful to ensure a deterministic iteration order. + * + * @return a sorted copy of the given collection. + */ + private static <T extends Comparable<T>> List<T> sorted(Collection<T> c) { + var l = new ArrayList<>(c); + Collections.sort(l); + return l; + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java index 1a9404b210d..1c126d7321c 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDesc; import static java.lang.constant.ConstantDescs.*; import java.lang.constant.MethodTypeDesc; import java.lang.module.Configuration; @@ -38,7 +37,6 @@ import java.lang.module.ModuleDescriptor.Opens; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; -import java.lang.module.ModuleDescriptor.Version; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; @@ -46,7 +44,6 @@ import java.lang.reflect.ClassFileFormatVersion; import java.net.URI; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; @@ -60,7 +57,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.function.IntSupplier; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -78,15 +74,22 @@ import java.lang.classfile.ClassBuilder; import java.lang.classfile.ClassFile; import java.lang.classfile.TypeKind; -import static java.lang.classfile.ClassFile.*; import java.lang.classfile.CodeBuilder; +import java.nio.file.Files; +import java.nio.file.Path; + import jdk.tools.jlink.internal.ModuleSorter; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; import jdk.tools.jlink.plugin.ResourcePoolEntry; +import static java.lang.classfile.ClassFile.*; +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.ENUM_PAGE_SIZE; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + /** * Jlink plugin to reconstitute module descriptors and other attributes for system * modules. The plugin generates implementations of SystemModules to avoid parsing @@ -329,6 +332,17 @@ private String genSystemModulesClass(List<ModuleInfo> moduleInfos, SystemModulesClassGenerator generator = new SystemModulesClassGenerator(className, moduleInfos, moduleDescriptorsPerMethod); byte[] bytes = generator.genClassBytes(cf); + // Diagnosis help, can be removed + if (Boolean.parseBoolean(System.getProperty("jlink.dumpSystemModuleClass", "false"))) { + try { + var filePath = Path.of(className + ".class").toAbsolutePath(); + System.err.println("Write " + filePath.toString()); + Files.createDirectories(filePath.getParent()); + Files.write(filePath, bytes); + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } + } String rn = "/java.base/" + className + ".class"; ResourcePoolEntry e = ResourcePoolEntry.create(rn, bytes); out.add(e); @@ -513,14 +527,6 @@ byte[] getBytes() throws IOException { static class SystemModulesClassGenerator { private static final ClassDesc CD_MODULE_DESCRIPTOR = ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); - private static final ClassDesc CD_MODULE_BUILDER = - ClassDesc.ofInternalName("jdk/internal/module/Builder"); - private static final ClassDesc CD_REQUIRES_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires$Modifier"); - private static final ClassDesc CD_EXPORTS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports$Modifier"); - private static final ClassDesc CD_OPENS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens$Modifier"); private static final ClassDesc CD_MODULE_TARGET = ClassDesc.ofInternalName("jdk/internal/module/ModuleTarget"); private static final ClassDesc CD_MODULE_HASHES = @@ -538,16 +544,12 @@ static class SystemModulesClassGenerator { private static final MethodTypeDesc MTD_Map = MethodTypeDesc.of(CD_Map); private static final MethodTypeDesc MTD_MapEntry_Object_Object = MethodTypeDesc.of(CD_Map_Entry, CD_Object, CD_Object); private static final MethodTypeDesc MTD_Map_MapEntryArray = MethodTypeDesc.of(CD_Map, CD_Map_Entry.arrayType()); - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of(CD_Set, CD_Object.arrayType()); private static final int MAX_LOCAL_VARS = 256; - private final int MD_VAR = 1; // variable for ModuleDescriptor private final int MT_VAR = 1; // variable for ModuleTarget private final int MH_VAR = 1; // variable for ModuleHashes - private final int DEDUP_LIST_VAR = 2; - private final int BUILDER_VAR = 3; - private int nextLocalVar = 4; // index to next local variable + private final int BUILDER_VAR = 2; // name of class to generate private final ClassDesc classDesc; @@ -560,8 +562,8 @@ static class SystemModulesClassGenerator { // A builder to create one single Set instance for a given set of // names or modifiers to reduce the footprint // e.g. target modules of qualified exports - private final DedupSetBuilder dedupSetBuilder - = new DedupSetBuilder(this::getNextLocalVar); + private final DedupSetBuilder dedupSetBuilder; + private final ArrayList<Snippet> clinitSnippets = new ArrayList<>(); public SystemModulesClassGenerator(String className, List<ModuleInfo> moduleInfos, @@ -569,13 +571,10 @@ public SystemModulesClassGenerator(String className, this.classDesc = ClassDesc.ofInternalName(className); this.moduleInfos = moduleInfos; this.moduleDescriptorsPerMethod = moduleDescriptorsPerMethod; + this.dedupSetBuilder = new DedupSetBuilder(this.classDesc); moduleInfos.forEach(mi -> dedups(mi.descriptor())); } - private int getNextLocalVar() { - return nextLocalVar++; - } - /* * Adds the given ModuleDescriptor to the system module list. * It performs link-time validation and prepares mapping from various @@ -636,6 +635,9 @@ public byte[] genClassBytes(Configuration cf) { // generate moduleReads genModuleReads(clb, cf); + + // generate static initializer + genClassInitializer(clb); }); } @@ -654,6 +656,19 @@ private void genConstructor(ClassBuilder clb) { .return_()); } + private void genClassInitializer(ClassBuilder clb) { + if (!clinitSnippets.isEmpty()) { + clb.withMethodBody( + CLASS_INIT_NAME, + MTD_void, + ACC_STATIC, + cob -> { + clinitSnippets.forEach(s -> s.emit(cob)); + cob.return_(); + }); + } + } + /** * Generate bytecode for hasSplitPackages method */ @@ -694,146 +709,25 @@ private void genIncubatorModules(ClassBuilder clb) { * Generate bytecode for moduleDescriptors method */ private void genModuleDescriptorsMethod(ClassBuilder clb) { - if (moduleInfos.size() <= moduleDescriptorsPerMethod) { - clb.withMethodBody( - "moduleDescriptors", - MTD_ModuleDescriptorArray, - ACC_PUBLIC, - cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .astore(MD_VAR); - - for (int index = 0; index < moduleInfos.size(); index++) { - ModuleInfo minfo = moduleInfos.get(index); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - index).build(); - } - cob.aload(MD_VAR) - .areturn(); - }); - return; - } - + var dedupSets = dedupSetBuilder.build(clb); + dedupSets.cacheSetupSnippet().ifPresent(clinitSnippets::add); - // Split the module descriptors be created by multiple helper methods. - // Each helper method "subi" creates the maximum N number of module descriptors - // mi, m{i+1} ... - // to avoid exceeding the 64kb limit of method length. Then it will call - // "sub{i+1}" to creates the next batch of module descriptors m{i+n}, m{i+n+1}... - // and so on. During the construction of the module descriptors, the string sets and - // modifier sets are deduplicated (see SystemModulesClassGenerator.DedupSetBuilder) - // and cached in the locals. These locals are saved in an array list so - // that the helper method can restore the local variables that may be - // referenced by the bytecode generated for creating module descriptors. - // Pseudo code looks like this: - // - // void subi(ModuleDescriptor[] mdescs, ArrayList<Object> localvars) { - // // assign localvars to local variables - // var l3 = localvars.get(0); - // var l4 = localvars.get(1); - // : - // // fill mdescs[i] to mdescs[i+n-1] - // mdescs[i] = ... - // mdescs[i+1] = ... - // : - // // save new local variables added - // localvars.add(lx) - // localvars.add(l{x+1}) - // : - // sub{i+i}(mdescs, localvars); - // } - - List<List<ModuleInfo>> splitModuleInfos = new ArrayList<>(); - List<ModuleInfo> currentModuleInfos = null; - for (int index = 0; index < moduleInfos.size(); index++) { - if (index % moduleDescriptorsPerMethod == 0) { - currentModuleInfos = new ArrayList<>(); - splitModuleInfos.add(currentModuleInfos); - } - currentModuleInfos.add(moduleInfos.get(index)); - } - - String helperMethodNamePrefix = "sub"; - ClassDesc arrayListClassDesc = ClassDesc.ofInternalName("java/util/ArrayList"); + var converter = new ModuleDescriptorBuilder(clb, dedupSets, classDesc); + var elementSnippets = converter.buildAll(moduleInfos); + var moduleDescriptors = new ArraySnippetBuilder(CD_MODULE_DESCRIPTOR) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination("sub", moduleDescriptorsPerMethod) + .build(elementSnippets); clb.withMethodBody( "moduleDescriptors", MTD_ModuleDescriptorArray, ACC_PUBLIC, cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .dup() - .astore(MD_VAR); - cob.new_(arrayListClassDesc) - .dup() - .loadConstant(moduleInfos.size()) - .invokespecial(arrayListClassDesc, INIT_NAME, MethodTypeDesc.of(CD_void, CD_int)) - .astore(DEDUP_LIST_VAR); - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + "0", - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ) - .areturn(); + moduleDescriptors.emit(cob); + cob.areturn(); }); - - int dedupVarStart = nextLocalVar; - for (int n = 0, count = 0; n < splitModuleInfos.size(); count += splitModuleInfos.get(n).size(), n++) { - int index = n; // the index of which ModuleInfo being processed in the current batch - int start = count; // the start index to the return ModuleDescriptor array for the current batch - int curDedupVar = nextLocalVar; - clb.withMethodBody( - helperMethodNamePrefix + index, - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc), - ACC_PUBLIC, - cob -> { - if (curDedupVar > dedupVarStart) { - for (int i = dedupVarStart; i < curDedupVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .loadConstant(i - dedupVarStart) - .invokevirtual(arrayListClassDesc, "get", MethodTypeDesc.of(CD_Object, CD_int)) - .astore(i); - } - } - - List<ModuleInfo> currentBatch = splitModuleInfos.get(index); - for (int j = 0; j < currentBatch.size(); j++) { - ModuleInfo minfo = currentBatch.get(j); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - start + j).build(); - } - - if (index < splitModuleInfos.size() - 1) { - if (nextLocalVar > curDedupVar) { - for (int i = curDedupVar; i < nextLocalVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .aload(i) - .invokevirtual(arrayListClassDesc, "add", MethodTypeDesc.of(CD_boolean, CD_Object)) - .pop(); - } - } - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + (index+1), - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ); - } - - cob.return_(); - }); - } } /** @@ -977,6 +871,7 @@ private void generate(ClassBuilder clb, // map of Set -> local Map<Set<String>, Integer> locals; + int setBuilt = 0; // generate code to create the sets that are duplicated if (dedup) { @@ -988,7 +883,7 @@ private void generate(ClassBuilder clb, locals = new HashMap<>(); int index = 1; for (Set<String> s : duplicateSets) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); cob.astore(index); locals.put(s, index); if (++index >= MAX_LOCAL_VARS) { @@ -1015,7 +910,7 @@ private void generate(ClassBuilder clb, // if de-duplicated then load the local, otherwise generate code Integer varIndex = locals.get(s); if (varIndex == null) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); } else { cob.aload(varIndex); } @@ -1040,449 +935,14 @@ private void generate(ClassBuilder clb, /** * Generate code to generate an immutable set. */ - private void genImmutableSet(CodeBuilder cob, Set<String> set) { - int size = set.size(); - - // use Set.of(Object[]) when there are more than 2 elements - // use Set.of(Object) or Set.of(Object, Object) when fewer - if (size > 2) { - cob.loadConstant(size) - .anewarray(CD_String); - int i = 0; - for (String element : sorted(set)) { - cob.dup() - .loadConstant(i) - .loadConstant(element) - .aastore(); - i++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } else { - for (String element : sorted(set)) { - cob.loadConstant(element); - } - var mtdArgs = new ClassDesc[size]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } - } - - class ModuleDescriptorBuilder { - static final ClassDesc CD_EXPORTS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); - static final ClassDesc CD_OPENS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); - static final ClassDesc CD_PROVIDES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); - static final ClassDesc CD_REQUIRES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); - - // method signature for static Builder::newExports, newOpens, - // newProvides, newRequires methods - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); - static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = - MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); - - // method signature for Builder instance methods that - // return this Builder instance - static final MethodTypeDesc MTD_EXPORTS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); - static final MethodTypeDesc MTD_OPENS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); - static final MethodTypeDesc MTD_PROVIDES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); - static final MethodTypeDesc MTD_REQUIRES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); - static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); - static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); - static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); - static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); - static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); - static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); - - final CodeBuilder cob; - final ModuleDescriptor md; - final Set<String> packages; - final int index; - - ModuleDescriptorBuilder(CodeBuilder cob, ModuleDescriptor md, Set<String> packages, int index) { - if (md.isAutomatic()) { - throw new InternalError("linking automatic module is not supported"); - } - this.cob = cob; - this.md = md; - this.packages = packages; - this.index = index; - } - - void build() { - // new jdk.internal.module.Builder - newBuilder(); - - // requires - requires(md.requires()); - - // exports - exports(md.exports()); - - // opens - opens(md.opens()); - - // uses - uses(md.uses()); - - // provides - provides(md.provides()); - - // all packages - packages(packages); - - // version - md.version().ifPresent(this::version); - - // main class - md.mainClass().ifPresent(this::mainClass); - - putModuleDescriptor(); - } - - void newBuilder() { - cob.new_(CD_MODULE_BUILDER) - .dup() - .loadConstant(md.name()) - .invokespecial(CD_MODULE_BUILDER, - INIT_NAME, - MTD_void_String) - .astore(BUILDER_VAR); - - if (md.isOpen()) { - setModuleBit("open", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { - setModuleBit("synthetic", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { - setModuleBit("mandated", true); - } - } - - /* - * Invoke Builder.<methodName>(boolean value) - */ - void setModuleBit(String methodName, boolean value) { - cob.aload(BUILDER_VAR) - .loadConstant(value ? 1 : 0) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_BOOLEAN) - .pop(); - } - - /* - * Put ModuleDescriptor into the modules array - */ - void putModuleDescriptor() { - cob.aload(MD_VAR) - .loadConstant(index) - .aload(BUILDER_VAR) - .loadConstant(md.hashCode()) - .invokevirtual(CD_MODULE_BUILDER, - "build", - MTD_ModuleDescriptor_int) - .aastore(); - } - - /* - * Call Builder::newRequires to create Requires instances and - * then pass it to the builder by calling: - * Builder.requires(Requires[]) - * - */ - void requires(Set<Requires> requires) { - cob.aload(BUILDER_VAR) - .loadConstant(requires.size()) - .anewarray(CD_REQUIRES); - int arrayIndex = 0; - for (Requires require : sorted(requires)) { - String compiledVersion = null; - if (require.compiledVersion().isPresent()) { - compiledVersion = require.compiledVersion().get().toString(); - } - - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newRequires(require.modifiers(), require.name(), compiledVersion); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "requires", - MTD_REQUIRES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newRequires(Set<Modifier> mods, String mn, String compiledVersion) - * - * Set<Modifier> mods = ... - * Builder.newRequires(mods, mn, compiledVersion); - */ - void newRequires(Set<Requires.Modifier> mods, String name, String compiledVersion) { - int varIndex = dedupSetBuilder.indexOfRequiresModifiers(cob, mods); - cob.aload(varIndex) - .loadConstant(name); - if (compiledVersion != null) { - cob.loadConstant(compiledVersion) - .invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING_STRING); - } else { - cob.invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING); - } - } - - /* - * Call Builder::newExports to create Exports instances and - * then pass it to the builder by calling: - * Builder.exports(Exports[]) - * - */ - void exports(Set<Exports> exports) { - cob.aload(BUILDER_VAR) - .loadConstant(exports.size()) - .anewarray(CD_EXPORTS); - int arrayIndex = 0; - for (Exports export : sorted(exports)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newExports(export.modifiers(), export.source(), export.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "exports", - MTD_EXPORTS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newExports(Set<Exports.Modifier> ms, String pn, - * Set<String> targets) - * or - * Builder.newExports(Set<Exports.Modifier> ms, String pn) - * - * Set<String> targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set<Modifier> mods = ... - * Builder.newExports(mods, pn, targets); - */ - void newExports(Set<Exports.Modifier> ms, String pn, Set<String> targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfExportsModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING); - } - } - - - /** - * Call Builder::newOpens to create Opens instances and - * then pass it to the builder by calling: - * Builder.opens(Opens[]) - */ - void opens(Set<Opens> opens) { - cob.aload(BUILDER_VAR) - .loadConstant(opens.size()) - .anewarray(CD_OPENS); - int arrayIndex = 0; - for (Opens open : sorted(opens)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newOpens(open.modifiers(), open.source(), open.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "opens", - MTD_OPENS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newOpens(Set<Opens.Modifier> ms, String pn, - * Set<String> targets) - * or - * Builder.newOpens(Set<Opens.Modifier> ms, String pn) - * - * Set<String> targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set<Modifier> mods = ... - * Builder.newOpens(mods, pn, targets); - */ - void newOpens(Set<Opens.Modifier> ms, String pn, Set<String> targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfOpensModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING); - } - } - - /* - * Invoke Builder.uses(Set<String> uses) - */ - void uses(Set<String> uses) { - int varIndex = dedupSetBuilder.indexOfStringSet(cob, uses); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "uses", - MTD_SET) - .pop(); - } - - /* - * Call Builder::newProvides to create Provides instances and - * then pass it to the builder by calling: - * Builder.provides(Provides[] provides) - * - */ - void provides(Collection<Provides> provides) { - cob.aload(BUILDER_VAR) - .loadConstant(provides.size()) - .anewarray(CD_PROVIDES); - int arrayIndex = 0; - for (Provides provide : sorted(provides)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newProvides(provide.service(), provide.providers()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "provides", - MTD_PROVIDES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newProvides(String service, Set<String> providers) - * - * Set<String> providers = new HashSet<>(); - * providers.add(impl); - * : - * : - * Builder.newProvides(service, providers); - */ - void newProvides(String service, List<String> providers) { - cob.loadConstant(service) - .loadConstant(providers.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (String provider : providers) { - cob.dup() // arrayref - .loadConstant(arrayIndex++) - .loadConstant(provider) - .aastore(); - } - cob.invokestatic(CD_List, - "of", - MTD_List_ObjectArray, - true) - .invokestatic(CD_MODULE_BUILDER, - "newProvides", - MTD_PROVIDES_STRING_LIST); - } - - /* - * Invoke Builder.packages(String pn) - */ - void packages(Set<String> packages) { - int varIndex = dedupSetBuilder.newStringSet(cob, packages); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "packages", - MTD_SET) - .pop(); - } - - /* - * Invoke Builder.mainClass(String cn) - */ - void mainClass(String cn) { - cob.aload(BUILDER_VAR) - .loadConstant(cn) - .invokevirtual(CD_MODULE_BUILDER, - "mainClass", - MTD_STRING) - .pop(); - } - - /* - * Invoke Builder.version(Version v); - */ - void version(Version v) { - cob.aload(BUILDER_VAR) - .loadConstant(v.toString()) - .invokevirtual(CD_MODULE_BUILDER, - "version", - MTD_STRING) - .pop(); - } - - void invokeBuilderMethod(String methodName, String value) { - cob.aload(BUILDER_VAR) - .loadConstant(value) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_STRING) - .pop(); - } + private void genImmutableSet(ClassBuilder clb, CodeBuilder cob, Set<String> set, String methodNamePrefix) { + var snippets = Snippet.buildAll(sorted(set), Snippet::loadConstant); + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination(methodNamePrefix, STRING_PAGE_SIZE) + .build(snippets) + .emit(cob); } class ModuleHashesBuilder { @@ -1577,240 +1037,234 @@ void hashForModule(String name, byte[] hash) { } } + /* + * Snippets to load the deduplicated set onto the operand stack. + * Set referenced more than once will be read from the cache, cacheSetupSnippet contains + * the bytecode to populate that cache. + */ + static record DedupSnippets(Map<Set<String>, Snippet> stringSets, + Map<Set<Requires.Modifier>, Snippet> requiresModifiersSets, + Map<Set<Opens.Modifier>, Snippet> opensModifiersSets, + Map<Set<Exports.Modifier>, Snippet> exportsModifiersSets, + Optional<Snippet> cacheSetupSnippet) {}; + /* * Wraps set creation, ensuring identical sets are properly deduplicated. */ static class DedupSetBuilder { - // map Set<String> to a specialized builder to allow them to be - // deduplicated as they are requested - final Map<Set<String>, SetBuilder<String>> stringSets = new HashMap<>(); - - // map Set<Requires.Modifier> to a specialized builder to allow them to be - // deduplicated as they are requested - final Map<Set<Requires.Modifier>, EnumSetBuilder<Requires.Modifier>> + final Map<Set<String>, RefCounter<String>> stringSets = new HashMap<>(); + final Map<Set<Requires.Modifier>, RefCounter<Requires.Modifier>> requiresModifiersSets = new HashMap<>(); - - // map Set<Exports.Modifier> to a specialized builder to allow them to be - // deduplicated as they are requested - final Map<Set<Exports.Modifier>, EnumSetBuilder<Exports.Modifier>> + final Map<Set<Exports.Modifier>, RefCounter<Exports.Modifier>> exportsModifiersSets = new HashMap<>(); - - // map Set<Opens.Modifier> to a specialized builder to allow them to be - // deduplicated as they are requested - final Map<Set<Opens.Modifier>, EnumSetBuilder<Opens.Modifier>> + final Map<Set<Opens.Modifier>, RefCounter<Opens.Modifier>> opensModifiersSets = new HashMap<>(); - private final int stringSetVar; - private final int enumSetVar; - private final IntSupplier localVarSupplier; + final ClassDesc owner; + final CacheBuilder cacheBuilder = new CacheBuilder(); + int setBuilt = 0; - DedupSetBuilder(IntSupplier localVarSupplier) { - this.stringSetVar = localVarSupplier.getAsInt(); - this.enumSetVar = localVarSupplier.getAsInt(); - this.localVarSupplier = localVarSupplier; + DedupSetBuilder(ClassDesc owner) { + this.owner = owner; } /* * Add the given set of strings to this builder. */ void stringSet(Set<String> strings) { - stringSets.computeIfAbsent(strings, - s -> new SetBuilder<>(s, stringSetVar, localVarSupplier) - ).increment(); + stringSets.computeIfAbsent(strings, RefCounter<String>::new).increment(); } /* * Add the given set of Exports.Modifiers */ void exportsModifiers(Set<Exports.Modifier> mods) { - exportsModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_EXPORTS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + exportsModifiersSets.computeIfAbsent(mods, RefCounter<Exports.Modifier>::new).increment(); } /* * Add the given set of Opens.Modifiers */ void opensModifiers(Set<Opens.Modifier> mods) { - opensModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_OPENS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + opensModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* * Add the given set of Requires.Modifiers */ void requiresModifiers(Set<Requires.Modifier> mods) { - requiresModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_REQUIRES_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + requiresModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* - * Retrieve the index to the given set of Strings. Emit code to - * generate it when SetBuilder::build is called. + * Generate bytecode to load a set onto the operand stack. + * Use cache if the set is referenced more than once. */ - int indexOfStringSet(CodeBuilder cob, Set<String> names) { - return stringSets.get(names).build(cob); + private Snippet buildStringSet(ClassBuilder clb, RefCounter<String> setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, STRING_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadConstant))); } /* - * Retrieve the index to the given set of Exports.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Generate the mapping from a set to the bytecode loading the set onto the operand stack. + * Ordering the sets to ensure same generated bytecode. */ - int indexOfExportsModifiers(CodeBuilder cob, Set<Exports.Modifier> mods) { - return exportsModifiersSets.get(mods).build(cob); + private Map<Set<String>, Snippet> buildStringSets(ClassBuilder clb, Map<Set<String>, RefCounter<String>> map) { + Map<Set<String>, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildStringSet(clb, e.getValue()))); + return snippets; } - /** - * Retrieve the index to the given set of Opens.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + /* + * Enum set support */ - int indexOfOpensModifiers(CodeBuilder cob, Set<Opens.Modifier> mods) { - return opensModifiersSets.get(mods).build(cob); + private <T extends Enum<T>> Snippet buildEnumSet(ClassBuilder clb, RefCounter<T> setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_Object) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, ENUM_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadEnum))); } + private <T extends Enum<T>> Map<Set<T>, Snippet> buildEnumSets(ClassBuilder clb, Map<Set<T>, RefCounter<T>> map) { + Map<Set<T>, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildEnumSet(clb, e.getValue()))); + return snippets; + } /* - * Retrieve the index to the given set of Requires.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Build snippets for all sets and optionally the cache. */ - int indexOfRequiresModifiers(CodeBuilder cob, Set<Requires.Modifier> mods) { - return requiresModifiersSets.get(mods).build(cob); + DedupSnippets build(ClassBuilder clb) { + return new DedupSnippets( + buildStringSets(clb, stringSets), + buildEnumSets(clb, requiresModifiersSets), + buildEnumSets(clb, opensModifiersSets), + buildEnumSets(clb, exportsModifiersSets), + cacheBuilder.build(clb) + ); } /* - * Build a new string set without any attempt to deduplicate it. + * RefCounter count references to the set, and keeps sorted elements to ensure + * generate same bytecode for a given set. + * RefCounter itself needs ordering to ensure generate same bytecode for the cache. */ - int newStringSet(CodeBuilder cob, Set<String> names) { - int index = new SetBuilder<>(names, stringSetVar, localVarSupplier).build(cob); - assert index == stringSetVar; - return index; - } - } + class RefCounter<T extends Comparable<T>> implements Comparable<RefCounter<T>> { + // sorted elements of the set to ensure same generated code + private final List<T> elements; + private int refCount; - /* - * SetBuilder generates bytecode to create one single instance of Set - * for a given set of elements and assign to a local variable slot. - * When there is only one single reference to a Set<T>, - * it will reuse defaultVarIndex. For a Set with multiple references, - * it will use a new local variable retrieved from the nextLocalVar - */ - static class SetBuilder<T extends Comparable<T>> { - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of( - CD_Set, CD_Object.arrayType()); - - private final Set<T> elements; - private final int defaultVarIndex; - private final IntSupplier nextLocalVar; - private int refCount; - private int localVarIndex; - - SetBuilder(Set<T> elements, - int defaultVarIndex, - IntSupplier nextLocalVar) { - this.elements = elements; - this.defaultVarIndex = defaultVarIndex; - this.nextLocalVar = nextLocalVar; - } + RefCounter(Set<T> elements) { + this.elements = sorted(elements); + } - /* - * Increments the number of references to this particular set. - */ - final void increment() { - refCount++; + int increment() { + return ++refCount; + } + + int refCount() { + return refCount; + } + + List<T> sortedList() { + return elements; + } + + @Override + public int compareTo(RefCounter<T> o) { + if (o == this) { + return 0; + } + if (elements.size() == o.elements.size()) { + var a1 = elements; + var a2 = o.elements; + for (int i = 0; i < elements.size(); i++) { + var r = a1.get(i).compareTo(a2.get(i)); + if (r != 0) { + return r; + } + } + return 0; + } else { + return elements.size() - o.elements.size(); + } + } } /** - * Generate the appropriate instructions to load an object reference - * to the element onto the stack. + * Build an array to host sets referenced more than once so a given set will only be constructed once. + * Transform the bytecode for loading the set onto the operand stack as needed. */ - void visitElement(T element, CodeBuilder cob) { - cob.loadConstant((ConstantDesc)element); - } + class CacheBuilder { + private static final String VALUES_ARRAY = "dedupSetValues"; + final ArrayList<Snippet> cachedValues = new ArrayList<>(); + + // Load the set from the cache to the operand stack + // dedupSetValues[index] + private Snippet loadFromCache(int index) { + assert index >= 0; + return cob -> + cob.getstatic(owner, VALUES_ARRAY, CD_Set.arrayType()) + .loadConstant(index) + .aaload(); + } - /* - * Build bytecode for the Set represented by this builder, - * or get the local variable index of a previously generated set - * (in the local scope). - * - * @return local variable index of the generated set. - */ - final int build(CodeBuilder cob) { - int index = localVarIndex; - if (localVarIndex == 0) { - // if non-empty and more than one set reference this builder, - // emit to a unique local - index = refCount <= 1 ? defaultVarIndex - : nextLocalVar.getAsInt(); - if (index < MAX_LOCAL_VARS) { - localVarIndex = index; + /** + * Transform the bytecode for loading the set onto the operand stack. + * @param loadSnippet The origin snippet to load the set onto the operand stack. + */ + Snippet transform(RefCounter<?> setRef, Snippet loadSnippet) { + if (setRef.refCount() > 1) { + cachedValues.add(loadSnippet); + return loadFromCache(cachedValues.size() - 1); } else { - // overflow: disable optimization by using localVarIndex = 0 - index = defaultVarIndex; + return loadSnippet; } - - generateSetOf(cob, index); } - return index; - } - private void generateSetOf(CodeBuilder cob, int index) { - if (elements.size() <= 10) { - // call Set.of(e1, e2, ...) - for (T t : sorted(elements)) { - visitElement(t, cob); + /* + * Returns a snippet that populates the cached values in <clinit>. + * + * The generated cache is essentially as the following: + * + * static final Set[] dedupSetValues; + * + * static { + * dedupSetValues = new Set[countOfStoredValues]; + * dedupSetValues[0] = Set.of(elements); // for inline set + * dedupSetValues[1] = dedupSet<setIndex>_0(); // for paginated set + * ... + * dedupSetValues[countOfStoredValues - 1] = ... + * } + */ + Optional<Snippet> build(ClassBuilder clb) { + if (cachedValues.isEmpty()) { + return Optional.empty(); } - var mtdArgs = new ClassDesc[elements.size()]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } else { - // call Set.of(E... elements) - cob.loadConstant(elements.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (T t : sorted(elements)) { - cob.dup() // arrayref - .loadConstant(arrayIndex); - visitElement(t, cob); // value - cob.aastore(); - arrayIndex++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } - cob.astore(index); - } - } - /* - * Generates bytecode to create one single instance of EnumSet - * for a given set of modifiers and assign to a local variable slot. - */ - static class EnumSetBuilder<T extends Comparable<T>> extends SetBuilder<T> { - private final ClassDesc classDesc; - - EnumSetBuilder(Set<T> modifiers, ClassDesc classDesc, - int defaultVarIndex, - IntSupplier nextLocalVar) { - super(modifiers, defaultVarIndex, nextLocalVar); - this.classDesc = classDesc; - } + var cacheValuesArray = new ArraySnippetBuilder(CD_Set) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination(VALUES_ARRAY) + .build(cachedValues.toArray(Snippet[]::new)); - /** - * Loads an Enum field. - */ - @Override - void visitElement(T t, CodeBuilder cob) { - cob.getstatic(classDesc, t.toString(), classDesc); + clb.withField(VALUES_ARRAY, CD_Set.arrayType(), ACC_STATIC | ACC_FINAL); + + return Optional.of(cob -> { + cacheValuesArray.emit(cob); + cob.putstatic(owner, VALUES_ARRAY, CD_Set.arrayType()); + }); + } } } } diff --git a/test/jdk/tools/jlink/JLink20000Packages.java b/test/jdk/tools/jlink/JLink20000Packages.java new file mode 100644 index 00000000000..865cf7ca98c --- /dev/null +++ b/test/jdk/tools/jlink/JLink20000Packages.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.StringJoiner; +import java.util.spi.ToolProvider; + +import tests.JImageGenerator; + +/* + * @test + * @summary Make sure that ~20000 packages in a uber jar can be linked using jlink. Now that + * pagination is in place, the limitation is on the constant pool size, not number + * of packages. + * @bug 8321413 + * @library ../lib + * @enablePreview + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main/othervm -Xmx1g -Xlog:init=debug -XX:+UnlockDiagnosticVMOptions -XX:+BytecodeVerificationLocal JLink20000Packages + */ +public class JLink20000Packages { + private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac") + .orElseThrow(() -> new RuntimeException("javac tool not found")); + + static void report(String command, String[] args) { + System.out.println(command + " " + String.join(" ", Arrays.asList(args))); + } + + static void javac(String[] args) { + report("javac", args); + JAVAC_TOOL.run(System.out, System.err, args); + } + + public static void main(String[] args) throws Exception { + Path src = Paths.get("bug8321413"); + Path imageDir = src.resolve("out-jlink"); + Path mainModulePath = src.resolve("bug8321413x"); + + StringJoiner mainModuleInfoContent = new StringJoiner(";\n exports ", "module bug8321413x {\n exports ", ";\n}"); + + for (int i = 0; i < 20000; i++) { + String packageName = "p" + i; + String className = "C" + i; + + Path packagePath = Files.createDirectories(mainModulePath.resolve(packageName)); + + StringBuilder classContent = new StringBuilder("package "); + classContent.append(packageName).append(";\n"); + classContent.append("class ").append(className).append(" {}\n"); + Files.writeString(packagePath.resolve(className + ".java"), classContent.toString()); + + mainModuleInfoContent.add(packageName); + } + + // create module reading the generated modules + Path mainModuleInfo = mainModulePath.resolve("module-info.java"); + Files.writeString(mainModuleInfo, mainModuleInfoContent.toString()); + + Path mainClassDir = mainModulePath.resolve("testpackage"); + Files.createDirectories(mainClassDir); + + Files.writeString(mainClassDir.resolve("JLink20000PackagesTest.java"), """ + package testpackage; + + public class JLink20000PackagesTest { + public static void main(String[] args) throws Exception { + System.out.println("JLink20000PackagesTest started."); + } + } + """); + + String out = src.resolve("out").toString(); + javac(new String[]{ + "-d", out, + "--module-source-path", src.toString(), + "--module", "bug8321413x" + }); + + JImageGenerator.getJLinkTask() + .modulePath(out) + .output(imageDir) + .addMods("bug8321413x") + .call() + .assertSuccess(); + + Path binDir = imageDir.resolve("bin").toAbsolutePath(); + Path bin = binDir.resolve("java"); + + ProcessBuilder processBuilder = new ProcessBuilder(bin.toString(), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+BytecodeVerificationLocal", + "-m", "bug8321413x/testpackage.JLink20000PackagesTest"); + processBuilder.inheritIO(); + processBuilder.directory(binDir.toFile()); + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) + throw new AssertionError("JLink20000PackagesTest failed to launch"); + } +} diff --git a/test/jdk/tools/jlink/SnippetsTest.java b/test/jdk/tools/jlink/SnippetsTest.java new file mode 100644 index 00000000000..ec0c94e3d26 --- /dev/null +++ b/test/jdk/tools/jlink/SnippetsTest.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import static java.lang.classfile.ClassFile.ACC_PUBLIC; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_String; +import static java.lang.constant.ConstantDescs.INIT_NAME; +import static java.lang.constant.ConstantDescs.MTD_void; +import java.lang.constant.MethodTypeDesc; +import static java.lang.invoke.MethodHandles.lookup; +import java.lang.invoke.MethodType; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.AccessFlag; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; + +import jdk.tools.jlink.internal.Snippets.*; + +/* + * @test + * @summary Test snippets generation for array and set. + * @bug 8321413 + * @enablePreview + * @modules jdk.jlink/jdk.tools.jlink.internal + * @run junit SnippetsTest + */ +public class SnippetsTest { + private static final boolean WRITE_CLASS_FILE = Boolean.parseBoolean(System.getProperty("DumpArraySnippetsTestClasses", "false")); + + @ParameterizedTest + @ValueSource(ints = { 10, 75, 90, 120, 200, 399, 400, 401}) + void testLoad400StringsArray(int pageSize) { + testPaginatedArray(400, pageSize); + } + + @Test + void testStringArrayLimitsWithPagination() { + // Each string takes 2 constant pool slot, one for String, another for Utf8 + testPaginatedArray(31_000, 8000); + try { + testPaginatedArray(32_000, 8000); + } catch (IllegalArgumentException iae) { + // expected constant pool explode + } + } + + @Test + void testStringArrayLimitsWithoutPagination() { + // each string array assignment takes ~8 bytes + testSimpleArray(8200); + try { + testSimpleArray(8300); + fail(); + } catch (IllegalArgumentException iae) { + // expected code size explode + } + } + + @Test + void testLoadableEnum() { + Enum<?>[] enums = { + AccessFlag.FINAL, + ModuleDescriptor.Requires.Modifier.MANDATED, + ModuleDescriptor.Opens.Modifier.SYNTHETIC, + ModuleDescriptor.Requires.Modifier.TRANSITIVE + }; + + Snippet[] elementSnippets = Snippet.buildAll(Arrays.asList(enums), Snippet::loadEnum); + + var loadable = new ArraySnippetBuilder(Enum.class.describeConstable().get()) + .build(elementSnippets); + + Supplier<Enum<?>[]> supplier = generateSupplier("LoadableEnumTest", clb -> loadable); + assertArrayEquals(enums, supplier.get()); + } + + @Test + void testArraySnippetBuilder() { + Integer[] expected = IntStream.range(0, 200) + .boxed() + .toArray(Integer[]::new); + var className = "LoadableArrayOf200Paged"; + var elementSnippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadInteger); + var instance = new ArraySnippetBuilder(CD_Integer) + .ownerClassDesc(ClassDesc.of(className)) + .enablePagination("page", 100); + + try { + instance.build(elementSnippets); + fail("Should throw NPE without ClassBuilder"); + } catch (NullPointerException npe) { + // expected + } + + Supplier<Integer[]> supplier = generateSupplier(className, clb -> instance.classBuilder(clb).build(elementSnippets)); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 2); + assertArrayEquals(expected, supplier.get()); + + var loadable = instance.disablePagination() + .ownerClassDesc(ClassDesc.of("LoadableArrayOf200NotPaged")) + .build(elementSnippets); + + // SimpleArray generate bytecode inline, so can be generated in any class + supplier = generateSupplier("TestLoadableArrayFactory", clb -> loadable); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + @Test + void testSetSnippetBuilder() { + String[] data = IntStream.range(0, 100) + .mapToObj(i -> "SetData" + i) + .toArray(String[]::new); + + var tiny = Set.of(data[0], data[1], data[2]); + var all = Set.of(data); + var setBuilder = new SetSnippetBuilder(CD_String); + + Supplier<Set<String>> supplier = generateSupplier("TinySetTest", clb -> + setBuilder.build(Snippet.buildAll(tiny, Snippet::loadConstant))); + // Set does not guarantee ordering, so not assertIterableEquals + assertEquals(tiny, supplier.get()); + + var allSnippets = Snippet.buildAll(all, Snippet::loadConstant); + + supplier = generateSupplier("AllSetTestNoPage", clb -> + setBuilder.build(allSnippets)); + assertEquals(all, supplier.get()); + + var className = "AllSetTestPageNotActivated"; + var methodNamePrefix = "page"; + var loadable = setBuilder.disablePagination() + .ownerClassDesc(ClassDesc.of(className)) + .build(allSnippets); + supplier = generateSupplier(className, clb -> loadable); + assertEquals(all, supplier.get()); + + className = "AllSetTestPageSize20"; + setBuilder.ownerClassDesc(ClassDesc.of(className)); + supplier = generateSupplier(className, clb -> setBuilder.classBuilder(clb) + .enablePagination(methodNamePrefix, 20) + .build(allSnippets)); + verifyPaginationMethods(supplier.getClass(), String.class, methodNamePrefix, 5); + assertEquals(all, supplier.get()); + } + + void testPaginatedArray(int elementCount, int pageSize) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "Package" + i) + .toArray(String[]::new); + var className = String.format("SnippetArrayProviderTest%dPagedBy%d", elementCount, pageSize); + ClassDesc testClassDesc = ClassDesc.of(className); + var builder = new ArraySnippetBuilder(CD_String) + .enablePagination("ArrayPage", pageSize, 1) + .ownerClassDesc(testClassDesc); + var snippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant); + var pagingContext = new PagingContext(expected.length, pageSize); + + Supplier<String[]> supplier = generateSupplier(className, clb -> builder.classBuilder(clb).build(snippets)); + verifyPaginationMethods(supplier.getClass(), String.class, "ArrayPage", pagingContext.pageCount()); + assertEquals((elementCount % pageSize) != 0, pagingContext.isLastPagePartial()); + assertArrayEquals(expected, supplier.get()); + } + + void testSimpleArray(int elementCount) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "NoPage" + i) + .toArray(String[]::new); + String className = "SnippetArrayProviderTest" + elementCount; + var array = new ArraySnippetBuilder(CD_String) + .disablePagination() + .build(Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant)); + + Supplier<String[]> supplier = generateSupplier(className, clb -> array); + verifyPaginationMethods(supplier.getClass(), String.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + <T> Supplier<T> generateSupplier(String className, Function<ClassBuilder, Loadable> builder) { + var testClassDesc = ClassDesc.of(className); + byte[] classBytes = generateSupplierClass(testClassDesc, builder); + try { + writeClassFile(className, classBytes); + var testClass = lookup().defineClass(classBytes); + lookup().findVirtual(testClass, "get", MethodType.methodType(Object.class)); + return (Supplier<T>) testClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + void verifyPaginationMethods(Class<?> testClass, Class<?> elementType, String methodNamePrefix, int pageCount) { + var methodType = MethodType.methodType(elementType.arrayType(), elementType.arrayType()); + if (pageCount <= 0) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_0", methodType); + fail("Unexpected paginate helper function"); + } catch (Exception ex) {} + } + + for (int i = 0; i < pageCount; i++) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_" + i, methodType); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + + byte[] generateSupplierClass(ClassDesc testClassDesc, Function<ClassBuilder, Loadable> builder) { + return ClassFile.of().build(testClassDesc, + clb -> { + clb.withSuperclass(CD_Object); + clb.withInterfaceSymbols(ClassDesc.ofInternalName("java/util/function/Supplier")); + clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> { + cob.aload(0); + cob.invokespecial(CD_Object, INIT_NAME, MTD_void); + cob.return_(); + }); + + var loadable = builder.apply(clb); + + clb.withMethodBody("get", MethodTypeDesc.of(CD_Object), ACC_PUBLIC, cob -> { + loadable.emit(cob); + cob.areturn(); + }); + }); + } + + void writeClassFile(String className, byte[] classBytes) throws IOException { + if (WRITE_CLASS_FILE) { + Files.write(Path.of(className + ".class"), classBytes); + } + } +} \ No newline at end of file From 92536e1f15faa4c6636ac2686ce35d7d75e9f94e Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Thu, 9 Jan 2025 18:22:33 +0000 Subject: [PATCH 91/99] 8344907: NullPointerException in Win32ShellFolder2.getSystemIcon when "icon" is null Reviewed-by: aivanov, kizune --- .../sun/awt/shell/Win32ShellFolder2.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 0a4fb12cda6..c85c2d4ced9 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1201,8 +1201,12 @@ public Image getIcon(int width, int height) { */ static Image getSystemIcon(SystemIcon iconType) { long hIcon = getSystemIcon(iconType.getIconID()); + if (hIcon == 0) { + return null; + } + Image icon = makeIcon(hIcon); - if (LARGE_ICON_SIZE != icon.getWidth(null)) { + if (icon != null && LARGE_ICON_SIZE != icon.getWidth(null)) { icon = new MultiResolutionIconImage(LARGE_ICON_SIZE, icon); } disposeIcon(hIcon); @@ -1214,15 +1218,16 @@ static Image getSystemIcon(SystemIcon iconType) { */ static Image getShell32Icon(int iconID, int size) { long hIcon = getIconResource("shell32.dll", iconID, size, size); - if (hIcon != 0) { - Image icon = makeIcon(hIcon); - if (size != icon.getWidth(null)) { - icon = new MultiResolutionIconImage(size, icon); - } - disposeIcon(hIcon); - return icon; + if (hIcon == 0) { + return null; } - return null; + + Image icon = makeIcon(hIcon); + if (icon != null && size != icon.getWidth(null)) { + icon = new MultiResolutionIconImage(size, icon); + } + disposeIcon(hIcon); + return icon; } /** From 73941c9642e724f8273775baba79a118772f984d Mon Sep 17 00:00:00 2001 From: Alisen Chung <achung@openjdk.org> Date: Thu, 9 Jan 2025 20:47:22 +0000 Subject: [PATCH 92/99] 8345144: Robot does not specify all causes of IllegalThreadStateException Reviewed-by: prr --- .../share/classes/java/awt/Robot.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index 8b7506f5f2d..d0877b3bddd 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -58,6 +58,15 @@ * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. * <p> + * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods + * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} + * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} + * which will throw {@code IllegalThreadStateException} when called on the AWT EDT. + * In addition, screen capture operations can be lengthy + * and {@code delay(long ms)} clearly inserts a delay, so these also + * should not be called on the EDT. Taken together, this means that as much as possible, + * methods on this class should not be called on the EDT. + * <p> * Note that some platforms require special privileges or extensions * to access low-level input control. If the current platform configuration * does not allow input control, an {@code AWTException} will be thrown @@ -216,6 +225,8 @@ private static void checkIsScreenDevice(GraphicsDevice device) { * * @param x X position * @param y Y position + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true */ public synchronized void mouseMove(int x, int y) { peer.mouseMove(x, y); @@ -268,6 +279,7 @@ public synchronized void mouseMove(int x, int y) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mouseRelease(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -325,6 +337,7 @@ public synchronized void mousePress(int buttons) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mousePress(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -349,6 +362,8 @@ private static void checkButtonsArgument(int buttons) { * @param wheelAmt number of "notches" to move the mouse wheel * Negative values indicate movement up/away from the user, * positive values indicate movement down/towards the user. + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true * * @since 1.4 */ @@ -368,6 +383,8 @@ public synchronized void mouseWheel(int wheelAmt) { * @param keycode Key to press (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not * a valid key + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true * @see #keyRelease(int) * @see java.awt.event.KeyEvent */ @@ -387,7 +404,9 @@ public synchronized void keyPress(int keycode) { * @param keycode Key to release (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not a * valid key - * @see #keyPress(int) + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true + * @see #keyPress(int) * @see java.awt.event.KeyEvent */ public synchronized void keyRelease(int keycode) { @@ -487,6 +506,12 @@ public synchronized BufferedImage createScreenCapture(Rectangle screenRect) { * nativeResImage = resolutionVariants.get(0); * } * }</pre> + * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since screen capture may be a lengthy + * operation, particularly if acquiring permissions is needed and involves + * user interaction. + * * @param screenRect Rect to capture in screen coordinates * @return The captured image * @throws IllegalArgumentException if {@code screenRect} width and height @@ -641,6 +666,10 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. + * <p> + * @apiNote Setting this to true means you cannot call mouse and key-controlling events + * on the AWT Event Dispatching Thread + * * @param isOn Whether {@code waitForIdle} is automatically invoked */ public synchronized void setAutoWaitForIdle(boolean isOn) { @@ -692,6 +721,10 @@ private void autoDelay() { * already set, this method returns immediately with the interrupt status * set. * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since delay may be a lengthy + * operation. + * * @param ms time to sleep in milliseconds * @throws IllegalArgumentException if {@code ms} is not between {@code 0} * and {@code 60,000} milliseconds inclusive From 46cd9be5cb0005824f076f4bdce587fdbaac2918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= <hannesw@openjdk.org> Date: Thu, 9 Jan 2025 21:37:36 +0000 Subject: [PATCH 93/99] 8347122: Add missing @serial tags to module java.desktop Reviewed-by: prr --- .../share/classes/java/applet/Applet.java | 4 ++-- .../share/classes/java/awt/AWTEvent.java | 4 ++-- .../share/classes/java/awt/AWTKeyStroke.java | 10 ++++----- .../share/classes/java/awt/Component.java | 19 +++++++++------- .../java/awt/ComponentOrientation.java | 4 ++-- .../share/classes/java/awt/Container.java | 3 ++- .../ContainerOrderFocusTraversalPolicy.java | 8 +++---- .../share/classes/java/awt/FlowLayout.java | 4 ++-- .../share/classes/java/awt/Frame.java | 4 ++-- .../share/classes/java/awt/GridBagLayout.java | 4 ++-- .../classes/java/awt/GridBagLayoutInfo.java | 22 +++++++++---------- .../share/classes/java/awt/List.java | 6 ++--- .../share/classes/java/awt/MenuComponent.java | 4 ++-- .../java/awt/ScrollPaneAdjustable.java | 4 ++-- .../share/classes/java/awt/TextComponent.java | 6 ++--- .../share/classes/java/awt/Window.java | 8 +++---- .../classes/java/awt/color/ColorSpace.java | 6 ++--- .../java/awt/color/ICC_ColorSpace.java | 14 ++++++------ .../classes/java/awt/desktop/FilesEvent.java | 4 ++-- .../java/awt/desktop/OpenFilesEvent.java | 4 ++-- .../java/awt/desktop/OpenURIEvent.java | 4 ++-- .../java/awt/desktop/UserSessionEvent.java | 4 ++-- .../java/awt/event/HierarchyEvent.java | 8 +++---- .../java/awt/event/InvocationEvent.java | 15 ++++++++----- .../classes/java/awt/event/KeyEvent.java | 6 ++--- .../classes/java/awt/event/MouseEvent.java | 4 ++-- .../java/awt/event/MouseWheelEvent.java | 10 ++++----- .../classes/java/awt/event/WindowEvent.java | 6 ++--- .../classes/java/awt/font/NumericShaper.java | 8 +++---- .../java/awt/font/TransformAttribute.java | 4 ++-- .../awt/image/renderable/ParameterBlock.java | 12 +++++++--- .../beans/IndexedPropertyChangeEvent.java | 4 ++-- .../beancontext/BeanContextChildSupport.java | 8 ++++++- .../beans/beancontext/BeanContextEvent.java | 4 +++- .../BeanContextMembershipEvent.java | 4 +++- .../BeanContextServiceAvailableEvent.java | 4 +++- .../BeanContextServiceRevokedEvent.java | 6 +++-- .../BeanContextServicesSupport.java | 4 +++- .../beans/beancontext/BeanContextSupport.java | 14 ++++++++---- .../metadata/IIOInvalidTreeException.java | 4 +++- .../attribute/AttributeSetUtilities.java | 6 ++--- .../print/attribute/standard/DialogOwner.java | 4 ++-- .../standard/MediaPrintableArea.java | 6 ++--- .../print/attribute/standard/MediaSize.java | 4 ++-- .../print/event/PrintJobAttributeEvent.java | 4 ++-- .../javax/print/event/PrintJobEvent.java | 4 ++-- .../event/PrintServiceAttributeEvent.java | 4 ++-- 47 files changed, 173 insertions(+), 134 deletions(-) diff --git a/src/java.desktop/share/classes/java/applet/Applet.java b/src/java.desktop/share/classes/java/applet/Applet.java index 2228ea419d4..56b2392f0e2 100644 --- a/src/java.desktop/share/classes/java/applet/Applet.java +++ b/src/java.desktop/share/classes/java/applet/Applet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -541,7 +541,7 @@ public void destroy() { // /** - * The accessible context associated with this {@code Applet}. + * @serial The accessible context associated with this {@code Applet}. */ @SuppressWarnings("serial") // Not statically typed as Serializable AccessibleContext accessibleContext = null; diff --git a/src/java.desktop/share/classes/java/awt/AWTEvent.java b/src/java.desktop/share/classes/java/awt/AWTEvent.java index 17c7b775c78..d48fae68cbe 100644 --- a/src/java.desktop/share/classes/java/awt/AWTEvent.java +++ b/src/java.desktop/share/classes/java/awt/AWTEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ public abstract class AWTEvent extends EventObject { /** - * The private data. + * @serial The private data. */ private byte[] bdata; diff --git a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java index df38220d24c..fee1c9a4e19 100644 --- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java +++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,22 +86,22 @@ public class AWTKeyStroke implements Serializable { private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke(); /** - * The character value for a keyboard key. + * @serial The character value for a keyboard key. */ private char keyChar = KeyEvent.CHAR_UNDEFINED; /** - * The key code for this {@code AWTKeyStroke}. + * @serial The key code for this {@code AWTKeyStroke}. */ private int keyCode = KeyEvent.VK_UNDEFINED; /** - * The bitwise-ored combination of any modifiers. + * @serial The bitwise-ored combination of any modifiers. */ private int modifiers; /** - * {@code true} if this {@code AWTKeyStroke} corresponds to a key release; + * @serial {@code true} if this {@code AWTKeyStroke} corresponds to a key release; * {@code false} otherwise. */ private boolean onKeyRelease; diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 8bfe16619bb..55fb06247af 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -305,7 +305,7 @@ public abstract class Component implements ImageObserver, MenuContainer, volatile Font font; /** - * The font which the peer is currently using. + * @serial The font which the peer is currently using. * ({@code null} if no peer exists.) */ Font peerFont; @@ -508,7 +508,7 @@ static class AWTTreeLock {} Dimension minSize; /** - * Whether or not setMinimumSize has been invoked with a non-null value. + * @serial Whether or not setMinimumSize has been invoked with a non-null value. */ boolean minSizeSet; @@ -521,7 +521,7 @@ static class AWTTreeLock {} Dimension prefSize; /** - * Whether or not setPreferredSize has been invoked with a non-null value. + * @serial Whether or not setPreferredSize has been invoked with a non-null value. */ boolean prefSizeSet; @@ -533,7 +533,7 @@ static class AWTTreeLock {} Dimension maxSize; /** - * Whether or not setMaximumSize has been invoked with a non-null value. + * @serial Whether or not setMaximumSize has been invoked with a non-null value. */ boolean maxSizeSet; @@ -698,12 +698,12 @@ Object getObjectLock() { } /** - * Whether the component is packed or not; + * @serial Whether the component is packed or not; */ boolean isPacked = false; /** - * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize + * @serial Pseudoparameter for direct Geometry API (setLocation, setBounds setSize * to signal setBounds what's changing. Should be used under TreeLock. * This is only needed due to the inability to change the cross-calling * order of public and deprecated methods. @@ -8290,7 +8290,7 @@ public boolean isFocusOwner() { } /** - * Used to disallow auto-focus-transfer on disposal of the focus owner + * @serial Used to disallow auto-focus-transfer on disposal of the focus owner * in the process of disposing its parent container. */ private boolean autoFocusTransferOnDisposal = true; @@ -9234,6 +9234,7 @@ Window getContainingWindow() { /** * The {@code AccessibleContext} associated with this {@code Component}. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected AccessibleContext accessibleContext = null; @@ -9290,6 +9291,7 @@ protected AccessibleAWTComponent() { /** * A component listener to track show/hide/resize events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ComponentListener accessibleAWTComponentHandler = null; @@ -9297,6 +9299,7 @@ protected AccessibleAWTComponent() { /** * A listener to track focus events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected FocusListener accessibleAWTFocusHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java index afa1e8af94a..f12d4014ee9 100644 --- a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java +++ b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -200,7 +200,7 @@ public static ComponentOrientation getOrientation(ResourceBundle bdl) } /** - * The bitwise-ored combination of flags. + * @serial The bitwise-ored combination of flags. */ private int orientation; diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index b6fbfb808a6..9bfb41a871e 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3853,6 +3853,7 @@ public Accessible getAccessibleAt(Point p) { /** * The handler to fire {@code PropertyChange} * when children are added or removed + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ContainerListener accessibleContainerHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java index 6f905f3d2c7..4183c3dc230 100644 --- a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java +++ b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,12 +66,12 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.ContainerOrderFocusTraversalPolicy"); /** - * This constant is used when the forward focus traversal order is active. + * @serial This constant is used when the forward focus traversal order is active. */ private final int FORWARD_TRAVERSAL = 0; /** - * This constant is used when the backward focus traversal order is active. + * @serial This constant is used when the backward focus traversal order is active. */ private final int BACKWARD_TRAVERSAL = 1; @@ -82,7 +82,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final long serialVersionUID = 486933713763926351L; /** - * Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus + * @serial Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus * down-cycle implicitly. */ private boolean implicitDownCycleTraversal = true; diff --git a/src/java.desktop/share/classes/java/awt/FlowLayout.java b/src/java.desktop/share/classes/java/awt/FlowLayout.java index 3ad34f01776..18f46c54c0c 100644 --- a/src/java.desktop/share/classes/java/awt/FlowLayout.java +++ b/src/java.desktop/share/classes/java/awt/FlowLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -188,7 +188,7 @@ public class FlowLayout implements LayoutManager, java.io.Serializable { int vgap; /** - * If true, components will be aligned on their baseline. + * @serial If true, components will be aligned on their baseline. */ private boolean alignOnBaseline; diff --git a/src/java.desktop/share/classes/java/awt/Frame.java b/src/java.desktop/share/classes/java/awt/Frame.java index e01ef082d42..fcdb4d5e032 100644 --- a/src/java.desktop/share/classes/java/awt/Frame.java +++ b/src/java.desktop/share/classes/java/awt/Frame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -347,7 +347,7 @@ public class Frame extends Window implements MenuContainer { boolean mbManagement = false; /* used only by the Motif impl. */ /** - * The bitwise mask of frame state constants. + * @serial The bitwise mask of frame state constants. */ // XXX: uwe: abuse old field for now // will need to take care of serialization diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayout.java b/src/java.desktop/share/classes/java/awt/GridBagLayout.java index 9fdd7ee7774..2dc65ab1265 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayout.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -473,7 +473,7 @@ public class GridBagLayout implements LayoutManager2, public double[] rowWeights; /** - * The component being positioned. This is set before calling into + * @serial The component being positioned. This is set before calling into * {@code adjustForGravity}. */ private Component componentAdjusting; diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java index 1a4ed2942c5..ecdc4001369 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,37 +45,37 @@ public final class GridBagLayoutInfo implements java.io.Serializable { private static final long serialVersionUID = -4899416460737170217L; /** - * The number of cells: horizontal and vertical. + * @serial The number of cells: horizontal and vertical. */ int width, height; /** - * The starting point for layout. + * @serial The starting point for layout. */ int startx, starty; /** - * The largest minWidth in each column. + * @serial The largest minWidth in each column. */ int[] minWidth; /** - * The largest minHeight in each row. + * @serial The largest minHeight in each row. */ int[] minHeight; /** - * The largest weight in each column. + * @serial The largest weight in each column. */ double[] weightX; /** - * The largest weight in each row. + * @serial The largest weight in each row. */ double[] weightY; /** - * Whether or not baseline layout has been requested and one of the + * @serial Whether or not baseline layout has been requested and one of the * components has a valid baseline. */ boolean hasBaseline; @@ -83,18 +83,18 @@ public final class GridBagLayoutInfo implements java.io.Serializable { // These are only valid if hasBaseline is true and are indexed by // row. /** - * The type of baseline for a particular row. A mix of the + * @serial The type of baseline for a particular row. A mix of the * BaselineResizeBehavior constants {@code (1 << ordinal())} */ short[] baselineType; /** - * Max ascent (baseline). + * @serial Max ascent (baseline). */ int[] maxAscent; /** - * Max descent (height - baseline) + * @serial Max descent (height - baseline) */ int[] maxDescent; diff --git a/src/java.desktop/share/classes/java/awt/List.java b/src/java.desktop/share/classes/java/awt/List.java index fe7ebb58431..30b26aa371b 100644 --- a/src/java.desktop/share/classes/java/awt/List.java +++ b/src/java.desktop/share/classes/java/awt/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1552,12 +1552,12 @@ protected class AccessibleAWTListChild extends AccessibleAWTComponent // [[[FIXME]]] need to finish implementing this!!! /** - * The parent {@code List}. + * @serial The parent {@code List}. */ private List parent; /** - * The index in the parent. + * @serial The index in the parent. */ private int indexInParent; diff --git a/src/java.desktop/share/classes/java/awt/MenuComponent.java b/src/java.desktop/share/classes/java/awt/MenuComponent.java index facf995416f..1391a397f82 100644 --- a/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -436,7 +436,7 @@ private void readObject(ObjectInputStream s) * --- Accessibility Support --- */ /** - * MenuComponent will contain all of the methods in interface Accessible, + * @serial MenuComponent will contain all of the methods in interface Accessible, * though it won't actually implement the interface - that will be up * to the individual objects which extend MenuComponent. */ diff --git a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java index d8d70fd2476..9b539a311d3 100644 --- a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java +++ b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -140,7 +140,7 @@ public final class ScrollPaneAdjustable implements Adjustable, Serializable { private int blockIncrement = 1; /** - * Specified adjustment listener to receive adjustment events from this + * @serial Specified adjustment listener to receive adjustment events from this * {@code ScrollPaneAdjustable}. */ @SuppressWarnings("serial") // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/awt/TextComponent.java b/src/java.desktop/share/classes/java/awt/TextComponent.java index 5185646a07e..da722090afb 100644 --- a/src/java.desktop/share/classes/java/awt/TextComponent.java +++ b/src/java.desktop/share/classes/java/awt/TextComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public sealed class TextComponent extends Component implements Accessible int selectionEnd; /** - * A flag used to tell whether the background has been set by + * @serial A flag used to tell whether the background has been set by * developer code (as opposed to AWT code). Used to determine * the background color of non-editable TextComponents. */ @@ -1207,7 +1207,7 @@ public String getBeforeIndex(int part, int index) { } // end of AccessibleAWTTextComponent /** - * Whether support of input methods should be checked or not. + * @serial Whether support of input methods should be checked or not. */ private boolean checkForEnableIM = true; } diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index 4e576f3dc9e..329e2574473 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -229,7 +229,7 @@ public static enum Type { static boolean systemSyncLWRequests = false; /** - * Focus transfers should be synchronous for lightweight component requests. + * @serial Focus transfers should be synchronous for lightweight component requests. */ boolean syncLWRequests = false; transient boolean beforeFirstShow = true; @@ -2777,7 +2777,7 @@ private void removeFromWindowList() { } /** - * Window type. + * @serial Window type. * * Synchronization: ObjectLock */ @@ -3337,7 +3337,7 @@ boolean canContainFocusOwner(Component focusOwnerCandidate) { } /** - * {@code true} if this Window should appear at the default location, + * @serial {@code true} if this Window should appear at the default location, * {@code false} if at the current location. */ private volatile boolean locationByPlatform = locationByPlatformProp; diff --git a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java index 80944e53017..2eab6aa46ef 100644 --- a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,12 +100,12 @@ public abstract class ColorSpace implements Serializable { private static final long serialVersionUID = -409452704308689724L; /** - * One of the {@code ColorSpace} type constants. + * @serial One of the {@code ColorSpace} type constants. */ private final int type; /** - * The number of components in the color space. + * @serial The number of components in the color space. */ private final int numComponents; diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java index 56ea5c573d8..5a0af93cb5e 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,32 +88,32 @@ public class ICC_ColorSpace extends ColorSpace { private static final long serialVersionUID = 3455889114070431483L; /** - * The specified {@code ICC_Profile} object. + * @serial The specified {@code ICC_Profile} object. */ private ICC_Profile thisProfile; /** - * The minimum normalized component values. + * @serial The minimum normalized component values. */ private float[] minVal; /** - * The maximum normalized component values. + * @serial The maximum normalized component values. */ private float[] maxVal; /** - * Difference between min and max values. + * @serial Difference between min and max values. */ private float[] diffMinMax; /** - * Inverted value of the difference between min and max values. + * @serial Inverted value of the difference between min and max values. */ private float[] invDiffMinMax; /** - * Whether the values should be scaled or not. + * @serial Whether the values should be scaled or not. */ private boolean needScaleInit = true; diff --git a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java index 3367d87456f..b7ce13abadc 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public sealed class FilesEvent extends AppEvent private static final long serialVersionUID = 5271763715462312871L; /** - * The list of files. + * @serial The list of files. */ @SuppressWarnings("serial") // Not statically typed as Serializable final List<File> files; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java index d815d867475..7c8ba561327 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public final class OpenFilesEvent extends FilesEvent { private static final long serialVersionUID = -3982871005867718956L; /** - * The search term used to find the files. + * @serial The search term used to find the files. */ final String searchTerm; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java index a1869d35fa3..f7e66065f54 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ public final class OpenURIEvent extends AppEvent { private static final long serialVersionUID = 221209100935933476L; /** - * The {@code URI} the app was asked to open. + * @serial The {@code URI} the app was asked to open. */ final URI uri; diff --git a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java index 9199358b688..4cb011c05f5 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public final class UserSessionEvent extends AppEvent { private static final long serialVersionUID = 6747138462796569055L; /** - * The reason of the user session change. + * @serial The reason of the user session change. */ private final Reason reason; diff --git a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java index 0588706df7a..ae463369f38 100644 --- a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,18 +166,18 @@ public class HierarchyEvent extends AWTEvent { public static final int SHOWING_CHANGED = 0x4; /** - * The {@code Component} at the top of the hierarchy which was changed. + * @serial The {@code Component} at the top of the hierarchy which was changed. */ Component changed; /** - * The parent of the {@code changed} component. This may be the parent + * @serial The parent of the {@code changed} component. This may be the parent * before or after the change, depending on the type of change. */ Container changedParent; /** - * A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} + * @serial A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} * events represented in this event object. For information on allowable * values, see the class description for {@link HierarchyEvent} */ diff --git a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java index c73b77282d5..b9966af5865 100644 --- a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,8 @@ public void dispose(InvocationEvent invocationEvent) { /** * The Runnable whose run() method will be called. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Runnable runnable; @@ -95,12 +97,13 @@ public void dispose(InvocationEvent invocationEvent) { * or after the event was disposed. * * @see #isDispatched + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected volatile Object notifier; /** - * The (potentially null) Runnable whose run() method will be called + * @serial The (potentially null) Runnable whose run() method will be called * immediately after the event was dispatched or disposed. * * @see #isDispatched @@ -110,7 +113,7 @@ public void dispose(InvocationEvent invocationEvent) { private final Runnable listener; /** - * Indicates whether the {@code run()} method of the {@code runnable} + * @serial Indicates whether the {@code run()} method of the {@code runnable} * was executed or not. * * @see #isDispatched @@ -122,18 +125,20 @@ public void dispose(InvocationEvent invocationEvent) { * Set to true if dispatch() catches Throwable and stores it in the * exception instance variable. If false, Throwables are propagated up * to the EventDispatchThread's dispatch loop. + * + * @serial */ protected boolean catchExceptions; /** - * The (potentially null) Exception thrown during execution of the + * @serial The (potentially null) Exception thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ private Exception exception = null; /** - * The (potentially null) Throwable thrown during execution of the + * @serial The (potentially null) Throwable thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ diff --git a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java index abc1082d5bd..7470a23881e 100644 --- a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -154,7 +154,7 @@ public non-sealed class KeyEvent extends InputEvent { /** - * Stores the state of native event dispatching system + * @serial Stores the state of native event dispatching system * - true, if when the event was created event proxying * mechanism was active * - false, if it was inactive @@ -1229,7 +1229,7 @@ public boolean isProxyActive(KeyEvent ev) { private static native void initIDs(); /** - * The original event source. + * @serial The original event source. * * Event source can be changed during processing, but in some cases * we need to be able to obtain original source. diff --git a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java index 56ac76eeaff..cabcb7b1d7d 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -334,7 +334,7 @@ public non-sealed class MouseEvent extends InputEvent { int clickCount; /** - * Indicates whether the event is a result of a touch event. + * @serial Indicates whether the event is a result of a touch event. */ private boolean causedByTouchEvent; diff --git a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java index 37efe0a04d7..33a357888dd 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ public class MouseWheelEvent extends MouseEvent { @Native public static final int WHEEL_BLOCK_SCROLL = 1; /** - * Indicates what sort of scrolling should take place in response to this + * @serial Indicates what sort of scrolling should take place in response to this * event, based on platform settings. Legal values are: * <ul> * <li> WHEEL_UNIT_SCROLL @@ -130,7 +130,7 @@ public class MouseWheelEvent extends MouseEvent { int scrollType; /** - * Only valid for scrollType WHEEL_UNIT_SCROLL. + * @serial Only valid for scrollType WHEEL_UNIT_SCROLL. * Indicates number of units that should be scrolled per * click of mouse wheel rotation, based on platform settings. * @@ -140,14 +140,14 @@ public class MouseWheelEvent extends MouseEvent { int scrollAmount; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getWheelRotation */ int wheelRotation; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getPreciseWheelRotation */ diff --git a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java index 51370170e51..d898860f153 100644 --- a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -165,12 +165,12 @@ public class WindowEvent extends ComponentEvent { transient Window opposite; /** - * Previous state of the window for window state change event. + * @serial Previous state of the window for window state change event. */ int oldState; /** - * New state of the window for window state change event. + * @serial New state of the window for window state change event. */ int newState; diff --git a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java index c12d63e9951..ae507036112 100644 --- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java +++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -393,16 +393,16 @@ private boolean inRange(int c) { } } - /** index of context for contextual shaping - values range from 0 to 18 */ + /** @serial index of context for contextual shaping - values range from 0 to 18 */ private int key; - /** flag indicating whether to shape contextually (high bit) and which + /** @serial flag indicating whether to shape contextually (high bit) and which * digit ranges to shape (bits 0-18) */ private int mask; /** - * The context {@code Range} for contextual shaping or the {@code + * @serial The context {@code Range} for contextual shaping or the {@code * Range} for non-contextual shaping. {@code null} for the bit * mask-based API. * diff --git a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java index 2dd25eec4d8..9bcf83ddc83 100644 --- a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java +++ b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public final class TransformAttribute implements Serializable { /** - * The {@code AffineTransform} for this + * @serial The {@code AffineTransform} for this * {@code TransformAttribute}, or {@code null} * if {@code AffineTransform} is the identity transform. */ diff --git a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java index 10f62777526..c98a5b2c771 100644 --- a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java +++ b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,10 +102,16 @@ public class ParameterBlock implements Cloneable, Serializable { @Serial private static final long serialVersionUID = -7577115551785240750L; - /** A Vector of sources, stored as arbitrary Objects. */ + /** + * A Vector of sources, stored as arbitrary Objects. + * @serial + */ protected Vector<Object> sources = new Vector<Object>(); - /** A Vector of non-source parameters, stored as arbitrary Objects. */ + /** + * A Vector of non-source parameters, stored as arbitrary Objects. + * @serial + */ protected Vector<Object> parameters = new Vector<Object>(); /** A dummy constructor. */ diff --git a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java index 983dd810079..90c0fb109d2 100644 --- a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java +++ b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ public class IndexedPropertyChangeEvent extends PropertyChangeEvent { private static final long serialVersionUID = -320227448495806870L; /** - * The index of the property element that was changed. + * @serial The index of the property element that was changed. */ private int index; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java index 532661dc29b..527a8be9cc0 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -358,6 +358,8 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code BeanContext} in which * this {@code BeanContextChild} is nested. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable public BeanContextChild beanContextChildPeer; @@ -365,12 +367,16 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code PropertyChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected PropertyChangeSupport pcSupport; /** * The {@code VetoableChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected VetoableChangeSupport vcSupport; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java index 62fd45eee79..1b600bc29b4 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,8 @@ public synchronized boolean isPropagated() { /** * The {@code BeanContext} from which this event was propagated + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContext propagatedFrom; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java index 5c5d112d36a..ab63aae86e5 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,8 @@ public boolean contains(Object child) { /** * The list of children affected by this * event notification. + * + * @serial */ @SuppressWarnings({"rawtypes", "serial"}) // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java index dd4cc457a31..b2132ad8f97 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,6 +84,8 @@ public Iterator<?> getCurrentServiceSelectors() { /** * A {@code Class} reference to the newly available service + * + * @serial */ protected Class<?> serviceClass; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java index d32b18376a4..6ef996b3482 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,11 +99,13 @@ public boolean isServiceClass(Class<?> service) { /** * A {@code Class} reference to the service that is being revoked. + * + * @serial */ protected Class<?> serviceClass; /** - * {@code true} if current service is being forcibly revoked. + * @serial {@code true} if current service is being forcibly revoked. */ private boolean invalidateRefs; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index 98d68d92fa1..0e2e4211a9c 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -627,6 +627,8 @@ protected BeanContextServiceProvider getServiceProvider() { /** * The service provider. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContextServiceProvider serviceProvider; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java index fedd6667de1..dbbecb87d7e 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -342,13 +342,13 @@ protected class BCSChild implements Serializable { /** - * The child. + * @serial The child. */ @SuppressWarnings("serial") // Not statically typed as Serializable private Object child; /** - * The peer if the child and the peer are related by an implementation + * @serial The peer if the child and the peer are related by an implementation * of BeanContextProxy */ @SuppressWarnings("serial") // Not statically typed as Serializable @@ -1393,7 +1393,7 @@ protected static final boolean classEquals(Class<?> first, Class<?> second) { protected transient HashMap<Object, BCSChild> children; /** - * Currently serializable children. + * @serial Currently serializable children. */ private int serializable = 0; // children serializable @@ -1407,12 +1407,16 @@ protected static final boolean classEquals(Class<?> first, Class<?> second) { /** * The current locale of this BeanContext. + * + * @serial */ protected Locale locale; /** * A {@code boolean} indicating if this * instance may now render a GUI. + * + * @serial */ protected boolean okToUseGui; @@ -1420,6 +1424,8 @@ protected static final boolean classEquals(Class<?> first, Class<?> second) { /** * A {@code boolean} indicating whether or not * this object is currently in design time mode. + * + * @serial */ protected boolean designTime; diff --git a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java index 2c851ec2f0e..bc14958de1c 100644 --- a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java +++ b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,8 @@ public class IIOInvalidTreeException extends IIOException { /** * The {@code Node} that led to the parsing error, or * {@code null}. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Node offendingNode = null; diff --git a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java index 9244c12270a..f762eb89925 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java +++ b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ private static class UnmodifiableAttributeSet private static final long serialVersionUID = -6131802583863447813L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; @@ -352,7 +352,7 @@ private static class SynchronizedAttributeSet private static final long serialVersionUID = 8365731020128564925L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java index 807eaa2b122..593e656cf6b 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public long getOwnerID(DialogOwner owner) { private static final long serialVersionUID = -1901909867156076547L; /** - * The owner of the dialog. + * @serial The owner of the dialog. */ private Window owner; private transient long id; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java index c1d16c23154..72a58f2b697 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,12 +85,12 @@ public final class MediaPrintableArea implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { /** - * Printable {@code x}, {@code y}, {@code width} and {@code height}. + * @serial Printable {@code x}, {@code y}, {@code width} and {@code height}. */ private int x, y, w, h; /** - * The units in which the values are expressed. + * @serial The units in which the values are expressed. */ private int units; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java index bf33eabafac..6a8db3b94c2 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ public class MediaSize extends Size2DSyntax implements Attribute { private static final long serialVersionUID = -1967958664615414771L; /** - * The media name. + * @serial The media name. */ private MediaSizeName mediaName; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java index ec244468c19..717898d8c50 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class PrintJobAttributeEvent extends PrintEvent { private static final long serialVersionUID = -6534469883874742101L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintJobAttributeSet attributes; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java index f68e2df5a03..629a487e04a 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class PrintJobEvent extends PrintEvent { private static final long serialVersionUID = -1711656903622072997L; /** - * The reason of this event. + * @serial The reason of this event. */ private int reason; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java index 4281c31b397..6cdc22246df 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class PrintServiceAttributeEvent extends PrintEvent { private static final long serialVersionUID = -7565987018140326600L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintServiceAttributeSet attributes; From bdd600078b016a732fdb4fdbc21470793379cac3 Mon Sep 17 00:00:00 2001 From: Alisen Chung <achung@openjdk.org> Date: Thu, 9 Jan 2025 21:51:51 +0000 Subject: [PATCH 94/99] 8347375: Extra <p> tag in robot specification Reviewed-by: kbarrett --- src/java.desktop/share/classes/java/awt/Robot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index d0877b3bddd..957e30126e1 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -57,7 +57,7 @@ * events are generated in the platform's native input * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. - * <p> + * * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} @@ -666,7 +666,7 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. - * <p> + * * @apiNote Setting this to true means you cannot call mouse and key-controlling events * on the AWT Event Dispatching Thread * From 925b22605a7c463fb7bb856e245fadaf70f99255 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Fri, 10 Jan 2025 00:26:38 +0000 Subject: [PATCH 95/99] 8346787: Fix two C2 IR matching tests for RISC-V Reviewed-by: fjiang, mli, dfenacci --- .../compiler/c2/irTests/ModINodeIdealizationTests.java | 8 +++++--- .../compiler/c2/irTests/ModLNodeIdealizationTests.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java index 2437b05586a..dffafea7ea8 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,8 +121,10 @@ public int powerOf2Random(int x) { } @Test - @IR(failOn = {IRNode.MOD_I}) - @IR(counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_I}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) // Special optimization for the case 2^k-1 for bigger k public int powerOf2Minus1(int x) { return x % 127; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java index 515a7d535f4..e931ff87c09 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,8 +105,10 @@ public long powerOf2Random(long x) { } @Test - @IR(failOn = {IRNode.MOD_L}) - @IR(counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_L}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) // Special optimization for the case 2^k-1 for bigger k public long powerOf2Minus1(long x) { return x % ((1L << 33) - 1); From eaee1d8b95fe1002e513fe65fd50988b264cb75c Mon Sep 17 00:00:00 2001 From: Henry Jen <henryjen@openjdk.org> Date: Fri, 10 Jan 2025 00:53:58 +0000 Subject: [PATCH 96/99] 8347379: Problem list failed tests after JDK-8321413 Reviewed-by: dholmes --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6a2ab0d1e04..b82d661bd2d 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -716,6 +716,8 @@ javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all # core_tools +tools/jlink/runtimeImage/JavaSEReproducibleTest.java 8347376 generic-all +tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java 8347376 generic-all ############################################################################ From 34f83daaa619323936056c70a2eb2a4652ce990a Mon Sep 17 00:00:00 2001 From: J9 Build <j9build@ca.ibm.com> Date: Fri, 10 Jan 2025 04:19:58 +0000 Subject: [PATCH 97/99] Update OPENJDK_TAG to merged level jdk-25+5 Signed-off-by: J9 Build <j9build@ca.ibm.com> --- closed/openjdk-tag.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/closed/openjdk-tag.gmk b/closed/openjdk-tag.gmk index bdd32e8ba11..8811bd09373 100644 --- a/closed/openjdk-tag.gmk +++ b/closed/openjdk-tag.gmk @@ -1 +1 @@ -OPENJDK_TAG := jdk-25+4 +OPENJDK_TAG := jdk-25+5 From c8a218485adc616ba3a7891cde3ac1cc60cb6910 Mon Sep 17 00:00:00 2001 From: Theresa Mammarella <Theresa.T.Mammarella@ibm.com> Date: Fri, 10 Jan 2025 08:54:52 -0500 Subject: [PATCH 98/99] Add missing update to the shared class cache search path URLClassPath.getResource(String name, boolean check) was removed in 24 due to the security manager removal. The OpenJ9 patch to update the scc's search path was lost because of this change. Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com> --- .../share/classes/jdk/internal/loader/URLClassPath.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java index f4630331fcb..22d5fce21de 100644 --- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java +++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java @@ -25,7 +25,7 @@ /* * =========================================================================== - * (c) Copyright IBM Corp. 1997, 2023 All Rights Reserved + * (c) Copyright IBM Corp. 1997, 2025 All Rights Reserved * =========================================================================== */ @@ -431,6 +431,9 @@ public Resource getResource(String name) { for (int i = 0; (loader = getLoader(i)) != null; i++) { Resource res = loader.getResource(name); if (res != null) { + res.setClasspathLoadIndex(i); /* Store the classpath index that this resource came from. */ //OpenJ9-shared_classes_misc + /* Update the search path with shared Classes Helper, this is only if we are using shared classes. */ //OpenJ9-shared_classes_misc + updateClasspathWithSharedClassesHelper(i); //OpenJ9-shared_classes_misc return res; } } From 1385b08b9abb6cbe214ab674c1700e83ac5ace1a Mon Sep 17 00:00:00 2001 From: Kostas Tsiounis <kostas.tsiounis@ibm.com> Date: Wed, 8 Jan 2025 11:00:00 -0500 Subject: [PATCH 99/99] Exclude additional FIPS related test failures This update migrates all FIPS excluded tests to be platform agnostic. Some tests are referencing an incorrect issue number unrelated to the test. Additional tests failing have been added to the excludes list since they are not expected to be running anytime soon. Signed-off-by: Kostas Tsiounis <kostas.tsiounis@ibm.com> --- ...st-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt | 52 +++++++++++------- .../jdk/ProblemList-FIPS140_3_OpenJcePlus.txt | 53 ++++++++++--------- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt index 45d67622b58..9478689af5b 100644 --- a/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt +++ b/test/jdk/ProblemList-FIPS140_3_OpenJCEPlusFIPS.FIPS140-3.txt @@ -117,6 +117,7 @@ com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java https://github.com com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Cipher/RSA/TestRSA.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +com/sun/crypto/provider/Cipher/Test4958071.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Cipher/TextLength/SameBufferOverwrite.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Cipher/UTIL/StrongOrUnlimited.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -141,6 +142,7 @@ com/sun/crypto/provider/KeyFactory/TestProviderLeak.java https://github.com/ecli com/sun/crypto/provider/KeyGenerator/Test4628062.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/KeyGenerator/Test6227536.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/KeyGenerator/TestExplicitKeyLength.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +com/sun/crypto/provider/KeyProtector/IterationCount.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Mac/DigestCloneabilityTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Mac/EmptyByteBufferTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Mac/HmacMD5.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -152,6 +154,7 @@ com/sun/crypto/provider/Mac/MacClone.java https://github.com/eclipse-openj9/open com/sun/crypto/provider/Mac/MacKAT.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Mac/MacSameTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/Mac/NullByteBufferTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +com/sun/crypto/provider/Mac/Test6205692.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/NSASuiteB/TestAESOids.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -208,7 +211,7 @@ java/security/MessageDigest/TestDigestIOStream.java https://github.com/eclipse-o java/security/MessageDigest/TestSameLength.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/MessageDigest/TestSameValue.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java https://github.ibm.com/runtimes/jit-crypto/issues/622 generic-all +java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/GetInstance/GetInstance.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/GetInstance/GetInstanceSecurity.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/Policy/SignedJar/SignedJarTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -281,6 +284,7 @@ java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java https: java/security/cert/CertPathValidatorException/Serial.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/cert/CertificateRevokedException/Basic.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/cert/GetInstance.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/cert/PKIXRevocationChecker/UnitTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/cert/PolicyNode/GetPolicyQualifiers.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/security/cert/X509CRL/VerifyDefault.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -299,7 +303,7 @@ javax/crypto/Cipher/TestCipherMode.java https://github.com/eclipse-openj9/openj9 javax/crypto/Cipher/TestGetInstance.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/crypto/Cipher/Turkish.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/crypto/CipherSpi/DirectBBRemaining.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -javax/crypto/CipherSpi/ResetByteBuffer.java https://github.com/eclipse-openj9/openj9/issues/20343 linux-s390x,windows-all +javax/crypto/CipherSpi/ResetByteBuffer.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/crypto/CryptoPermission/AllPermCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/crypto/CryptoPermission/LowercasePermCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/crypto/CryptoPermission/RC2PermCheck.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -329,6 +333,7 @@ javax/crypto/spec/DESKeySpec/CheckParity.java https://github.com/eclipse-openj9/ javax/crypto/spec/RC2ParameterSpec/RC2AlgorithmParameters.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/security/auth/kerberos/KerberosTixDateTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/security/auth/kerberos/StandardNames.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +javax/security/auth/Subject/UnsupportedSV.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/xml/crypto/dsig/BadXPointer.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/xml/crypto/dsig/Basic.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/xml/crypto/dsig/ErrorHandlerPermissions.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -432,8 +437,8 @@ sun/security/krb5/auto/UnboundService.java https://github.com/eclipse-openj9/ope sun/security/krb5/auto/UseCacheAndStoreKey.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/krb5/auto/W83.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -sun/security/krb5/auto/tools/KinitConfPlusProps.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/krb5/auto/tools/KtabSalt.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all +sun/security/krb5/auto/tools/KinitConfPlusProps.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/krb5/auto/tools/KtabSalt.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/krb5/etype/KerberosAesSha2.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/krb5/etype/WeakCrypto.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/krb5/ktab/BufferBoundary.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -473,7 +478,7 @@ java/rmi/MarshalledObject/MOFilterTest.java https://github.com/eclipse-openj9/op java/rmi/MarshalledObject/compare/Compare.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/rmi/MarshalledObject/compare/HashCode.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/rmi/Naming/DefaultRegistryPort.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -java/rmi/Naming/LookupIPv6.java https://github.com/eclipse-openj9/openj9/issues/20343 aix-all,linux-ppc64le,linux-s390x,windows-all +java/rmi/Naming/LookupIPv6.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/rmi/Naming/LookupNameWithColon.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/rmi/Naming/RmiIsNoScheme.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all java/rmi/Naming/UnderscoreHost.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -540,6 +545,7 @@ java/sql/testng/test/sql/SQLTransientExceptionTests.java https://github.com/ecli java/sql/testng/test/sql/SQLWarningTests.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/naming/module/RunBasic.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/naming/spi/FactoryCacheTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all +javax/naming/spi/providers/InitialContextTest.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all javax/net/ssl/ALPN/SSLEngineAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ALPN/SSLSocketAlpnTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -628,8 +634,8 @@ javax/net/ssl/ServerName/EndingDotHostname.java https://github.com/eclipse-openj javax/net/ssl/ServerName/SSLEngineExplorer.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ServerName/SSLEngineExplorerUnmatchedSNI.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all +javax/net/ssl/ServerName/SSLEngineExplorerWithCli.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +javax/net/ssl/ServerName/SSLEngineExplorerWithSrv.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ServerName/SSLSocketConsistentSNI.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ServerName/SSLSocketExplorer.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all javax/net/ssl/ServerName/SSLSocketExplorerFailure.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -739,6 +745,9 @@ javax/xml/jaxp/datatype/8033980/SerializationTest.java https://github.com/eclips jdk/dynalink/BeanLinkerTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/dynalink/TrustedDynamicLinkerFactoryTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/dynalink/UntrustedDynamicLinkerFactoryTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +jdk/internal/jline/JLineConsoleProviderTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +jdk/internal/jline/LazyJdkConsoleProvider.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +jdk/internal/jline/RedirectedStdOut.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/security/jarsigner/Function.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all jdk/security/jarsigner/Properties.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -780,20 +789,21 @@ sun/security/ec/xec/TestXDH.java https://github.com/eclipse-openj9/openj9/issues sun/security/ec/xec/XECKeyFormat.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/jca/PreferredProviderNegativeTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/jca/PreferredProviderTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -sun/security/mscapi/AccessKeyStore.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/AllTypes.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/DupAlias.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/EncodingMutability.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/IsSunMSCAPIAvailable.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/IterateWindowsRootStore.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/KeyStoreCompatibilityMode.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/KeytoolChangeAlias.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/NullKey.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/PrngSerialize.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all -sun/security/mscapi/PrngSlow.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all +sun/security/mscapi/AccessKeyStore.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/AllTypes.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/DupAlias.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/EncodingMutability.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/IsSunMSCAPIAvailable.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/IterateWindowsRootStore.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/KeyStoreCompatibilityMode.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/KeytoolChangeAlias.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/NullKey.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/PrngSerialize.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/mscapi/PrngSlow.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs7/PKCS7VerifyTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs7/SignerOrder.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/pkcs/pkcs8/LongPKCS8orX509KeySpec.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs8/PKCS8Test.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs8/TestLeadingZeros.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs/pkcs9/PKCS9AttrTypeTests.java https://github.ibm.com/runtimes/backlog/issues/1089 generic-all @@ -823,6 +833,7 @@ sun/security/pkcs12/StorePasswordTest.java https://github.com/eclipse-openj9/ope sun/security/pkcs12/StoreSecretKeyTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs12/StoreTrustedCertTest.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/pkcs12/WrongPBES2.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/provider/all/Deterministic.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/provider/DSA/SecureRandomReset.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/provider/DSA/SupportedDSAParamGen.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/provider/DSA/SupportedDSAParamGenLongKey.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -1029,7 +1040,7 @@ sun/security/ssl/rsa/CheckProviderEntries.java https://github.com/eclipse-openj9 sun/security/ssl/rsa/SignatureOffsets.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/ssl/rsa/SignedObjectChain.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/ssl/spi/ProviderInit.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all -sun/security/tools/jarsigner/CertChainUnclosed.java https://github.com/eclipse-openj9/openj9/issues/20343 windows-all +sun/security/tools/jarsigner/CertChainUnclosed.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/tools/jarsigner/DefaultSigalg.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/tools/jarsigner/EntriesOrder.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/tools/jarsigner/JarSigningNonAscii.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all @@ -1085,6 +1096,9 @@ sun/security/x509/AlgorithmId/NonStandardNames.java https://github.com/eclipse-o sun/security/x509/AlgorithmId/OmitAlgIdParam.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/AlgorithmId/PBES2.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/AlgorithmId/Uppercase.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/x509/CertificateValidity/NullName.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/x509/EDIPartyName/NullName.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all +sun/security/x509/Extensions/IllegalExtensions.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/OtherName/Parse.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/URICertStore/AIACertTimeout.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all sun/security/x509/URICertStore/CRLReadTimeout.java https://github.com/eclipse-openj9/openj9/issues/20343 generic-all diff --git a/test/jdk/ProblemList-FIPS140_3_OpenJcePlus.txt b/test/jdk/ProblemList-FIPS140_3_OpenJcePlus.txt index a60b4f23309..c4755e817e2 100644 --- a/test/jdk/ProblemList-FIPS140_3_OpenJcePlus.txt +++ b/test/jdk/ProblemList-FIPS140_3_OpenJcePlus.txt @@ -1,5 +1,5 @@ # =========================================================================== -# (c) Copyright IBM Corp. 2023, 2024 All Rights Reserved +# (c) Copyright IBM Corp. 2023, 2025 All Rights Reserved # =========================================================================== # 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 @@ -162,7 +162,7 @@ java/lang/Class/GetPackageBootLoaderChildLayer.java https://github.com/ibmruntim java/lang/ClassLoader/forNameLeak/ClassForNameLeak.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/lang/ProcessBuilder/JspawnhelperWarnings.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/lang/SecurityManager/CheckSecurityProvider.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -java/lang/String/CompactString/NegativeSize.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 aix-all,linux-ppc64le,linux-s390x,windows-all +java/lang/String/CompactString/NegativeSize.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/lang/reflect/records/IsRecordTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/lang/reflect/records/RecordPermissionsTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/lang/reflect/records/RecordReflectionTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -292,7 +292,7 @@ javax/crypto/Cipher/TestCipherMode.java https://github.com/ibmruntimes/openj9-op javax/crypto/Cipher/TestGetInstance.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/crypto/Cipher/Turkish.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/crypto/CipherSpi/DirectBBRemaining.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -javax/crypto/CipherSpi/ResetByteBuffer.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-s390x,windows-all +javax/crypto/CipherSpi/ResetByteBuffer.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/crypto/CryptoPermission/AllPermCheck.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/crypto/CryptoPermission/LowercasePermCheck.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/crypto/CryptoPermission/RC2PermCheck.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -354,7 +354,7 @@ sun/security/krb5/auto/BasicKrb5Test.java https://github.com/ibmruntimes/openj9- sun/security/krb5/auto/BasicProc.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/auto/BogusKDC.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/auto/CleanState.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/krb5/auto/Cleaners.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/krb5/auto/Cleaners.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/auto/CrossRealm.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/auto/DiffNameSameKey.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/auto/DiffSaltParams.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -431,6 +431,7 @@ sun/security/krb5/ktab/BufferBoundary.java https://github.com/ibmruntimes/openj9 sun/security/krb5/ktab/FileKeyTab.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/ktab/KeyTabIndex.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/krb5/runNameEquals.sh https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/provider/all/Deterministic.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all # # Exclude tests list from extended.openjdk # @@ -470,10 +471,10 @@ java/io/Serializable/records/WriteReplaceTest.java https://github.com/ibmruntime java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/io/Serializable/serialFilter/GlobalFilterTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/io/Serializable/serialFilter/SerialFilterFactoryTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -java/nio/channels/DatagramChannel/AdaptorMulticasting.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-x64,windows-all +java/nio/channels/DatagramChannel/AdaptorMulticasting.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/nio/channels/Selector/SelectWithConsumer.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -java/nio/channels/etc/OpenAndConnect.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-x64,windows-all -java/nio/channels/etc/ProtocolFamilies.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-x64,windows-all +java/nio/channels/etc/OpenAndConnect.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +java/nio/channels/etc/ProtocolFamilies.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/nio/channels/unixdomain/IOExchanges.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/nio/channels/unixdomain/Security.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all java/nio/file/Files/CopyToNonDefaultFS.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -623,7 +624,7 @@ javax/net/ssl/TLSv11/ExportableStreamCipher.java https://github.com/ibmruntimes/ javax/net/ssl/TLSv11/GenericBlockCipher.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/net/ssl/TLSv11/GenericStreamCipher.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/net/ssl/TLSv11/TLSDataExchangeTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -javax/net/ssl/TLSv11/TLSEnginesClosureTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +javax/net/ssl/TLSv11/TLSEnginesClosureTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/net/ssl/TLSv11/TLSHandshakeTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/net/ssl/TLSv11/TLSMFLNTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all javax/net/ssl/TLSv11/TLSNotEnabledRC4Test.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -672,7 +673,7 @@ jdk/nio/zipfs/PropertyPermissionTests.java https://github.com/ibmruntimes/openj9 jdk/nio/zipfs/TestPosix.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all jdk/nio/zipfs/ZFSTests.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all jdk/nio/zipfs/ZipFSPermissionsTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -jdk/nio/zipfs/ZipFSTester.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 aix-all,linux-ppc64le,linux-s390x,windows-all +jdk/nio/zipfs/ZipFSTester.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all jdk/security/jarsigner/Function.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all jdk/security/jarsigner/Properties.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -691,7 +692,7 @@ sun/security/ec/SignatureDigestTruncate.java https://github.com/ibmruntimes/open sun/security/ec/SignatureKAT.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ec/SignatureParameters.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ec/SignedObjectChain.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/ec/TestEC.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/ec/TestEC.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ec/ed/EdCRLSign.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ec/ed/EdDSAKeyCompatibility.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ec/ed/EdDSAKeySize.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -707,17 +708,17 @@ sun/security/ec/xec/TestXDH.java https://github.com/ibmruntimes/openj9-openjdk-j sun/security/ec/xec/XECKeyFormat.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/jca/PreferredProviderNegativeTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/jca/PreferredProviderTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/mscapi/AccessKeyStore.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/AllTypes.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/DupAlias.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/EncodingMutability.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/IsSunMSCAPIAvailable.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/IterateWindowsRootStore.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/KeyStoreCompatibilityMode.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/KeytoolChangeAlias.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/NullKey.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/PrngSerialize.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all -sun/security/mscapi/PrngSlow.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 windows-all +sun/security/mscapi/AccessKeyStore.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/AllTypes.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/DupAlias.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/EncodingMutability.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/IsSunMSCAPIAvailable.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/IterateWindowsRootStore.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/KeyStoreCompatibilityMode.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/KeytoolChangeAlias.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/NullKey.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/PrngSerialize.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all +sun/security/mscapi/PrngSlow.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs/pkcs7/PKCS7VerifyTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs/pkcs7/SignerOrder.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -726,7 +727,7 @@ sun/security/pkcs/pkcs8/TestLeadingZeros.java https://github.com/ibmruntimes/ope sun/security/pkcs11/KeyStore/ClientAuth.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs11/Provider/Absolute.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs11/SecretKeyFactory/TestPBKD.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 aix-all,linux-s390x,linux-x64,windows-all +sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs12/Bug6415637.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs12/EmptyPassword.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/pkcs12/GetAttributes.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -816,12 +817,12 @@ sun/security/ssl/AppInputStream/ReadZeroBytes.java https://github.com/ibmruntime sun/security/ssl/AppInputStream/RemoveMarkReset.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/AppOutputStream/NoExceptionOnClose.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/CertPathRestrictions/TLSRestrictions.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/ssl/CipherSuite/DisabledCurve.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/ssl/CipherSuite/DisabledCurve.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/CipherSuite/LegacyConstraints.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/ssl/CipherSuite/NamedGroupsWithCipherSuite.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/ssl/CipherSuite/NamedGroupsWithCipherSuite.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/CipherSuite/RestrictNamedGroup.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/CipherSuite/RestrictSignatureScheme.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/ssl/CipherSuite/SupportedGroups.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/ssl/CipherSuite/SupportedGroups.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/ClientHandshaker/CipherSuiteOrder.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/ClientHandshaker/LengthCheckTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/ssl/ClientHandshaker/RSAExport.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all @@ -935,7 +936,7 @@ sun/security/tools/jarsigner/EntriesOrder.java https://github.com/ibmruntimes/op sun/security/tools/jarsigner/JarSigningNonAscii.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/tools/jarsigner/LargeJarEntry.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/tools/jarsigner/LineBrokenMultiByteCharacter.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all -sun/security/tools/jarsigner/PreserveRawManifestEntryAndDigest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 linux-ppc64le,linux-s390x,linux-x64,windows-all +sun/security/tools/jarsigner/PreserveRawManifestEntryAndDigest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/tools/jarsigner/Test4431684.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/tools/jarsigner/TimestampCheck.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all sun/security/tools/jarsigner/TsacertOptionTest.java https://github.com/ibmruntimes/openj9-openjdk-jdk/issues/820 generic-all