Skip to content

8351740: Clean up some code around initialization of encoding properties #24463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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