diff --git a/make/modules/java.xml/Copy.gmk b/make/modules/java.xml/Copy.gmk
index 3b6c66e42c5ed..9d24486a4fe34 100644
--- a/make/modules/java.xml/Copy.gmk
+++ b/make/modules/java.xml/Copy.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -24,14 +24,18 @@
#
include CopyCommon.gmk
+include Modules.gmk
################################################################################
+#
+# Copy property files from share/conf to CONF_DST_DIR LIB_DST_DIR
+#
+JAXPPROPFILE_SRC_DIR := $(TOPDIR)/src/java.xml/share/conf
+JAXPPROPFILE_SRCS := $(wildcard $(JAXPPROPFILE_SRC_DIR)/jaxp*.properties*)
+JAXPPROPFILE_TARGET_FILES := $(subst $(JAXPPROPFILE_SRC_DIR),$(CONF_DST_DIR),$(JAXPPROPFILE_SRCS))
-XML_LIB_SRC := $(TOPDIR)/src/java.xml/share/conf
-
-$(CONF_DST_DIR)/jaxp.properties: $(XML_LIB_SRC)/jaxp.properties
+$(CONF_DST_DIR)/%: $(JAXPPROPFILE_SRC_DIR)/%
$(call install-file)
-TARGETS := $(CONF_DST_DIR)/jaxp.properties
-
+TARGETS += $(JAXPPROPFILE_TARGET_FILES)
################################################################################
diff --git a/src/java.xml/share/classes/module-info.java b/src/java.xml/share/classes/module-info.java
index 78ae956151906..febd31cba535f 100644
--- a/src/java.xml/share/classes/module-info.java
+++ b/src/java.xml/share/classes/module-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -402,6 +402,14 @@
* @implNote
*
*
*
+ * JAXP Configuration Files
+ * The JDK provides three JAXP Configuration Files:
+ *
+ *
+ * - {@code jaxp.properties}:
+ * the default configuration that the JDK uses to set property values when XML
+ * factories are initiated.
+ *
+ * - {@code jaxp-strict.properties}: a configuration that
+ * contains more restrictive settings than the default {@code jaxp.properties}.
+ * In particular:
+ *
+ *
+ * This file allows deployments to test the more secure/strict behavior,
+ * identify issues such as a processor unknowingly makes outbound network
+ * connections to fetch DTD, or processes XML that relies on extension functions.
+ *
+ *
+ * - {@code jaxp-compat.properties}: a configuration specifying
+ * the property values that are the same as the properties' default values. It can
+ * be used to regain compatibility from a more strict configuration in a future release.
+ * The difference from the default {@code jaxp.properties} is that it contains
+ * additional properties that were not included in {@code jaxp.properties},
+ * setting them to their default values.
+ *
+ *
+ *
* JDK built-in Catalog
* The JDK has a built-in catalog that hosts the following DTDs defined by the Java Platform:
*
diff --git a/src/java.xml/share/conf/jaxp-compat.properties b/src/java.xml/share/conf/jaxp-compat.properties
index 8a02e40e49ffa..62527b2742d8c 100644
--- a/src/java.xml/share/conf/jaxp-compat.properties
+++ b/src/java.xml/share/conf/jaxp-compat.properties
@@ -1,10 +1,6 @@
################################################################################
# JAXP Compatibility Configuration File
#
-# ** Warning: unsafe configuration, use with security assessment
-# ** Note: this file can change over time as the security configuration evolves
-# ** along with new development. They may also be phased out and removed.
-#
# This is one of the three configuration files provided in the JDK:
#
# jaxp.properties: this is the default configuration that the JDK uses to set
@@ -36,6 +32,12 @@
# Use the system property java.xml.config.file to override the default configuration:
#
# java -Djava.xml.config.file=$JAVA_HOME/conf/jaxp-compat.properties
+#
+# The pathname to the configuration file must be valid. If it is not absolute,
+# it will be considered relative to the working directory of the JVM. If there
+# is an error reading the configuration file, the configuration process proceeds
+# as if the java.xml.config.file property was not set.
+#
################################################################################
#
diff --git a/src/java.xml/share/conf/jaxp-strict.properties b/src/java.xml/share/conf/jaxp-strict.properties
index 47dd333f62664..4559489e85eb9 100644
--- a/src/java.xml/share/conf/jaxp-strict.properties
+++ b/src/java.xml/share/conf/jaxp-strict.properties
@@ -1,9 +1,6 @@
################################################################################
# JAXP Strict Configuration File
#
-# ** Note: this file can change over time as the security configuration evolves
-# ** along with new development. They may also be phased out and removed.
-#
# This is one of the three configuration files provided in the JDK:
#
# jaxp.properties: this is the default configuration that the JDK uses to set
@@ -34,6 +31,12 @@
# and used to assess the impact of a stricter configuration:
#
# java -Djava.xml.config.file=$JAVA_HOME/conf/jaxp-strict.properties
+#
+# The pathname to the configuration file must be valid. If it is not absolute,
+# it will be considered relative to the working directory of the JVM. If there
+# is an error reading the configuration file, the configuration process proceeds
+# as if the java.xml.config.file property was not set.
+#
################################################################################
#
diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java
new file mode 100644
index 0000000000000..7127166e54f7a
--- /dev/null
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package common.config;
+
+import common.util.TestBase;
+import static common.util.TestBase.CONFIG_COMPAT;
+import static common.util.TestBase.CONFIG_STRICT;
+import java.util.stream.IntStream;
+import javax.xml.transform.TransformerFactory;
+
+/**
+ * @test @bug 8330542
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @modules java.xml/jdk.xml.internal
+ * @run driver common.config.ConfigFileTest 0 // verifies jaxp-strict.properties
+ * @run driver common.config.ConfigFileTest 1 // verifies jaxp-compat.properties
+ * @summary verifies the JAXP configuration files jaxp-strict.properties and
+ * jaxp-compat.properties.
+ */
+public class ConfigFileTest {
+ // system property for custom configuration file
+ static final String SP_CONFIG = "java.xml.config.file";
+
+ // properties in the configuration file
+ String[] keys = {
+ "jdk.xml.enableExtensionFunctions",
+ "jdk.xml.overrideDefaultParser",
+ "jdk.xml.jdkcatalog.resolve",
+ "jdk.xml.dtd.support",
+ "jdk.xml.entityExpansionLimit",
+ "jdk.xml.totalEntitySizeLimit",
+ "jdk.xml.maxGeneralEntitySizeLimit",
+ "jdk.xml.maxParameterEntitySizeLimit",
+ "jdk.xml.entityReplacementLimit",
+ "jdk.xml.elementAttributeLimit",
+ "jdk.xml.maxOccurLimit",
+ "jdk.xml.maxElementDepth",
+ "jdk.xml.maxXMLNameLimit",
+ "jdk.xml.xpathExprGrpLimit",
+ "jdk.xml.xpathExprOpLimit",
+ "jdk.xml.xpathTotalOpLimit"};
+
+ // type of properties
+ boolean[] propertyIsFeature ={true, true, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false};
+
+ // values from jaxp-strict.properties
+ String[] strictValues ={"false", "false", "strict", "allow", "2500", "100000",
+ "100000", "15000", "100000", "10000", "5000", "0", "1000", "10", "100", "10000"};
+
+ // values from jaxp-compat.properties
+ String[] compatValues ={"true", "false", "continue", "allow", "64000", "10000000",
+ "0", "1000000", "3000000", "10000", "5000", "0", "1000", "10", "100", "10000"};
+
+ public static void main(String args[]) throws Exception {
+ new ConfigFileTest().run(args[0]);
+ }
+
+ public void run(String index) throws Exception {
+ if (index.equals("0")) {
+ verifyConfig(CONFIG_STRICT, strictValues);
+ } else {
+ verifyConfig(CONFIG_COMPAT, compatValues);
+ }
+ }
+
+ /**
+ * Verifies a configuration file by iterating through its property settings.
+ * @param filename the configuration file
+ * @param values expected values in the configuration file
+ */
+ private void verifyConfig(String filename, String[] values) {
+ String javaHome = System.getProperty("java.home");
+ System.setProperty(SP_CONFIG, javaHome + "/conf/" + filename);
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ IntStream.range(0, keys.length).forEach(i -> {
+ if (propertyIsFeature[i]) {
+ TestBase.Assert.assertEquals(tf.getFeature(keys[i]), Boolean.parseBoolean(values[i]));
+ } else {
+ TestBase.Assert.assertEquals(tf.getAttribute(keys[i]), values[i]);
+ }
+ });
+ System.clearProperty(SP_CONFIG);
+ }
+}
diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java b/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java
index 6be967d8dd5a2..5466654912efb 100644
--- a/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
+import java.util.Objects;
import java.util.regex.Pattern;
import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures;
@@ -121,6 +122,10 @@ public class TestBase {
// CATALOG=strict
public static final String CONFIG_CATALOG_STRICT = "catalog2.properties";
+ // JAXP Configuration Files to be added to $JAVA_HOME/conf/
+ public static final String CONFIG_STRICT = "jaxp-strict.properties";
+ public static final String CONFIG_COMPAT = "jaxp-compat.properties";
+
public static final String UNKNOWN_HOST = "invalid.site.com";
String xmlExternalEntity, xmlExternalEntityId;
@@ -133,6 +138,10 @@ public static enum Properties {
// config file: CATALOG = strict
CONFIG_FILE_CATALOG_STRICT(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, CONFIG_CATALOG_STRICT)),
CONFIG_FILE_DTD2(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, JCF_DTD2)),
+ // JAXP Configuration Files to be added to $JAVA_HOME/conf/
+ CONFIG_FILE_STRICT(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, CONFIG_STRICT)),
+ CONFIG_FILE_COMPAT(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, CONFIG_COMPAT)),
+
FSP(XMLConstants.FEATURE_SECURE_PROCESSING, null, Type.FEATURE, "true"),
FSP_FALSE(XMLConstants.FEATURE_SECURE_PROCESSING, null, Type.FEATURE, "false"),
@@ -715,7 +724,7 @@ static String getPath(String base, String file) {
return temp;
}
- static class Assert {
+ public static class Assert {
public static void assertTrue(boolean condition) {
assertTrue(condition, null);
}
@@ -733,5 +742,11 @@ public static void assertTrue(boolean condition, String message) {
public static void fail(String message) {
throw new RuntimeException("Test failed. " + message);
}
+
+ public static void assertEquals(Object actual, Object expected) {
+ if (!Objects.equals(actual, expected)) {
+ throw new RuntimeException("Expected: " + expected + " but actual result was " + actual);
+ }
+ }
}
}