diff --git a/.editorconfig b/.editorconfig index 0e6c17e76740d..98f07b3c5fbbd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,3 +5,7 @@ trim_trailing_whitespace = true [Makefile] trim_trailing_whitespace = true + +[src/hotspot/**.{cpp,hpp,h}] +indent_style = space +indent_size = 2 diff --git a/doc/building.html b/doc/building.html index 1e6f99e97c93d..722fe6b8d1256 100644 --- a/doc/building.html +++ b/doc/building.html @@ -376,7 +376,7 @@
It is recommended that you use at least macOS 13 (Ventura) and Xcode -14, but earlier versions may also work.
+It is recommended that you use at least macOS 14 and Xcode 15.4, but +earlier versions may also work.
The standard macOS environment contains the basic tooling needed to build, but for external libraries a package manager is recommended. The JDK uses homebrew in the examples, but @@ -590,11 +590,11 @@
The string representation of the specified object is obtained as if - * by calling {@link String#valueOf(Object)}. - * - * @param obj - * An object whose string representation is to be written, - * may be {@code null}. - * - * @return This console - * - * @since 23 - */ - @PreviewFeature(feature = PreviewFeature.Feature.IMPLICIT_CLASSES) - public Console print(Object obj) { - throw newUnsupportedOperationException(); - } - - /** - * Writes a prompt as if by calling {@code print}, then reads a single line - * of text from this console. - * - * @param prompt - * A prompt string, may be {@code null}. - * - * @throws IOError - * If an I/O error occurs. - * - * @return A string containing the line read from the console, not - * including any line-termination characters, or {@code null} - * if an end of stream has been reached without having read - * any characters. - * - * @since 23 - */ - @PreviewFeature(feature = PreviewFeature.Feature.IMPLICIT_CLASSES) - public String readln(String prompt) { - throw newUnsupportedOperationException(); - } - - /** - * Reads a single line of text from this console. - * - * @throws IOError - * If an I/O error occurs. - * - * @return A string containing the line read from the console, not - * including any line-termination characters, or {@code null} - * if an end of stream has been reached without having read - * any characters. - * - * @since 24 - */ - @PreviewFeature(feature = PreviewFeature.Feature.IMPLICIT_CLASSES) - public String readln() { - throw newUnsupportedOperationException(); - } - /** * Writes a formatted string to this console's output stream using * the specified format string and arguments with the diff --git a/src/java.base/share/classes/java/io/FilePermission.java b/src/java.base/share/classes/java/io/FilePermission.java index aa6f11e00ee87..883f0410b6dc8 100644 --- a/src/java.base/share/classes/java/io/FilePermission.java +++ b/src/java.base/share/classes/java/io/FilePermission.java @@ -34,11 +34,9 @@ import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; -import jdk.internal.access.JavaIOFilePermissionAccess; -import jdk.internal.access.SharedSecrets; import sun.nio.fs.DefaultFileSystemProvider; -import sun.security.util.FilePermCompat; import sun.security.util.SecurityConstants; +import sun.security.util.SecurityProperties; /** * This class represents access to a file or directory. A FilePermission consists @@ -155,6 +153,26 @@ public final class FilePermission extends Permission implements Serializable { private static final char RECURSIVE_CHAR = '-'; private static final char WILD_CHAR = '*'; + /** + * New behavior? Keep compatibility? + * The new behavior does not use the canonical path normalization + */ + private static final boolean nb = initNb(); + + // Initialize the nb flag from the System property jdk.io.permissionsUseCanonicalPath. + private static boolean initNb() { + String flag = SecurityProperties.getOverridableProperty( + "jdk.io.permissionsUseCanonicalPath"); + return switch (flag) { + case "true" -> false; // compatibility mode to canonicalize paths + case "false" -> true; // do not canonicalize + case null -> true; // default, do not canonicalize + default -> + throw new RuntimeException( + "Invalid jdk.io.permissionsUseCanonicalPath: " + flag); + }; + } + // public String toString() { // StringBuilder sb = new StringBuilder(); // sb.append("*** FilePermission on " + getName() + " ***"); @@ -232,51 +250,49 @@ private static Path altPath(Path in) { } } - static { - SharedSecrets.setJavaIOFilePermissionAccess( - /** - * Creates FilePermission objects with special internals. - * See {@link FilePermCompat#newPermPlusAltPath(Permission)} and - * {@link FilePermCompat#newPermUsingAltPath(Permission)}. - */ - new JavaIOFilePermissionAccess() { - public FilePermission newPermPlusAltPath(FilePermission input) { - if (!input.invalid && input.npath2 == null && !input.allFiles) { - Path npath2 = altPath(input.npath); - if (npath2 != null) { - // Please note the name of the new permission is - // different than the original so that when one is - // added to a FilePermissionCollection it will not - // be merged with the original one. - return new FilePermission(input.getName() + "#plus", - input, - input.npath, - npath2, - input.mask, - input.actions); - } - } - return input; - } - public FilePermission newPermUsingAltPath(FilePermission input) { - if (!input.invalid && !input.allFiles) { - Path npath2 = altPath(input.npath); - if (npath2 != null) { - // New name, see above. - return new FilePermission(input.getName() + "#using", - input, - npath2, - null, - input.mask, - input.actions); - } - } - return null; - } + // Construct a new Permission with altPath + // Used by test FilePermissionCollectionMerge + private FilePermission newPermPlusAltPath() { + System.err.println("PlusAlt path: " + this + ", npath: " + npath); + if (nb && !invalid && npath2 == null && !allFiles) { + Path npath2 = altPath(npath); + if (npath2 != null) { + // Please note the name of the new permission is + // different than the original so that when one is + // added to a FilePermissionCollection it will not + // be merged with the original one. + return new FilePermission(getName() + "#plus", + this, + npath, + npath2, + mask, + actions); } - ); + } + return this; } + // Construct a new Permission adding altPath + // Used by test FilePermissionCollectionMerge + private FilePermission newPermUsingAltPath() { + System.err.println("Alt path: " + this + ", npath: " + npath); + if (!invalid && !allFiles) { + Path npath2 = altPath(npath); + if (npath2 != null) { + // New name, see above. + return new FilePermission(getName() + "#using", + this, + npath2, + null, + mask, + actions); + } + } + return this; +} + + + /** * initialize a FilePermission object. Common to all constructors. * Also called during de-serialization. @@ -291,7 +307,7 @@ private void init(int mask) { if (mask == NONE) throw new IllegalArgumentException("invalid actions mask"); - if (FilePermCompat.nb) { + if (nb) { String name = getName(); if (name == null) @@ -567,7 +583,7 @@ boolean impliesIgnoreMask(FilePermission that) { if (that.allFiles) { return false; } - if (FilePermCompat.nb) { + if (nb) { // Left at least same level of wildness as right if ((this.recursive && that.recursive) != that.recursive || (this.directory && that.directory) != that.directory) { @@ -766,7 +782,7 @@ public boolean equals(Object obj) { if (this.invalid || that.invalid) { return false; } - if (FilePermCompat.nb) { + if (nb) { return (this.mask == that.mask) && (this.allFiles == that.allFiles) && this.npath.equals(that.npath) && @@ -789,7 +805,7 @@ public boolean equals(Object obj) { */ @Override public int hashCode() { - if (FilePermCompat.nb) { + if (nb) { return Objects.hash( mask, allFiles, directory, recursive, npath, npath2, invalid); } else { diff --git a/src/java.base/share/classes/java/io/IO.java b/src/java.base/share/classes/java/io/IO.java deleted file mode 100644 index a49a51041fc04..0000000000000 --- a/src/java.base/share/classes/java/io/IO.java +++ /dev/null @@ -1,143 +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. 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.io; - -import jdk.internal.javac.PreviewFeature; - -/** - * A collection of static convenience methods that provide access to - * {@linkplain System#console() system console} for implicitly declared classes. - * - *
Each of this class' methods throws {@link IOError} if the system console - * is {@code null}; otherwise, the effect is as if a similarly-named method - * had been called on that console. - * - *
Input and output from methods in this class use the character set of - * the system console as specified by {@link Console#charset}. - * - * @since 23 - */ -@PreviewFeature(feature = PreviewFeature.Feature.IMPLICIT_CLASSES) -public final class IO { - - private IO() { - throw new Error("no instances"); - } - - /** - * Writes a string representation of the specified object to the system - * console, terminates the line and then flushes that console. - * - *
The effect is as if {@link Console#println(Object) println(obj)} - * had been called on {@code System.console()}. - * - * @param obj the object to print, may be {@code null} - * - * @throws IOError if {@code System.console()} returns {@code null}, - * or if an I/O error occurs - */ - public static void println(Object obj) { - con().println(obj); - } - - /** - * Terminates the current line on the system console and then flushes - * that console. - * - *
The effect is as if {@link Console#println() println()} - * had been called on {@code System.console()}. - * - * @throws IOError if {@code System.console()} returns {@code null}, - * or if an I/O error occurs - * @since 24 - */ - public static void println() { - con().println(); - } - - /** - * Writes a string representation of the specified object to the system - * console and then flushes that console. - * - *
The effect is as if {@link Console#print(Object) print(obj)} - * had been called on {@code System.console()}. - * - * @param obj the object to print, may be {@code null} - * - * @throws IOError if {@code System.console()} returns {@code null}, - * or if an I/O error occurs - */ - public static void print(Object obj) { - con().print(obj); - } - - /** - * Writes a prompt as if by calling {@code print}, then reads a single line - * of text from the system console. - * - *
The effect is as if {@link Console#readln(String) readln(prompt)} - * had been called on {@code System.console()}. - * - * @param prompt the prompt string, may be {@code null} - * - * @return a string containing the line read from the system console, not - * including any line-termination characters. Returns {@code null} if an - * end of stream has been reached without having read any characters. - * - * @throws IOError if {@code System.console()} returns {@code null}, - * or if an I/O error occurs - */ - public static String readln(String prompt) { - return con().readln(prompt); - } - - /** - * Reads a single line of text from the system console. - * - *
The effect is as if {@link Console#readln() readln()}
- * had been called on {@code System.console()}.
- *
- * @return a string containing the line read from the system console, not
- * including any line-termination characters. Returns {@code null} if an
- * end of stream has been reached without having read any characters.
- *
- * @throws IOError if {@code System.console()} returns {@code null},
- * or if an I/O error occurs
- * @since 24
- */
- public static String readln() {
- return con().readln();
- }
-
- private static Console con() {
- var con = System.console();
- if (con != null) {
- return con;
- } else {
- throw new IOError(null);
- }
- }
-}
diff --git a/src/java.base/share/classes/java/io/ProxyingConsole.java b/src/java.base/share/classes/java/io/ProxyingConsole.java
index cc5cd92626470..5c8da9f51da19 100644
--- a/src/java.base/share/classes/java/io/ProxyingConsole.java
+++ b/src/java.base/share/classes/java/io/ProxyingConsole.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
@@ -81,54 +81,6 @@ public Reader reader() {
return reader;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public Console println(Object obj) {
- synchronized (writeLock) {
- delegate.println(obj);
- }
- return this;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Console print(Object obj) {
- synchronized (writeLock) {
- delegate.print(obj);
- }
- return this;
- }
-
- /**
- * {@inheritDoc}
- *
- * @throws IOError {@inheritDoc}
- */
- @Override
- public String readln(String prompt) {
- synchronized (writeLock) {
- synchronized (readLock) {
- return delegate.readln(prompt);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @throws IOError {@inheritDoc}
- */
- @Override
- public String readln() {
- synchronized (readLock) {
- return delegate.readln();
- }
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
index c2f90e228020d..b8d209b8a6e24 100644
--- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
+++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.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
@@ -29,7 +29,6 @@
import jdk.internal.math.FloatToDecimal;
import jdk.internal.util.DecimalDigits;
-import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.Spliterator;
@@ -360,8 +359,12 @@ public void setLength(int newLength) {
*/
@Override
public char charAt(int index) {
+ byte coder = this.coder;
+ byte[] value = this.value;
+ // Ensure count is less than or equal to capacity (racy reads and writes can produce inconsistent values)
+ int count = Math.min(this.count, value.length >> coder);
checkIndex(index, count);
- if (isLatin1()) {
+ if (coder == LATIN1) {
return (char)(value[index] & 0xff);
}
return StringUTF16.getChar(value, index);
@@ -420,6 +423,7 @@ public int codePointAt(int index) {
* of this sequence.
*/
public int codePointBefore(int index) {
+ byte[] value = this.value;
int i = index - 1;
checkIndex(i, count);
if (isLatin1()) {
@@ -1730,7 +1734,7 @@ private final void putCharsAt(int index, CharSequence s, int off, int end) {
} else {
inflate();
// store c to make sure it has a UTF16 char
- StringUTF16.putChar(this.value, j++, c);
+ StringUTF16.putCharSB(this.value, j++, c);
i++;
StringUTF16.putCharsSB(this.value, j, s, i, end);
return;
@@ -1825,7 +1829,7 @@ private final void appendChars(CharSequence s, int off, int end) {
count = j;
inflate();
// Store c to make sure sb has a UTF16 char
- StringUTF16.putChar(this.value, j++, c);
+ StringUTF16.putCharSB(this.value, j++, c);
count = j;
i++;
StringUTF16.putCharsSB(this.value, j, s, i, end);
diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java
index aa64d799b6655..4c24e98a549ac 100644
--- a/src/java.base/share/classes/java/lang/Boolean.java
+++ b/src/java.base/share/classes/java/lang/Boolean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* 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,7 +104,7 @@ public final class Boolean implements java.io.Serializable,
* Also consider using the final fields {@link #TRUE} and {@link #FALSE}
* if possible.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Boolean(boolean value) {
this.value = value;
}
@@ -124,7 +124,7 @@ public Boolean(boolean value) {
* {@code boolean} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Boolean} object.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Boolean(String s) {
this(parseBoolean(s));
}
diff --git a/src/java.base/share/classes/java/lang/Byte.java b/src/java.base/share/classes/java/lang/Byte.java
index 5835f65366fb7..accd448a0cdc5 100644
--- a/src/java.base/share/classes/java/lang/Byte.java
+++ b/src/java.base/share/classes/java/lang/Byte.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
@@ -346,7 +346,7 @@ public static Byte decode(String nm) throws NumberFormatException {
* {@link #valueOf(byte)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Byte(byte value) {
this.value = value;
}
@@ -369,7 +369,7 @@ public Byte(byte value) {
* {@code byte} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Byte} object.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10);
}
diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java
index f5a9ab77b5240..a439a90761d48 100644
--- a/src/java.base/share/classes/java/lang/Character.java
+++ b/src/java.base/share/classes/java/lang/Character.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
@@ -9232,7 +9232,7 @@ public static final UnicodeScript forName(String scriptName) {
* {@link #valueOf(char)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Character(char value) {
this.value = value;
}
@@ -11089,6 +11089,7 @@ public static boolean isIdentifierIgnorable(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character is an Emoji;
* {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isEmoji(int codePoint) {
@@ -11107,6 +11108,7 @@ public static boolean isEmoji(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character has the Emoji Presentation
* property; {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isEmojiPresentation(int codePoint) {
@@ -11125,6 +11127,7 @@ public static boolean isEmojiPresentation(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character is an Emoji Modifier;
* {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isEmojiModifier(int codePoint) {
@@ -11143,6 +11146,7 @@ public static boolean isEmojiModifier(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character is an Emoji Modifier Base;
* {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isEmojiModifierBase(int codePoint) {
@@ -11161,6 +11165,7 @@ public static boolean isEmojiModifierBase(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character is an Emoji Component;
* {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isEmojiComponent(int codePoint) {
@@ -11179,6 +11184,7 @@ public static boolean isEmojiComponent(int codePoint) {
* @param codePoint the character (Unicode code point) to be tested.
* @return {@code true} if the character is an Extended Pictographic;
* {@code false} otherwise.
+ * @spec https://unicode.org/reports/tr51/ Unicode Emoji
* @since 21
*/
public static boolean isExtendedPictographic(int codePoint) {
diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index d86baaac3621a..8be5ae8fa1521 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -1384,10 +1384,8 @@ public Set
+ * The {@link #readln()} and {@link #readln(String)} methods decode bytes read from
+ * {@code System.in} into characters. The charset used for decoding is specified by the
+ * {@link System#getProperties stdin.encoding} property. If this property is not present,
+ * or if the charset it names cannot be loaded, then UTF-8 is used instead. Decoding
+ * always replaces malformed and unmappable byte sequences with the charset's default
+ * replacement string.
+ *
+ * Charset decoding is set up upon the first call to one of the {@code readln} methods.
+ * Decoding may buffer additional bytes beyond those that have been decoded to characters
+ * returned to the application. After the first call to one of the {@code readln} methods,
+ * any subsequent use of {@code System.in} results in unspecified behavior.
+ *
+ * @apiNote
+ * The expected use case is that certain applications will use only the {@code readln}
+ * methods to read from the standard input, and they will not mix these calls with
+ * other techniques for reading from {@code System.in}.
+ *
+ * @since 25
+ */
+public final class IO {
+
+ /*
+ * We are deliberately not including printf, at least not initially, for
+ * the following reasons. First, it introduces a rather cryptic and arcane
+ * formatting language that isn't really suited to beginners. Second, it
+ * is inherently localizable, which drags in a whole bunch of issues about
+ * what locale should be used for formatting, the possible inclusion of
+ * an overload with an explicit Locale parameter, and so forth. These issues
+ * are best avoided for the time being. Third, when string templates come
+ * along, they might offer a better alternative to printf-style formatting,
+ * so it's best not be saddled with this unnecessarily.
+ */
+
+ /*
+ * Notes on flushing. We want flushing to occur after every call to println
+ * and print, so that the user can see output immediately. This could be
+ * important if the user calls print() to issue a prompt before calling
+ * readln() instead of the readln(prompt) overload. It's also important to
+ * flush after print() in case the user is relying on print() to emit output
+ * as sort of a progress indicator.
+ *
+ * We rely on System.out to have autoflush enabled, which flushes after every
+ * println() call, so we needn't flush again. We flush unconditionally after
+ * calls to print(). Since System.out is doing a lot of flushing anyway, there
+ * isn't much point trying to make this conditional, for example, only if
+ * stdout is connected to a terminal.
+ */
+
+ private IO() {
+ throw new Error("no instances");
+ }
+
+ /**
+ * Writes a string representation of the specified object and then writes
+ * a line separator to the standard output.
+ *
+ * The effect is as if {@link java.io.PrintStream#println(Object) println(obj)}
+ * had been called on {@code System.out}.
+ *
+ * @param obj the object to print, may be {@code null}
+ */
+ public static void println(Object obj) {
+ System.out.println(obj);
+ }
+
+ /**
+ * Writes a line separator to the standard output.
+ *
+ * The effect is as if {@link java.io.PrintStream#println() println()}
+ * had been called on {@code System.out}.
+ */
+ public static void println() {
+ System.out.println();
+ }
+
+ /**
+ * Writes a string representation of the specified object to the
+ * standard output.
+ *
+ * The effect is as if {@link java.io.PrintStream#print(Object) print(obj)}
+ * had been called on {@code System.out}.
+ *
+ * @param obj the object to print, may be {@code null}
+ */
+ public static void print(Object obj) {
+ var out = System.out;
+ out.print(obj);
+ out.flush();
+ }
+
+ /**
+ * Reads a single line of text from the standard input.
+ *
+ * One line is read from the decoded input as if by
+ * {@link java.io.BufferedReader#readLine() BufferedReader.readLine()}
+ * and then the result is returned.
+ *
+ * If necessary, this method first sets up charset decoding, as described in
+ * above in the class specification.
+ *
+ * @return a string containing the line read from the standard input, not
+ * including any line separator characters. Returns {@code null} if an
+ * end of stream has been reached without having read any characters.
+ *
+ * @throws IOError if an I/O error occurs
+ */
+ public static String readln() {
+ try {
+ return reader().readLine();
+ } catch (IOException ioe) {
+ throw new IOError(ioe);
+ }
+ }
+
+ /**
+ * Writes a prompt and then reads a line of input.
+ *
+ * Writes a prompt as if by calling {@link #print print}, and then reads a single
+ * line of text as if by calling {@link #readln() readln}.
+ *
+ * If necessary, this method first sets up charset decoding, as described in
+ * above in the class specification.
+ *
+ * @param prompt the prompt string, may be {@code null}
+ *
+ * @return a string containing the line read from the standard input, not
+ * including any line separator characters. Returns {@code null} if an
+ * end of stream has been reached without having read any characters.
+ *
+ * @throws IOError if an I/O error occurs
+ */
+ public static String readln(String prompt) {
+ print(prompt);
+ return readln();
+ }
+
+ /**
+ * The BufferedReader used by readln(). Initialized under a class lock by
+ * the reader() method. All access should be through the reader() method.
+ */
+ private static BufferedReader br;
+
+ /**
+ * On the first call, creates an InputStreamReader to decode characters from
+ * System.in, wraps it in a BufferedReader, and returns the BufferedReader.
+ * These objects are cached and returned by subsequent calls.
+ *
+ * @return the internal BufferedReader instance
+ */
+ static synchronized BufferedReader reader() {
+ if (br == null) {
+ String enc = System.getProperty("stdin.encoding", "");
+ Charset cs = Charset.forName(enc, StandardCharsets.UTF_8);
+ br = new BufferedReader(new InputStreamReader(System.in, cs));
+ }
+ return br;
+ }
+}
diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java
index 99b056ec18a3f..1350a66b66c7c 100644
--- a/src/java.base/share/classes/java/lang/Integer.java
+++ b/src/java.base/share/classes/java/lang/Integer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1024,7 +1024,7 @@ public static Integer valueOf(int i) {
* {@link #valueOf(int)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Integer(int value) {
this.value = value;
}
@@ -1046,7 +1046,7 @@ public Integer(int value) {
* {@code int} primitive, or use {@link #valueOf(String)}
* to convert a string to an {@code Integer} object.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java
index c401fcd8027e5..3093f37e99ac7 100644
--- a/src/java.base/share/classes/java/lang/Long.java
+++ b/src/java.base/share/classes/java/lang/Long.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1109,7 +1109,7 @@ else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
* {@link #valueOf(long)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Long(long value) {
this.value = value;
}
@@ -1132,7 +1132,7 @@ public Long(long value) {
* {@code long} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Long} object.
*/
- @Deprecated(since="9", forRemoval = true)
+ @Deprecated(since="9")
public Long(String s) throws NumberFormatException {
this.value = parseLong(s, 10);
}
diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java
index dcc92d012de59..065e1ac46208e 100644
--- a/src/java.base/share/classes/java/lang/Module.java
+++ b/src/java.base/share/classes/java/lang/Module.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
@@ -40,7 +40,6 @@
import java.net.URI;
import java.net.URL;
import java.security.CodeSource;
-import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -688,7 +687,6 @@ public boolean isOpen(String pn) {
return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/true);
}
-
/**
* Returns {@code true} if this module exports or opens the given package
* to the given module. If the other module is {@code EVERYONE_MODULE} then
@@ -707,12 +705,12 @@ private boolean implIsExportedOrOpen(String pn, Module other, boolean open) {
if (descriptor.isOpen() || descriptor.isAutomatic())
return descriptor.packages().contains(pn);
- // exported/opened via module declaration/descriptor
- if (isStaticallyExportedOrOpen(pn, other, open))
+ // exported/opened via module declaration/descriptor or CLI options
+ if (isExplicitlyExportedOrOpened(pn, other, open))
return true;
// exported via addExports/addOpens
- if (isReflectivelyExportedOrOpen(pn, other, open))
+ if (isReflectivelyExportedOrOpened(pn, other, open))
return true;
// not exported or open to other
@@ -723,7 +721,7 @@ private boolean implIsExportedOrOpen(String pn, Module other, boolean open) {
* Returns {@code true} if this module exports or opens a package to
* the given module via its module declaration or CLI options.
*/
- private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
+ private boolean isExplicitlyExportedOrOpened(String pn, Module other, boolean open) {
// test if package is open to everyone or
+ * A {@code StableValue
+ * Consider the following example where a stable value field "{@code logger}" is a
+ * shallowly immutable holder of contents of type {@code Logger} and that is initially
+ * created as unset, which means it holds no contents. Later in the example, the
+ * state of the "{@code logger}" field is checked and if it is still unset,
+ * the contents is set:
+ *
+ * {@snippet lang = java:
+ * public class Component {
+ *
+ * // Creates a new unset stable value with no contents
+ * // @link substring="of" target="#of" :
+ * private final StableValue
+ * If {@code getLogger()} is called from several threads, several instances of
+ * {@code Logger} might be created. However, the contents can only be set at most once
+ * meaning the first writer wins.
+ *
+ * In order to guarantee that, even under races, only one instance of {@code Logger} is
+ * ever created, the {@linkplain #orElseSet(Supplier) orElseSet()} method can be used
+ * instead, where the contents are lazily computed, and atomically set, via a
+ * {@linkplain Supplier supplier}. In the example below, the supplier is provided in the
+ * form of a lambda expression:
+ *
+ * {@snippet lang = java:
+ * public class Component {
+ *
+ * // Creates a new unset stable value with no contents
+ * // @link substring="of" target="#of" :
+ * private final StableValue
+ * The {@code getLogger()} method calls {@code logger.orElseSet()} on the stable value to
+ * retrieve its contents. If the stable value is unset, then {@code orElseSet()}
+ * evaluates the given supplier, and sets the contents to the result; the result is then
+ * returned to the client. In other words, {@code orElseSet()} guarantees that a
+ * stable value's contents is set before it returns.
+ *
+ * Furthermore, {@code orElseSet()} guarantees that out of one or more suppliers provided,
+ * only at most one is ever evaluated, and that one is only ever evaluated once,
+ * even when {@code logger.orElseSet()} is invoked concurrently. This property is crucial
+ * as evaluation of the supplier may have side effects, for example, the call above to
+ * {@code Logger.create()} may result in storage resources being prepared.
+ *
+ *
+ * A stable int function is a function that takes an {@code int} parameter and
+ * uses it to compute a result that is then cached by the backing stable value storage
+ * for that parameter value. A stable {@link IntFunction} is created via the
+ * {@linkplain StableValue#intFunction(int, IntFunction) StableValue.intFunction()}
+ * factory. Upon creation, the input range (i.e. {@code [0, size)}) is specified together
+ * with an underlying {@linkplain IntFunction} which is invoked at most once per input
+ * value. In effect, the stable int function will act like a cache for the underlying
+ * {@linkplain IntFunction}:
+ *
+ * {@snippet lang = java:
+ * final class PowerOf2Util {
+ *
+ * private PowerOf2Util() {}
+ *
+ * private static final int SIZE = 6;
+ * private static final IntFunction
+ * A stable function is a function that takes a parameter (of type {@code T}) and
+ * uses it to compute a result (of type {@code R}) that is then cached by the backing
+ * stable value storage for that parameter value. A stable function is created via the
+ * {@linkplain StableValue#function(Set, Function) StableValue.function()} factory.
+ * Upon creation, the input {@linkplain Set} is specified together with an underlying
+ * {@linkplain Function} which is invoked at most once per input value. In effect, the
+ * stable function will act like a cache for the underlying {@linkplain Function}:
+ *
+ * {@snippet lang = java:
+ * class Log2Util {
+ *
+ * private Log2Util() {}
+ *
+ * private static final Set
+ * Similarly, a stable map is an unmodifiable map whose keys are known at
+ * construction. The stable map values are computed when they are first accessed,
+ * using a provided {@linkplain Function}:
+ *
+ * {@snippet lang = java:
+ * class Log2Util {
+ *
+ * private Log2Util() {}
+ *
+ * private static final Set
+ * Another example, which has a more complex dependency graph, is to compute the
+ * Fibonacci sequence lazily:
+ * {@snippet lang = java:
+ * public final class Fibonacci {
+ *
+ * private Fibonacci() {}
+ *
+ * private static final int MAX_SIZE_INT = 46;
+ *
+ * private static final IntFunction
+ * The fibonacci example above is a directed acyclic graph (i.e.,
+ * it has no circular dependencies and is therefore a dependency tree):
+ *{@snippet lang=text :
+ *
+ * ___________fib(5)____________
+ * / \
+ * ____fib(4)____ ____fib(3)____
+ * / \ / \
+ * fib(3) fib(2) fib(2) fib(1)
+ * / \ / \ / \
+ * fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
+ *}
+ *
+ * If there are circular dependencies in a dependency graph, a stable value will
+ * eventually throw an {@linkplain IllegalStateException} upon referencing elements in
+ * a circularity.
+ *
+ *
+ * The at-most-once write operation on a stable value that succeeds
+ * (e.g. {@linkplain #trySet(Object) trySet()})
+ * {@linkplain java.util.concurrent##MemoryVisibility happens-before}
+ * any successful read operation (e.g. {@linkplain #orElseThrow()}).
+ * A successful write operation can be either:
+ *
+ * The method {@link #orElseSet(Supplier)} guarantees that the provided
+ * {@linkplain Supplier} is invoked successfully at most once, even under race.
+ * Invocations of {@link #setOrThrow(Object)} form a total order of zero or more
+ * exceptional invocations followed by zero (if the contents were already set) or one
+ * successful invocation. Since stable functions and stable collections are built on top
+ * of the same principles as {@linkplain StableValue#orElseSet(Supplier) orElseSet()} they
+ * too are thread safe and guarantee at-most-once-per-input invocation.
+ *
+ *
+ * Except for a {@code StableValue}'s contents itself,
+ * an {@linkplain #orElse(Object) orElse(other)} parameter, and
+ * an {@linkplain #equals(Object) equals(obj)} parameter; all
+ * method parameters must be non-null or a {@link NullPointerException}
+ * will be thrown.
+ *
+ * @implNote A {@code StableValue} is mainly intended to be a non-public field in
+ * a class and is usually neither exposed directly via accessors nor passed as
+ * a method parameter.
+ *
+ * Stable functions and collections make reasonable efforts to provide
+ * {@link Object#toString()} operations that do not trigger evaluation
+ * of the internal stable values when called.
+ * Stable collections have {@link Object#equals(Object)} operations that try
+ * to minimize evaluation of the internal stable values when called.
+ *
+ * As objects can be set via stable values but never removed, this can be a
+ * source of unintended memory leaks. A stable value's contents are
+ * {@linkplain java.lang.ref##reachability strongly reachable}.
+ * Be advised that reachable stable values will hold their set contents until
+ * the stable value itself is collected.
+ *
+ * A {@code StableValue} that has a type parameter {@code T} that is an array
+ * type (of arbitrary rank) will only allow the JVM to treat the
+ * array reference as a stable value but not its components.
+ * Instead, a {@linkplain #list(int, IntFunction) a stable list} of arbitrary
+ * depth can be used, which provides stable components. More generally, a
+ * stable value can hold other stable values of arbitrary depth and still
+ * provide transitive constantness.
+ *
+ * Stable values, functions, and collections are not {@link Serializable}.
+ *
+ * @param
+ * When this method returns, the contents of this StableValue is always set.
+ *
+ * @return {@code true} if the contents of this StableValue was set to the
+ * provided {@code contents}, {@code false} otherwise
+ * @param contents to set
+ * @throws IllegalStateException if a supplier invoked by {@link #orElseSet(Supplier)}
+ * recursively attempts to set this stable value by calling this method
+ * directly or indirectly.
+ */
+ boolean trySet(T contents);
+
+ /**
+ * {@return the contents if set, otherwise, returns the provided {@code other} value}
+ *
+ * @param other to return if the contents is not set
+ */
+ T orElse(T other);
+
+ /**
+ * {@return the contents if set, otherwise, throws {@code NoSuchElementException}}
+ *
+ * @throws NoSuchElementException if no contents is set
+ */
+ T orElseThrow();
+
+ /**
+ * {@return {@code true} if the contents is set, {@code false} otherwise}
+ */
+ boolean isSet();
+
+ /**
+ * {@return the contents; if unset, first attempts to compute and set the
+ * contents using the provided {@code supplier}}
+ *
+ * The provided {@code supplier} is guaranteed to be invoked at most once if it
+ * completes without throwing an exception. If this method is invoked several times
+ * with different suppliers, only one of them will be invoked provided it completes
+ * without throwing an exception.
+ *
+ * If the supplier throws an (unchecked) exception, the exception is rethrown and no
+ * contents is set. The most common usage is to construct a new object serving
+ * as a lazily computed value or memoized result, as in:
+ *
+ * {@snippet lang=java:
+ * Value v = stable.orElseSet(Value::new);
+ * }
+ *
+ * When this method returns successfully, the contents is always set.
+ *
+ * The provided {@code supplier} will only be invoked once even if invoked from
+ * several threads unless the {@code supplier} throws an exception.
+ *
+ * @param supplier to be used for computing the contents, if not previously set
+ * @throws IllegalStateException if the provided {@code supplier} recursively
+ * attempts to set this stable value.
+ */
+ T orElseSet(Supplier extends T> supplier);
+
+ // Convenience methods
+
+ /**
+ * Sets the contents of this StableValue to the provided {@code contents}, or, if
+ * already set, throws {@code IllegalStateException}.
+ *
+ * When this method returns (or throws an exception), the contents is always set.
+ *
+ * @param contents to set
+ * @throws IllegalStateException if the contents was already set
+ */
+ void setOrThrow(T contents);
+
+ // Object methods
+
+ /**
+ * {@return {@code true} if {@code this == obj}, {@code false} otherwise}
+ *
+ * @param obj to check for equality
+ */
+ boolean equals(Object obj);
+
+ /**
+ * {@return the {@linkplain System#identityHashCode(Object) identity hash code} of
+ * {@code this} object}
+ */
+ int hashCode();
+
+ // Factories
+
+ /**
+ * {@return a new unset stable value}
+ *
+ * An unset stable value has no contents.
+ *
+ * @param Stable Functions
+ * Stable values provide the foundation for higher-level functional abstractions. A
+ * stable supplier is a supplier that computes a value and then caches it into
+ * a backing stable value storage for subsequent use. A stable supplier is created via the
+ * {@linkplain StableValue#supplier(Supplier) StableValue.supplier()} factory, by
+ * providing an underlying {@linkplain Supplier} which is invoked when the stable supplier
+ * is first accessed:
+ *
+ * {@snippet lang = java:
+ * public class Component {
+ *
+ * private final SupplierStable Collections
+ * Stable values can also be used as backing storage for
+ * {@linkplain Collection##unmodifiable unmodifiable collections}. A stable list
+ * is an unmodifiable list, backed by an array of stable values. The stable list elements
+ * are computed when they are first accessed, using a provided {@linkplain IntFunction}:
+ *
+ * {@snippet lang = java:
+ * final class PowerOf2Util {
+ *
+ * private PowerOf2Util() {}
+ *
+ * private static final int SIZE = 6;
+ * private static final IntFunctionComposing stable values
+ * A stable value can depend on other stable values, forming a dependency graph
+ * that can be lazily computed but where access to individual elements can still be
+ * performant. In the following example, a single {@code Foo} and a {@code Bar}
+ * instance (that is dependent on the {@code Foo} instance) are lazily created, both of
+ * which are held by stable values:
+ * {@snippet lang = java:
+ * public final class DependencyUtil {
+ *
+ * private DependencyUtil() {}
+ *
+ * public static class Foo {
+ * // ...
+ * }
+ *
+ * public static class Bar {
+ * public Bar(Foo foo) {
+ * // ...
+ * }
+ * }
+ *
+ * private static final SupplierThread Safety
+ * The contents of a stable value is guaranteed to be set at most once. If competing
+ * threads are racing to set a stable value, only one update succeeds, while the other
+ * updates are blocked until the stable value is set, whereafter the other updates
+ * observes the stable value is set and leave the stable value unchanged.
+ *
+ *
+ * A successful read operation can be either:
+ *
+ *
+ * Performance
+ * As the contents of a stable value can never change after it has been set, a JVM
+ * implementation may, for a set stable value, elide all future reads of that
+ * stable value, and instead directly use any contents that it has previously observed.
+ * This is true if the reference to the stable value is a constant (e.g. in cases where
+ * the stable value itself is stored in a {@code static final} field). Stable functions
+ * and collections are built on top of StableValue. As such, they might also be eligible
+ * for the same JVM optimizations as for StableValue.
+ *
+ * @implSpec Implementing classes of {@code StableValue} are free to synchronize on
+ * {@code this} and consequently, it should be avoided to
+ * (directly or indirectly) synchronize on a {@code StableValue}. Hence,
+ * synchronizing on {@code this} may lead to deadlock.
+ *