You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/02/11 15:16:07 UTC

[commons-lang] branch master updated: Refactor system property access into a new SystemProperties class

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 95a0e2b09 Refactor system property access into a new SystemProperties class
95a0e2b09 is described below

commit 95a0e2b09bc4a3a363e5ab1c853d002fb74ad7af
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sat Feb 11 09:49:41 2023 -0500

    Refactor system property access into a new SystemProperties class
---
 .../java/org/apache/commons/lang3/ArchUtils.java   |   2 +-
 .../org/apache/commons/lang3/SystemProperties.java | 791 +++++++++++++++++++++
 .../java/org/apache/commons/lang3/SystemUtils.java | 492 +++++++++----
 .../org/apache/commons/lang3/text/StrLookup.java   |  11 +-
 .../apache/commons/lang3/SystemPropertiesTest.java | 254 +++++++
 .../apache/commons/lang3/text/StrLookupTest.java   |   3 +-
 6 files changed, 1412 insertions(+), 141 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/ArchUtils.java b/src/main/java/org/apache/commons/lang3/ArchUtils.java
index eaa622a6a..0a67d2c49 100644
--- a/src/main/java/org/apache/commons/lang3/ArchUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArchUtils.java
@@ -121,7 +121,7 @@ public class ArchUtils {
      * @return A {@link Processor} when supported, else {@code null}.
      */
     public static Processor getProcessor() {
-        return getProcessor(SystemUtils.OS_ARCH);
+        return getProcessor(SystemProperties.getOsArch());
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/lang3/SystemProperties.java b/src/main/java/org/apache/commons/lang3/SystemProperties.java
new file mode 100644
index 000000000..221c7c973
--- /dev/null
+++ b/src/main/java/org/apache/commons/lang3/SystemProperties.java
@@ -0,0 +1,791 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3;
+
+import java.util.function.Supplier;
+
+/**
+ * Accesses current system property names and values.
+ *
+ * @since 3.13.0
+ */
+public final class SystemProperties {
+
+    private static final Supplier<String> NULL_SUPPLIER = () -> null;
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String AWT_TOOLKIT = "awt.toolkit";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String FILE_ENCODING = "file.encoding";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String FILE_SEPARATOR = "file.separator";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_AWT_FONTS = "java.awt.fonts";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_AWT_GRAPHICSENV = "java.awt.graphicsenv";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_AWT_HEADLESS = "java.awt.headless";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_AWT_PRINTERJOB = "java.awt.printerjob";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_CLASS_PATH = "java.class.path";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_CLASS_VERSION = "java.class.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_COMPILER = "java.compiler";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_ENDORSED_DIRS = "java.endorsed.dirs";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_EXT_DIRS = "java.ext.dirs";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_HOME = "java.home";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_LIBRARY_PATH = "java.library.path";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_RUNTIME_NAME = "java.runtime.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_RUNTIME_VERSION = "java.runtime.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_SPECIFICATION_NAME = "java.specification.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_SPECIFICATION_VENDOR = "java.specification.vendor";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_SPECIFICATION_VERSION = "java.specification.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY = "java.util.prefs.PreferencesFactory";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VENDOR = "java.vendor";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VENDOR_URL = "java.vendor.url";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VERSION = "java.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_INFO = "java.vm.info";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_NAME = "java.vm.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_SPECIFICATION_NAME = "java.vm.specification.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_SPECIFICATION_VENDOR = "java.vm.specification.vendor";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_SPECIFICATION_VERSION = "java.vm.specification.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_VENDOR = "java.vm.vendor";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String JAVA_VM_VERSION = "java.vm.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String LINE_SEPARATOR = "line.separator";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String OS_ARCH = "os.arch";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String OS_NAME = "os.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String OS_VERSION = "os.version";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String PATH_SEPARATOR = "path.separator";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_COUNTRY = "user.country";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_DIR = "user.dir";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_HOME = "user.home";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_LANGUAGE = "user.language";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_NAME = "user.name";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_REGION = "user.region";
+
+    /**
+     * The System property name {@value}.
+     */
+    public static final String USER_TIMEZONE = "user.timezone";
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getAwtToolkit() {
+        return getProperty(AWT_TOOLKIT);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getFileEncoding() {
+        return getProperty(FILE_ENCODING);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getFileSeparator() {
+        return getProperty(FILE_SEPARATOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaAwtFonts() {
+        return getProperty(JAVA_AWT_FONTS);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaAwtGraphicsenv() {
+        return getProperty(JAVA_AWT_GRAPHICSENV);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaAwtHeadless() {
+        return getProperty(JAVA_AWT_HEADLESS);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaAwtPrinterjob() {
+        return getProperty(JAVA_AWT_PRINTERJOB);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaClassPath() {
+        return getProperty(JAVA_CLASS_PATH);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaClassVersion() {
+        return getProperty(JAVA_CLASS_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaCompiler() {
+        return getProperty(JAVA_COMPILER);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaEndorsedDirs() {
+        return getProperty(JAVA_ENDORSED_DIRS);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaExtDirs() {
+        return getProperty(JAVA_EXT_DIRS);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaHome() {
+        return getProperty(JAVA_HOME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaIoTmpdir() {
+        return getProperty(JAVA_IO_TMPDIR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaLibraryPath() {
+        return getProperty(JAVA_LIBRARY_PATH);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaRuntimeName() {
+        return getProperty(JAVA_RUNTIME_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaRuntimeVersion() {
+        return getProperty(JAVA_RUNTIME_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaSpecificationName() {
+        return getProperty(JAVA_SPECIFICATION_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaSpecificationVendor() {
+        return getProperty(JAVA_SPECIFICATION_VENDOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaSpecificationVersion() {
+        return getProperty(JAVA_SPECIFICATION_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaUtilPrefsPreferencesFactory() {
+        return getProperty(JAVA_UTIL_PREFS_PREFERENCES_FACTORY);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVendor() {
+        return getProperty(JAVA_VENDOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVendorUrl() {
+        return getProperty(JAVA_VENDOR_URL);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVersion() {
+        return getProperty(JAVA_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmInfo() {
+        return getProperty(JAVA_VM_INFO);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmName() {
+        return getProperty(JAVA_VM_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmSpecificationName() {
+        return getProperty(JAVA_VM_SPECIFICATION_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmSpecificationVendor() {
+        return getProperty(JAVA_VM_SPECIFICATION_VENDOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmSpecificationVersion() {
+        return getProperty(JAVA_VM_SPECIFICATION_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmVendor() {
+        return getProperty(JAVA_VM_VENDOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getJavaVmVersion() {
+        return getProperty(JAVA_VM_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getLineSeparator() {
+        return getProperty(LINE_SEPARATOR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getOsArch() {
+        return getProperty(OS_ARCH);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getOsName() {
+        return getProperty(OS_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getOsVersion() {
+        return getProperty(OS_VERSION);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getPathSeparator() {
+        return getProperty(PATH_SEPARATOR);
+    }
+
+    /**
+     * Gets a System property, defaulting to {@code null} if the property cannot be read.
+     * <p>
+     * If a {@link SecurityException} is caught, the return value is {@code null}.
+     * </p>
+     *
+     * @param property the system property name
+     * @return the system property value or {@code null} if a security problem occurs
+     */
+    public static String getProperty(final String property) {
+        return getProperty(property, NULL_SUPPLIER);
+    }
+
+    /**
+     * Gets a System property, defaulting to {@code null} if the property cannot be read.
+     * <p>
+     * If a {@link SecurityException} is caught, the return value is {@code null}.
+     * </p>
+     *
+     * @param property        the system property name.
+     * @param defaultValue get this Supplier when the property is empty or throws SecurityException.
+     * @return the system property value or {@code null} if a security problem occurs
+     */
+    static String getProperty(final String property, final Supplier<String> defaultValue) {
+        try {
+            if (StringUtils.isEmpty(property)) {
+                return defaultValue.get();
+            }
+            final String value = System.getProperty(property);
+            return StringUtils.getIfEmpty(value, defaultValue);
+        } catch (final SecurityException ignore) {
+            // We are not allowed to look at this property.
+            //
+            // System.err.println("Caught a SecurityException reading the system property '" + property
+            // + "'; the SystemUtils property value will default to null.");
+            return defaultValue.get();
+        }
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserCountry() {
+        return getProperty(USER_COUNTRY);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserDir() {
+        return getProperty(USER_DIR);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserHome() {
+        return getProperty(USER_HOME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserLanguage() {
+        return getProperty(USER_LANGUAGE);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserName() {
+        return getProperty(USER_NAME);
+    }
+
+    /**
+     * Gets the current value from the system properties map.
+     * <p>
+     * Returns {@code null} if the property cannot be read due to a {@link SecurityException}.
+     * </p>
+     *
+     * @return the current value from the system properties map.
+     */
+    public static String getUserTimezone() {
+        return getProperty(USER_TIMEZONE);
+    }
+}
diff --git a/src/main/java/org/apache/commons/lang3/SystemUtils.java b/src/main/java/org/apache/commons/lang3/SystemUtils.java
index 95c6279de..85a2bb443 100644
--- a/src/main/java/org/apache/commons/lang3/SystemUtils.java
+++ b/src/main/java/org/apache/commons/lang3/SystemUtils.java
@@ -30,6 +30,7 @@ import java.io.File;
  * </p>
  *
  * @since 1.0
+ * @see SystemProperties
  */
 public class SystemUtils {
 
@@ -42,54 +43,6 @@ public class SystemUtils {
     // -----------------------------------------------------------------------
     // These MUST be declared first. Other constants depend on this.
 
-    /**
-     * The System property key for the user home directory.
-     */
-    private static final String USER_HOME_KEY = "user.home";
-
-    /**
-     * The System property key for the user name.
-     */
-    private static final String USER_NAME_KEY = "user.name";
-
-    /**
-     * The System property key for the user directory.
-     */
-    private static final String USER_DIR_KEY = "user.dir";
-
-    /**
-     * The System property key for the Java IO temporary directory.
-     */
-    private static final String JAVA_IO_TMPDIR_KEY = "java.io.tmpdir";
-
-    /**
-     * The System property key for the Java home directory.
-     */
-    private static final String JAVA_HOME_KEY = "java.home";
-
-    /**
-     * The {@code awt.toolkit} System Property.
-     *
-     * <p>
-     * Holds a class name, on Windows XP this is {@code sun.awt.windows.WToolkit}.
-     * </p>
-     * <p>
-     * <b>On platforms without a GUI, this value is {@code null}.</b>
-     * </p>
-     * <p>
-     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
-     * not exist.
-     * </p>
-     * <p>
-     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
-     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
-     * sync with that System property.
-     * </p>
-     *
-     * @since 2.1
-     */
-    public static final String AWT_TOOLKIT = getSystemProperty("awt.toolkit");
-
     /**
      * The {@code file.encoding} System Property.
      *
@@ -106,10 +59,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getFileEncoding()
      * @since 2.0
      * @since Java 1.2
      */
-    public static final String FILE_ENCODING = getSystemProperty("file.encoding");
+    public static final String FILE_ENCODING = SystemProperties.getFileEncoding();
 
     /**
      * The {@code file.separator} System Property.
@@ -130,12 +84,13 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getFileSeparator()
      * @deprecated Use {@link File#separator}, since it is guaranteed to be a
      *             string containing a single character and it does not require a privilege check.
      * @since Java 1.1
      */
     @Deprecated
-    public static final String FILE_SEPARATOR = getSystemProperty("file.separator");
+    public static final String FILE_SEPARATOR = SystemProperties.getFileSeparator();
 
     /**
      * The {@code java.awt.fonts} System Property.
@@ -150,9 +105,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaAwtFonts()
      * @since 2.1
      */
-    public static final String JAVA_AWT_FONTS = getSystemProperty("java.awt.fonts");
+    public static final String JAVA_AWT_FONTS = SystemProperties.getJavaAwtFonts();
 
     /**
      * The {@code java.awt.graphicsenv} System Property.
@@ -167,9 +123,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaAwtGraphicsenv()
      * @since 2.1
      */
-    public static final String JAVA_AWT_GRAPHICSENV = getSystemProperty("java.awt.graphicsenv");
+    public static final String JAVA_AWT_GRAPHICSENV = SystemProperties.getJavaAwtGraphicsenv();
 
     /**
      * The {@code java.awt.headless} System Property. The value of this property is the String {@code "true"} or
@@ -186,10 +143,11 @@ public class SystemUtils {
      * </p>
      *
      * @see #isJavaAwtHeadless()
+     * @see SystemProperties#getJavaAwtHeadless()
      * @since 2.1
      * @since Java 1.4
      */
-    public static final String JAVA_AWT_HEADLESS = getSystemProperty("java.awt.headless");
+    public static final String JAVA_AWT_HEADLESS = SystemProperties.getJavaAwtHeadless();
 
     /**
      * The {@code java.awt.printerjob} System Property.
@@ -204,9 +162,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaAwtPrinterjob()
      * @since 2.1
      */
-    public static final String JAVA_AWT_PRINTERJOB = getSystemProperty("java.awt.printerjob");
+    public static final String JAVA_AWT_PRINTERJOB = SystemProperties.getJavaAwtPrinterjob();
 
     /**
      * The {@code java.class.path} System Property. Java class path.
@@ -221,9 +180,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaClassPath()
      * @since Java 1.1
      */
-    public static final String JAVA_CLASS_PATH = getSystemProperty("java.class.path");
+    public static final String JAVA_CLASS_PATH = SystemProperties.getJavaClassPath();
 
     /**
      * The {@code java.class.version} System Property. Java class format version number.
@@ -238,9 +198,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaClassVersion()
      * @since Java 1.1
      */
-    public static final String JAVA_CLASS_VERSION = getSystemProperty("java.class.version");
+    public static final String JAVA_CLASS_VERSION = SystemProperties.getJavaClassVersion();
 
     /**
      * The {@code java.compiler} System Property. Name of JIT compiler to use. First in JDK version 1.2. Not used in Sun
@@ -256,9 +217,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaCompiler()
      * @since Java 1.2. Not used in Sun versions after 1.2.
      */
-    public static final String JAVA_COMPILER = getSystemProperty("java.compiler");
+    public static final String JAVA_COMPILER = SystemProperties.getJavaCompiler();
 
     /**
      * The {@code java.endorsed.dirs} System Property. Path of endorsed directory or directories.
@@ -273,9 +235,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaEndorsedDirs()
      * @since Java 1.4
      */
-    public static final String JAVA_ENDORSED_DIRS = getSystemProperty("java.endorsed.dirs");
+    public static final String JAVA_ENDORSED_DIRS = SystemProperties.getJavaEndorsedDirs();
 
     /**
      * The {@code java.ext.dirs} System Property. Path of extension directory or directories.
@@ -290,9 +253,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaExtDirs()
      * @since Java 1.3
      */
-    public static final String JAVA_EXT_DIRS = getSystemProperty("java.ext.dirs");
+    public static final String JAVA_EXT_DIRS = SystemProperties.getJavaExtDirs();
 
     /**
      * The {@code java.home} System Property. Java installation directory.
@@ -307,9 +271,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaHome()
      * @since Java 1.1
      */
-    public static final String JAVA_HOME = getSystemProperty(JAVA_HOME_KEY);
+    public static final String JAVA_HOME = SystemProperties.getJavaHome();
 
     /**
      * The {@code java.io.tmpdir} System Property. Default temp file path.
@@ -324,9 +289,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaIoTmpdir()
      * @since Java 1.2
      */
-    public static final String JAVA_IO_TMPDIR = getSystemProperty(JAVA_IO_TMPDIR_KEY);
+    public static final String JAVA_IO_TMPDIR = SystemProperties.getJavaIoTmpdir();
 
     /**
      * The {@code java.library.path} System Property. List of paths to search when loading libraries.
@@ -341,9 +307,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaLibraryPath()
      * @since Java 1.2
      */
-    public static final String JAVA_LIBRARY_PATH = getSystemProperty("java.library.path");
+    public static final String JAVA_LIBRARY_PATH = SystemProperties.getJavaLibraryPath();
 
     /**
      * The {@code java.runtime.name} System Property. Java Runtime Environment name.
@@ -358,10 +325,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaRuntimeName()
      * @since 2.0
      * @since Java 1.3
      */
-    public static final String JAVA_RUNTIME_NAME = getSystemProperty("java.runtime.name");
+    public static final String JAVA_RUNTIME_NAME = SystemProperties.getJavaRuntimeName();
 
     /**
      * The {@code java.runtime.version} System Property. Java Runtime Environment version.
@@ -376,10 +344,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaRuntimeVersion()
      * @since 2.0
      * @since Java 1.3
      */
-    public static final String JAVA_RUNTIME_VERSION = getSystemProperty("java.runtime.version");
+    public static final String JAVA_RUNTIME_VERSION = SystemProperties.getJavaRuntimeVersion();
 
     /**
      * The {@code java.specification.name} System Property. Java Runtime Environment specification name.
@@ -394,9 +363,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaSpecificationName()
      * @since Java 1.2
      */
-    public static final String JAVA_SPECIFICATION_NAME = getSystemProperty("java.specification.name");
+    public static final String JAVA_SPECIFICATION_NAME = SystemProperties.getJavaSpecificationName();
 
     /**
      * The {@code java.specification.vendor} System Property. Java Runtime Environment specification vendor.
@@ -411,9 +381,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaSpecificationVendor()
      * @since Java 1.2
      */
-    public static final String JAVA_SPECIFICATION_VENDOR = getSystemProperty("java.specification.vendor");
+    public static final String JAVA_SPECIFICATION_VENDOR = SystemProperties.getJavaSpecificationVendor();
 
     /**
      * The {@code java.specification.version} System Property. Java Runtime Environment specification version.
@@ -428,9 +399,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaSpecificationVersion()
      * @since Java 1.3
      */
-    public static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version");
+    public static final String JAVA_SPECIFICATION_VERSION = SystemProperties.getJavaSpecificationVersion();
+
     private static final JavaVersion JAVA_SPECIFICATION_VERSION_AS_ENUM = JavaVersion.get(JAVA_SPECIFICATION_VERSION);
 
     /**
@@ -446,11 +419,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaUtilPrefsPreferencesFactory()
      * @since 2.1
      * @since Java 1.4
      */
-    public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY =
-        getSystemProperty("java.util.prefs.PreferencesFactory");
+    public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY = SystemProperties.getJavaUtilPrefsPreferencesFactory();
 
     /**
      * The {@code java.vendor} System Property. Java vendor-specific string.
@@ -465,9 +438,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVersion()
      * @since Java 1.1
      */
-    public static final String JAVA_VENDOR = getSystemProperty("java.vendor");
+    public static final String JAVA_VENDOR = SystemProperties.getJavaVersion();
 
     /**
      * The {@code java.vendor.url} System Property. Java vendor URL.
@@ -482,9 +456,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVendorUrl()
      * @since Java 1.1
      */
-    public static final String JAVA_VENDOR_URL = getSystemProperty("java.vendor.url");
+    public static final String JAVA_VENDOR_URL = SystemProperties.getJavaVendorUrl();
 
     /**
      * The {@code java.version} System Property. Java version number.
@@ -499,9 +474,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVersion()
      * @since Java 1.1
      */
-    public static final String JAVA_VERSION = getSystemProperty("java.version");
+    public static final String JAVA_VERSION = SystemProperties.getJavaVersion();
 
     /**
      * The {@code java.vm.info} System Property. Java Virtual Machine implementation info.
@@ -516,10 +492,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmInfo()
      * @since 2.0
      * @since Java 1.2
      */
-    public static final String JAVA_VM_INFO = getSystemProperty("java.vm.info");
+    public static final String JAVA_VM_INFO = SystemProperties.getJavaVmInfo();
 
     /**
      * The {@code java.vm.name} System Property. Java Virtual Machine implementation name.
@@ -534,9 +511,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmName()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_NAME = getSystemProperty("java.vm.name");
+    public static final String JAVA_VM_NAME = SystemProperties.getJavaVmName();
 
     /**
      * The {@code java.vm.specification.name} System Property. Java Virtual Machine specification name.
@@ -551,9 +529,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmSpecificationName()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_SPECIFICATION_NAME = getSystemProperty("java.vm.specification.name");
+    public static final String JAVA_VM_SPECIFICATION_NAME = SystemProperties.getJavaVmSpecificationName();
 
     /**
      * The {@code java.vm.specification.vendor} System Property. Java Virtual Machine specification vendor.
@@ -568,9 +547,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmSpecificationVendor()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_SPECIFICATION_VENDOR = getSystemProperty("java.vm.specification.vendor");
+    public static final String JAVA_VM_SPECIFICATION_VENDOR = SystemProperties.getJavaVmSpecificationVendor();
 
     /**
      * The {@code java.vm.specification.version} System Property. Java Virtual Machine specification version.
@@ -585,9 +565,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmSpecificationVersion()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_SPECIFICATION_VERSION = getSystemProperty("java.vm.specification.version");
+    public static final String JAVA_VM_SPECIFICATION_VERSION = SystemProperties.getJavaVmSpecificationVersion();
 
     /**
      * The {@code java.vm.vendor} System Property. Java Virtual Machine implementation vendor.
@@ -602,9 +583,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmVendor()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_VENDOR = getSystemProperty("java.vm.vendor");
+    public static final String JAVA_VM_VENDOR = SystemProperties.getJavaVmVendor();
 
     /**
      * The {@code java.vm.version} System Property. Java Virtual Machine implementation version.
@@ -619,9 +601,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getJavaVmVersion()
      * @since Java 1.2
      */
-    public static final String JAVA_VM_VERSION = getSystemProperty("java.vm.version");
+    public static final String JAVA_VM_VERSION = SystemProperties.getJavaVmVersion();
 
     /**
      * The {@code line.separator} System Property. Line separator ({@code &quot;\n&quot;} on UNIX).
@@ -636,11 +619,12 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getLineSeparator()
      * @deprecated Use {@link System#lineSeparator()} instead, since it does not require a privilege check.
      * @since Java 1.1
      */
     @Deprecated
-    public static final String LINE_SEPARATOR = getSystemProperty("line.separator");
+    public static final String LINE_SEPARATOR = SystemProperties.getLineSeparator();
 
     /**
      * The {@code os.arch} System Property. Operating system architecture.
@@ -655,9 +639,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getOsArch()
      * @since Java 1.1
      */
-    public static final String OS_ARCH = getSystemProperty("os.arch");
+    public static final String OS_ARCH = SystemProperties.getOsArch();
 
     /**
      * The {@code os.name} System Property. Operating system name.
@@ -672,9 +657,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getOsName()
      * @since Java 1.1
      */
-    public static final String OS_NAME = getSystemProperty("os.name");
+    public static final String OS_NAME = SystemProperties.getOsName();
 
     /**
      * The {@code os.version} System Property. Operating system version.
@@ -689,9 +675,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getOsVersion()
      * @since Java 1.1
      */
-    public static final String OS_VERSION = getSystemProperty("os.version");
+    public static final String OS_VERSION = SystemProperties.getOsVersion();
 
     /**
      * The {@code path.separator} System Property. Path separator ({@code &quot;:&quot;} on UNIX).
@@ -706,12 +693,13 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getPathSeparator()
      * @deprecated Use {@link File#pathSeparator}, since it is guaranteed to be a
      *             string containing a single character and it does not require a privilege check.
      * @since Java 1.1
      */
     @Deprecated
-    public static final String PATH_SEPARATOR = getSystemProperty("path.separator");
+    public static final String PATH_SEPARATOR = SystemProperties.getPathSeparator();
 
     /**
      * The {@code user.country} or {@code user.region} System Property. User's country code, such as {@code "GB"}. First
@@ -730,8 +718,8 @@ public class SystemUtils {
      * @since 2.0
      * @since Java 1.2
      */
-    public static final String USER_COUNTRY = getSystemProperty("user.country") == null ?
-            getSystemProperty("user.region") : getSystemProperty("user.country");
+    public static final String USER_COUNTRY = SystemProperties.getProperty(SystemProperties.USER_COUNTRY,
+            () -> SystemProperties.getProperty(SystemProperties.USER_REGION));
 
     /**
      * The {@code user.dir} System Property. User's current working directory.
@@ -746,9 +734,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getUserDir()
      * @since Java 1.1
      */
-    public static final String USER_DIR = getSystemProperty(USER_DIR_KEY);
+    public static final String USER_DIR = SystemProperties.getUserDir();
 
     /**
      * The {@code user.home} System Property. User's home directory.
@@ -763,9 +752,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getUserHome()
      * @since Java 1.1
      */
-    public static final String USER_HOME = getSystemProperty(USER_HOME_KEY);
+    public static final String USER_HOME = SystemProperties.getUserHome();
 
     /**
      * The {@code user.language} System Property. User's language code, such as {@code "en"}.
@@ -780,10 +770,11 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getUserLanguage()
      * @since 2.0
      * @since Java 1.2
      */
-    public static final String USER_LANGUAGE = getSystemProperty("user.language");
+    public static final String USER_LANGUAGE = SystemProperties.getUserLanguage();
 
     /**
      * The {@code user.name} System Property. User's account name.
@@ -798,9 +789,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getUserName()
      * @since Java 1.1
      */
-    public static final String USER_NAME = getSystemProperty(USER_NAME_KEY);
+    public static final String USER_NAME = SystemProperties.getUserName();
 
     /**
      * The {@code user.timezone} System Property. For example: {@code "America/Los_Angeles"}.
@@ -815,9 +807,10 @@ public class SystemUtils {
      * sync with that System property.
      * </p>
      *
+     * @see SystemProperties#getUserTimezone()
      * @since 2.1
      */
-    public static final String USER_TIMEZONE = getSystemProperty("user.timezone");
+    public static final String USER_TIMEZONE = SystemProperties.getUserTimezone();
 
     // Java version checks
     // -----------------------------------------------------------------------
@@ -830,6 +823,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_1 = getJavaVersionMatches("1.1");
 
@@ -839,6 +835,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_2 = getJavaVersionMatches("1.2");
 
@@ -848,6 +847,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_3 = getJavaVersionMatches("1.3");
 
@@ -857,6 +859,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_4 = getJavaVersionMatches("1.4");
 
@@ -866,6 +871,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_5 = getJavaVersionMatches("1.5");
 
@@ -875,6 +883,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      */
     public static final boolean IS_JAVA_1_6 = getJavaVersionMatches("1.6");
 
@@ -884,6 +895,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.0
      */
@@ -895,6 +909,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.3.2
      */
@@ -906,6 +923,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      *
@@ -920,6 +940,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.5
      */
@@ -931,6 +954,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.7
      */
@@ -942,6 +968,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.8
      */
@@ -953,6 +982,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.9
      */
@@ -964,6 +996,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.9
      */
@@ -975,6 +1010,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.10
      */
@@ -986,6 +1024,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.10
      */
@@ -996,6 +1037,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.13.0
      */
@@ -1006,6 +1050,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.13.0
      */
@@ -1016,6 +1063,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.13.0
      */
@@ -1034,6 +1084,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1045,6 +1098,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1056,6 +1112,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.3
      */
@@ -1067,6 +1126,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1078,6 +1140,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1089,6 +1154,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1100,6 +1168,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1111,6 +1182,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1122,6 +1196,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1133,6 +1210,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1144,6 +1224,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1155,6 +1238,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1166,6 +1252,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1177,6 +1266,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1188,6 +1280,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1199,6 +1294,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1210,6 +1308,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1221,6 +1322,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1232,6 +1336,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.5
      */
@@ -1243,6 +1350,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.12.0
      */
@@ -1254,6 +1364,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.12.0
      */
@@ -1265,6 +1378,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.12.0
      */
@@ -1276,6 +1392,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.12.0
      */
@@ -1287,6 +1406,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.12.0
      */
@@ -1298,6 +1420,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.1
      */
@@ -1309,6 +1434,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.1
      */
@@ -1320,6 +1448,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.1
      */
@@ -1331,6 +1462,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1342,6 +1476,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1353,6 +1490,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1364,6 +1504,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.1
      */
@@ -1376,6 +1519,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1387,6 +1533,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1398,6 +1547,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.1
      */
@@ -1409,6 +1561,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.1
      */
@@ -1420,6 +1575,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.4
      */
@@ -1431,6 +1589,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1442,6 +1603,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1453,6 +1617,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1464,6 +1631,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1475,6 +1645,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.0
      */
@@ -1486,6 +1659,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 2.4
      */
@@ -1497,6 +1673,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.0
      */
@@ -1508,6 +1687,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.2
      */
@@ -1519,6 +1701,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.5
      */
@@ -1537,6 +1722,9 @@ public class SystemUtils {
      * <li>Affects Java versions 7u321, 8u311, 11.0.13-oracle, 17.0.1: https://bugs.openjdk.org/browse/JDK-8274737</li>
      * <li>Fixed in OpenJDK commit https://github.com/openjdk/jdk/commit/97ea9dd2f24f9f1fb9b9345a4202a825ee28e014</li>
      * </ul>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.13.0
      */
@@ -1548,6 +1736,9 @@ public class SystemUtils {
      * <p>
      * The field will return {@code false} if {@code OS_NAME} is {@code null}.
      * </p>
+     * <p>
+     * This value is initialized when the class is loaded.
+     * </p>
      *
      * @since 3.5
      */
@@ -1558,6 +1749,67 @@ public class SystemUtils {
     // os.version = 02.02.00
     public static final boolean IS_OS_ZOS = getOsMatchesName("z/OS");
 
+    /**
+     * The System property key for the user home directory.
+     */
+    public static final String USER_HOME_KEY = "user.home";
+
+    /**
+     * The System property key for the user name.
+     *
+     * @deprecated Use {@link SystemProperties#USER_NAME}.
+     */
+    @Deprecated
+    public static final String USER_NAME_KEY = "user.name";
+
+    /**
+     * The System property key for the user directory.
+     *
+     * @deprecated Use {@link SystemProperties#USER_DIR}.
+     */
+    @Deprecated
+    public static final String USER_DIR_KEY = "user.dir";
+
+    /**
+     * The System property key for the Java IO temporary directory.
+     *
+     * @deprecated Use {@link SystemProperties#JAVA_IO_TMPDIR}.
+     */
+    @Deprecated
+    public static final String JAVA_IO_TMPDIR_KEY = "java.io.tmpdir";
+
+    /**
+     * The System property key for the Java home directory.
+     *
+     * @deprecated Use {@link SystemProperties#JAVA_HOME}.
+     */
+    @Deprecated
+    public static final String JAVA_HOME_KEY = "java.home";
+
+    /**
+     * The {@code awt.toolkit} System Property.
+     *
+     * <p>
+     * Holds a class name, on Windows XP this is {@code sun.awt.windows.WToolkit}.
+     * </p>
+     * <p>
+     * <b>On platforms without a GUI, this value is {@code null}.</b>
+     * </p>
+     * <p>
+     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
+     * not exist.
+     * </p>
+     * <p>
+     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
+     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
+     * sync with that System property.
+     * </p>
+     *
+     * @since 2.1
+     * @see SystemProperties#getAwtToolkit()
+     */
+    public static final String AWT_TOOLKIT = SystemProperties.getAwtToolkit();
+
     /**
      * Gets an environment variable, defaulting to {@code defaultValue} if the variable cannot be read.
      *
@@ -1600,29 +1852,29 @@ public class SystemUtils {
     }
 
     /**
-     * Gets the Java home directory as a {@link File}.
+     * Gets the current Java home directory as a {@link File}.
      *
      * @return a directory
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getJavaHome()
      * @since 2.1
      */
     public static File getJavaHome() {
-        return new File(System.getProperty(JAVA_HOME_KEY));
+        return new File(SystemProperties.getJavaHome());
     }
 
     /**
-     * Gets the Java IO temporary directory as a {@link File}.
+     * Gets the current Java IO temporary directory as a {@link File}.
      *
      * @return a directory
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getJavaIoTmpdir()
      * @since 2.1
      */
     public static File getJavaIoTmpDir() {
-        return new File(System.getProperty(JAVA_IO_TMPDIR_KEY));
+        return new File(SystemProperties.getJavaIoTmpdir());
     }
 
     /**
@@ -1657,64 +1909,44 @@ public class SystemUtils {
     }
 
     /**
-     * Gets a System property, defaulting to {@code null} if the property cannot be read.
-     *
-     * <p>
-     * If a {@link SecurityException} is caught, the return value is {@code null} and a message is written to
-     * {@code System.err}.
-     * </p>
-     *
-     * @param property the system property name
-     * @return the system property value or {@code null} if a security problem occurs
-     */
-    private static String getSystemProperty(final String property) {
-        try {
-            return System.getProperty(property);
-        } catch (final SecurityException ex) {
-            // we are not allowed to look at this property
-            // System.err.println("Caught a SecurityException reading the system property '" + property
-            // + "'; the SystemUtils property value will default to null.");
-            return null;
-        }
-    }
-
-    /**
-     * Gets the user directory as a {@link File}.
+     * Gets the current user directory as a {@link File}.
      *
      * @return a directory
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getUserDir()
      * @since 2.1
      */
     public static File getUserDir() {
-        return new File(System.getProperty(USER_DIR_KEY));
+        return new File(SystemProperties.getUserDir());
     }
 
     /**
-     * Gets the user home directory as a {@link File}.
+     * Gets the current user home directory as a {@link File}.
      *
      * @return a directory
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getUserHome()
      * @since 2.1
      */
     public static File getUserHome() {
-        return new File(System.getProperty(USER_HOME_KEY));
+        return new File(SystemProperties.getUserHome());
     }
 
     /**
-     * Gets the user name.
+     * Gets the current user name.
      *
      * @return a name
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getUserName()
      * @since 3.10
+     * @deprecated Use {@link SystemProperties#getUserName()}.
      */
+    @Deprecated
     public static String getUserName() {
-        return System.getProperty(USER_NAME_KEY);
+        return SystemProperties.getUserName();
     }
 
     /**
@@ -1724,11 +1956,11 @@ public class SystemUtils {
      * @return a name
      * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
      * access to the specified system property.
-     * @see System#getProperty(String)
+     * @see SystemProperties#getUserName()
      * @since 3.10
      */
     public static String getUserName(final String defaultValue) {
-        return System.getProperty(USER_NAME_KEY, defaultValue);
+        return System.getProperty(SystemProperties.USER_NAME, defaultValue);
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/lang3/text/StrLookup.java b/src/main/java/org/apache/commons/lang3/text/StrLookup.java
index 11410a715..52ef035e1 100644
--- a/src/main/java/org/apache/commons/lang3/text/StrLookup.java
+++ b/src/main/java/org/apache/commons/lang3/text/StrLookup.java
@@ -18,6 +18,8 @@ package org.apache.commons.lang3.text;
 
 import java.util.Map;
 
+import org.apache.commons.lang3.SystemProperties;
+
 /**
  * Lookup a String key to a String value.
  * <p>
@@ -179,14 +181,7 @@ public abstract class StrLookup<V> {
          */
         @Override
         public String lookup(final String key) {
-            if (!key.isEmpty()) {
-                try {
-                    return System.getProperty(key);
-                } catch (final SecurityException ignored) {
-                    // ignored, all lookup(String) will return null.
-                }
-            }
-            return null;
+            return SystemProperties.getProperty(key);
         }
     }
 }
diff --git a/src/test/java/org/apache/commons/lang3/SystemPropertiesTest.java b/src/test/java/org/apache/commons/lang3/SystemPropertiesTest.java
new file mode 100644
index 000000000..0e9c99c65
--- /dev/null
+++ b/src/test/java/org/apache/commons/lang3/SystemPropertiesTest.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import org.junit.jupiter.api.Test;
+
+public class SystemPropertiesTest {
+
+    private boolean isJava11OrGreater() {
+        return SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_11);
+    }
+
+    @Test
+    public void testGetAwtToolkit() {
+        assertDoesNotThrow(SystemProperties::getAwtToolkit);
+    }
+
+    @Test
+    public void testGetFileEncoding() {
+        assertNotNull(SystemProperties.getFileEncoding());
+    }
+
+    @Test
+    public void testGetFileSeparator() {
+        assertNotNull(SystemProperties.getFileSeparator());
+    }
+
+    @Test
+    public void testGetJavaAwtFonts() {
+        assertNull(SystemProperties.getJavaAwtFonts());
+    }
+
+    @Test
+    public void testGetJavaAwtGraphicsenv() {
+        assertDoesNotThrow(SystemProperties::getJavaAwtGraphicsenv);
+    }
+
+    @Test
+    public void testGetJavaAwtHeadless() {
+        assertNull(SystemProperties.getJavaAwtHeadless());
+    }
+
+    @Test
+    public void testGetJavaAwtPrinterjob() {
+        assertDoesNotThrow(SystemProperties::getJavaAwtPrinterjob);
+    }
+
+    @Test
+    public void testGetJavaClassPath() {
+        assertNotNull(SystemProperties.getJavaClassPath());
+    }
+
+    @Test
+    public void testGetJavaClassVersion() {
+        assertNotNull(SystemProperties.getJavaClassVersion());
+    }
+
+    @Test
+    public void testGetJavaCompiler() {
+        if (SystemUtils.IS_JAVA_14) {
+            // Not in Java 11
+            assertNotNull(SystemProperties.getJavaCompiler());
+        }
+    }
+
+    @Test
+    public void testGetJavaEndorsedDirs() {
+        if (isJava11OrGreater()) {
+            // Not in Java 11
+            assertNull(SystemProperties.getJavaEndorsedDirs());
+        } else {
+            assertNotNull(SystemProperties.getJavaExtDirs());
+        }
+    }
+
+    @Test
+    public void testGetJavaExtDirs() {
+        if (isJava11OrGreater()) {
+            // Not in Java 11
+            assertNull(SystemProperties.getJavaExtDirs());
+        } else {
+            assertNotNull(SystemProperties.getJavaExtDirs());
+        }
+    }
+
+    @Test
+    public void testGetJavaHome() {
+        assertNotNull(SystemProperties.getJavaHome());
+    }
+
+    @Test
+    public void testGetJavaIoTmpdir() {
+        assertNotNull(SystemProperties.getJavaIoTmpdir());
+    }
+
+    @Test
+    public void testGetJavaLibraryPath() {
+        assertNotNull(SystemProperties.getJavaLibraryPath());
+    }
+
+    @Test
+    public void testGetJavaRuntimeName() {
+        assertNotNull(SystemProperties.getJavaRuntimeName());
+    }
+
+    @Test
+    public void testGetJavaRuntimeVersion() {
+        assertNotNull(SystemProperties.getJavaRuntimeVersion());
+    }
+
+    @Test
+    public void testGetJavaSpecificationName() {
+        assertNotNull(SystemProperties.getJavaSpecificationName());
+    }
+
+    @Test
+    public void testGetJavaSpecificationVendor() {
+        assertNotNull(SystemProperties.getJavaSpecificationVendor());
+    }
+
+    @Test
+    public void testGetJavaSpecificationVersion() {
+        assertNotNull(SystemProperties.getJavaSpecificationVersion());
+    }
+
+    @Test
+    public void testGetJavaUtilPrefsPreferencesFactory() {
+        assertNull(SystemProperties.getJavaUtilPrefsPreferencesFactory());
+    }
+
+    @Test
+    public void testGetJavaVendor() {
+        assertNotNull(SystemProperties.getJavaVendor());
+    }
+
+    @Test
+    public void testGetJavaVendorUrl() {
+        assertNotNull(SystemProperties.getJavaVendorUrl());
+    }
+
+    @Test
+    public void testGetJavaVersion() {
+        assertNotNull(SystemProperties.getJavaVersion());
+    }
+
+    @Test
+    public void testGetJavaVmInfo() {
+        assertNotNull(SystemProperties.getJavaVmInfo());
+    }
+
+    @Test
+    public void testGetJavaVmName() {
+        assertNotNull(SystemProperties.getJavaVmName());
+    }
+
+    @Test
+    public void testGetJavaVmSpecificationName() {
+        assertNotNull(SystemProperties.getJavaVmSpecificationName());
+    }
+
+    @Test
+    public void testGetJavaVmSpecificationVendor() {
+        assertNotNull(SystemProperties.getJavaVmSpecificationVendor());
+    }
+
+    @Test
+    public void testGetJavaVmSpecificationVersion() {
+        assertNotNull(SystemProperties.getJavaVmSpecificationVersion());
+    }
+
+    @Test
+    public void testGetJavaVmVendor() {
+        assertNotNull(SystemProperties.getJavaVmVendor());
+    }
+
+    @Test
+    public void testGetJavaVmVersion() {
+        assertNotNull(SystemProperties.getJavaVmVersion());
+    }
+
+    @Test
+    public void testGetLineSeparator() {
+        assertNotNull(SystemProperties.getLineSeparator());
+    }
+
+    @Test
+    public void testGetOsArch() {
+        assertNotNull(SystemProperties.getOsArch());
+    }
+
+    @Test
+    public void testGetOsName() {
+        assertNotNull(SystemProperties.getOsName());
+    }
+
+    @Test
+    public void testGetOsVersion() {
+        assertNotNull(SystemProperties.getOsVersion());
+    }
+
+    @Test
+    public void testGetPathSeparator() {
+        assertNotNull(SystemProperties.getPathSeparator());
+    }
+
+    @Test
+    public void testGetUserCountry() {
+        assertNotNull(SystemProperties.getUserCountry());
+    }
+
+    @Test
+    public void testGetUserDir() {
+        assertNotNull(SystemProperties.getUserDir());
+    }
+
+    @Test
+    public void testGetUserHome() {
+        assertNotNull(SystemProperties.getUserHome());
+    }
+
+    @Test
+    public void testGetUserLanguage() {
+        assertNotNull(SystemProperties.getUserLanguage());
+    }
+
+    @Test
+    public void testGetUserName() {
+        assertNotNull(SystemProperties.getUserName());
+    }
+
+    @Test
+    public void testGetUserTimezone() {
+        assertDoesNotThrow(SystemProperties::getUserTimezone);
+    }
+
+}
diff --git a/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java b/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java
index 43a2f8c71..acc42dac9 100644
--- a/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java
+++ b/src/test/java/org/apache/commons/lang3/text/StrLookupTest.java
@@ -19,7 +19,6 @@ package org.apache.commons.lang3.text;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -46,7 +45,7 @@ public class StrLookupTest extends AbstractLangTest {
         assertEquals(System.getProperty("os.name"), StrLookup.systemPropertiesLookup().lookup("os.name"));
         assertNull(StrLookup.systemPropertiesLookup().lookup(""));
         assertNull(StrLookup.systemPropertiesLookup().lookup("other"));
-        assertThrows(NullPointerException.class, () -> StrLookup.systemPropertiesLookup().lookup(null));
+        assertNull(StrLookup.systemPropertiesLookup().lookup(null));
     }
 
     /**