diff --git a/src/java.base/share/classes/jdk/internal/util/SystemProps.java b/src/java.base/share/classes/jdk/internal/util/SystemProps.java index b6aa1ef855ed7..26110a1dab3c9 100644 --- a/src/java.base/share/classes/jdk/internal/util/SystemProps.java +++ b/src/java.base/share/classes/jdk/internal/util/SystemProps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, 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 @@ -74,20 +74,18 @@ public static Map initProperties() { putIfAbsent(props, "user.dir", raw.propDefault(Raw._user_dir_NDX)); putIfAbsent(props, "user.name", raw.propDefault(Raw._user_name_NDX)); - // Platform defined encoding cannot be overridden on the command line + // Platform defined encodings cannot be overridden on the command line put(props, "sun.jnu.encoding", raw.propDefault(Raw._sun_jnu_encoding_NDX)); - var nativeEncoding = ((raw.propDefault(Raw._file_encoding_NDX) == null) - ? raw.propDefault(Raw._sun_jnu_encoding_NDX) - : raw.propDefault(Raw._file_encoding_NDX)); + String nativeEncoding = raw.propDefault(Raw._native_encoding_NDX); put(props, "native.encoding", nativeEncoding); // "file.encoding" defaults to "UTF-8", unless specified in the command line // where "COMPAT" designates the native encoding. - var fileEncoding = props.getOrDefault("file.encoding", "UTF-8"); - if ("COMPAT".equals(fileEncoding)) { + String fileEncoding = props.get("file.encoding"); + if (fileEncoding == null) { + put(props, "file.encoding", "UTF-8"); + } else if ("COMPAT".equals(fileEncoding)) { put(props, "file.encoding", nativeEncoding); - } else { - putIfAbsent(props, "file.encoding", fileEncoding); } // "stdout/err.encoding", prepared for System.out/err. For compatibility @@ -209,17 +207,17 @@ private static void fillI18nProps(HashMap cmdProps, } /** - * Read the raw properties from native System.c. + * Read raw property values from the JVM command line and from + * platform-specific code using native methods in System.c. */ public static class Raw { - // Array indices written by native vmProperties() + // Indexes of array elements written by native platformProperties() // The order is arbitrary (but alphabetic for convenience) @Native private static final int _display_country_NDX = 0; @Native private static final int _display_language_NDX = 1 + _display_country_NDX; @Native private static final int _display_script_NDX = 1 + _display_language_NDX; @Native private static final int _display_variant_NDX = 1 + _display_script_NDX; - @Native private static final int _file_encoding_NDX = 1 + _display_variant_NDX; - @Native private static final int _file_separator_NDX = 1 + _file_encoding_NDX; + @Native private static final int _file_separator_NDX = 1 + _display_variant_NDX; @Native private static final int _format_country_NDX = 1 + _file_separator_NDX; @Native private static final int _format_language_NDX = 1 + _format_country_NDX; @Native private static final int _format_script_NDX = 1 + _format_language_NDX; @@ -234,7 +232,8 @@ public static class Raw { @Native private static final int _https_proxyPort_NDX = 1 + _https_proxyHost_NDX; @Native private static final int _java_io_tmpdir_NDX = 1 + _https_proxyPort_NDX; @Native private static final int _line_separator_NDX = 1 + _java_io_tmpdir_NDX; - @Native private static final int _os_arch_NDX = 1 + _line_separator_NDX; + @Native private static final int _native_encoding_NDX = 1 + _line_separator_NDX; + @Native private static final int _os_arch_NDX = 1 + _native_encoding_NDX; @Native private static final int _os_name_NDX = 1 + _os_arch_NDX; @Native private static final int _os_version_NDX = 1 + _os_name_NDX; @Native private static final int _path_separator_NDX = 1 + _os_version_NDX; @@ -255,7 +254,7 @@ public static class Raw { @Native private static final int _user_name_NDX = 1 + _user_home_NDX; @Native private static final int FIXED_LENGTH = 1 + _user_name_NDX; - // Array of Strings returned from the VM and Command line properties + // Array of property values returned from platform-specific native code // The array is not used after initialization is complete. private final String[] platformProps; @@ -264,27 +263,26 @@ private Raw() { } /** - * Return the value for a well known default from native. - * @param index the index of the known property - * @return the value + * Returns a property value obtained from platform-specific native code. + * @param index the index of the property + * @return the property value, may be null */ String propDefault(int index) { return platformProps[index]; } /** - * Return a Properties instance of the command line and VM options - * defined by name and value. - * The Properties instance is sized to include the fixed properties. + * Returns a HashMap containing properties obtained from the command line + * and from the JVM. The HashMap is sized to include the platform properties. * - * @return return a Properties instance of the command line and VM options + * @return return a HashMap containing command line and JVM properties */ private HashMap cmdProperties() { String[] vmProps = vmProperties(); - // While optimal initialCapacity here would be the exact number of properties - // divided by LOAD_FACTOR, a large portion of the properties in Raw are - // usually not set, so for typical cases the chosen capacity avoids resizing - var cmdProps = new HashMap((vmProps.length / 2) + Raw.FIXED_LENGTH); + // Many platformProperties are null, so this initial size is an overestimate. + // However, more properties are added later, including encoding properties + // and version properties, so the excess space is justified. + HashMap cmdProps = HashMap.newHashMap((vmProps.length / 2) + Raw.FIXED_LENGTH); for (int i = 0; i < vmProps.length;) { String k = vmProps[i++]; if (k != null) { diff --git a/src/java.base/share/native/libjava/System.c b/src/java.base/share/native/libjava/System.c index 7b038a6a9d59b..530828b17420e 100644 --- a/src/java.base/share/native/libjava/System.c +++ b/src/java.base/share/native/libjava/System.c @@ -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 @@ -146,20 +146,19 @@ Java_jdk_internal_util_SystemProps_00024Raw_platformProperties(JNIEnv *env, jcla PUTPROP(propArray, _path_separator_NDX, sprops->path_separator); PUTPROP(propArray, _line_separator_NDX, sprops->line_separator); + /* basic encoding properties, always non-NULL */ #ifdef MACOSX /* * Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't - * want to use it to overwrite file.encoding + * want to use it to overwrite native.encoding */ - PUTPROP(propArray, _file_encoding_NDX, sprops->encoding); + PUTPROP(propArray, _native_encoding_NDX, sprops->encoding); #else - PUTPROP(propArray, _file_encoding_NDX, sprops->sun_jnu_encoding); + PUTPROP(propArray, _native_encoding_NDX, sprops->sun_jnu_encoding); #endif PUTPROP(propArray, _sun_jnu_encoding_NDX, sprops->sun_jnu_encoding); - /* - * file encoding for stdout and stderr - */ + /* encodings for standard streams, may be NULL */ PUTPROP(propArray, _stdout_encoding_NDX, sprops->stdout_encoding); PUTPROP(propArray, _stderr_encoding_NDX, sprops->stderr_encoding); diff --git a/src/java.base/share/native/libjava/java_props.h b/src/java.base/share/native/libjava/java_props.h index 592c158c453df..95fb6d9e7f91a 100644 --- a/src/java.base/share/native/libjava/java_props.h +++ b/src/java.base/share/native/libjava/java_props.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, 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 @@ -63,8 +63,8 @@ typedef struct { char *display_country; char *format_variant; char *display_variant; - char *encoding; - char *sun_jnu_encoding; + char *encoding; /* always set non-NULL by platform code */ + char *sun_jnu_encoding; /* always set non-NULL by platform code */ char *stdout_encoding; char *stderr_encoding; diff --git a/src/java.base/unix/native/libjava/java_props_md.c b/src/java.base/unix/native/libjava/java_props_md.c index 4a6d0f7f5a4b5..5adfeb0f894ca 100644 --- a/src/java.base/unix/native/libjava/java_props_md.c +++ b/src/java.base/unix/native/libjava/java_props_md.c @@ -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 @@ -27,6 +27,7 @@ #include #include #endif +#include #include #include #ifndef ARCHPROPNAME @@ -463,6 +464,10 @@ GetJavaProperties(JNIEnv *env) #else sprops.sun_jnu_encoding = sprops.encoding; #endif + + assert(sprops.encoding != NULL); + assert(sprops.sun_jnu_encoding != NULL); + if (isatty(STDOUT_FILENO) == 1) { sprops.stdout_encoding = sprops.encoding; } diff --git a/src/java.base/windows/native/libjava/java_props_md.c b/src/java.base/windows/native/libjava/java_props_md.c index f99abdec1066f..8fb1ee838417c 100644 --- a/src/java.base/windows/native/libjava/java_props_md.c +++ b/src/java.base/windows/native/libjava/java_props_md.c @@ -26,6 +26,7 @@ #include "jni.h" #include "jni_util.h" +#include #include #include #include @@ -667,10 +668,15 @@ GetJavaProperties(JNIEnv* env) &sprops.display_variant, &display_encoding); + if (sprops.encoding == NULL) { + sprops.encoding = "UTF-8"; + } + sprops.sun_jnu_encoding = getEncodingInternal(0); if (sprops.sun_jnu_encoding == NULL) { sprops.sun_jnu_encoding = "UTF-8"; } + if (LANGIDFROMLCID(userDefaultLCID) == 0x0c04 && majorVersion == 6) { // MS claims "Vista has built-in support for HKSCS-2004. // All of the HKSCS-2004 characters have Unicode 4.1. @@ -683,6 +689,9 @@ GetJavaProperties(JNIEnv* env) sprops.sun_jnu_encoding = "MS950_HKSCS"; } + assert(sprops.encoding != NULL); + assert(sprops.sun_jnu_encoding != NULL); + hStdOutErr = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdOutErr != INVALID_HANDLE_VALUE && GetFileType(hStdOutErr) == FILE_TYPE_CHAR) {