Skip to content
50 changes: 24 additions & 26 deletions src/java.base/share/classes/jdk/internal/util/SystemProps.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -74,20 +74,18 @@ public static Map<String, String> 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
Expand Down Expand Up @@ -209,17 +207,17 @@ private static void fillI18nProps(HashMap<String, String> 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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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<String, String> 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<String, String>((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<String, String> cmdProps = HashMap.newHashMap((vmProps.length / 2) + Raw.FIXED_LENGTH);
for (int i = 0; i < vmProps.length;) {
String k = vmProps[i++];
if (k != null) {
Expand Down
13 changes: 6 additions & 7 deletions src/java.base/share/native/libjava/System.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions src/java.base/share/native/libjava/java_props.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;

Expand Down
7 changes: 6 additions & 1 deletion src/java.base/unix/native/libjava/java_props_md.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -27,6 +27,7 @@
#include <stdio.h>
#include <ctype.h>
#endif
#include <assert.h>
#include <pwd.h>
#include <locale.h>
#ifndef ARCHPROPNAME
Expand Down Expand Up @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions src/java.base/windows/native/libjava/java_props_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "jni.h"
#include "jni_util.h"

#include <assert.h>
#include <windows.h>
#include <shlobj.h>
#include <objidl.h>
Expand Down Expand Up @@ -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.
Expand All @@ -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) {
Expand Down