From c37c1eb22f4398099dfb360189ad288909be519d Mon Sep 17 00:00:00 2001 From: elharo Date: Fri, 17 Jul 2026 15:03:04 +0000 Subject: [PATCH 1/7] Enable SurrogatePairLengthTest in its own forked JVM --- build.xml | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/build.xml b/build.xml index 3f17b5112..9b064e07e 100644 --- a/build.xml +++ b/build.xml @@ -837,21 +837,30 @@ Authors: - - - - - - - - + + + + + + + + + + + + + From 36364ca31a0533535d4805353228261222008254 Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 12:22:49 +0000 Subject: [PATCH 2/7] Enable SurrogatePairLengthTest without forked JVM Change TypeValidator.getDataLength() to read the system property at runtime instead of caching it in a static final field. The test now uses setUp/tearDown to set and reset the property. --- build.xml | 15 +++------- .../xerces/impl/dv/xs/TypeValidator.java | 19 ++++++------ .../config/SurrogatePairLengthTest.java | 29 +++++++++---------- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/build.xml b/build.xml index bd7d6b400..9068914f9 100644 --- a/build.xml +++ b/build.xml @@ -844,6 +844,10 @@ Authors: --> + + @@ -852,17 +856,6 @@ Authors: - - - - - - diff --git a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java index 56fb2a8c6..fd0dc2758 100644 --- a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java +++ b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java @@ -39,15 +39,8 @@ */ public abstract class TypeValidator { - private static final boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Object run() { - try { - return Boolean.getBoolean("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength") ? Boolean.TRUE : Boolean.FALSE; - } - catch (SecurityException ex) {} - return Boolean.FALSE; - }}) == Boolean.TRUE; + // Checked at runtime to allow tests to set the property via System.setProperty() + // before each test. Tests execute sequentially within a shared JVM. /** * Which facets are allowed for this type. @@ -138,13 +131,19 @@ public int compare(Object value1, Object value2) { public int getDataLength(Object value) { if (value instanceof String) { final String str = (String)value; - if (!USE_CODE_POINT_COUNT_FOR_STRING_LENGTH) { + if (!getCodePointCountEnabled()) { return str.length(); } return getCodePointLength(str); } return -1; } + + private static boolean getCodePointCountEnabled() { + return AccessController.doPrivileged((PrivilegedAction) () -> + Boolean.getBoolean("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength") + ); + } /** * Get the number of digits of the value. diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index 57ab99e81..3a0ab0728 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -17,8 +17,6 @@ package schema.config; -import junit.framework.Assert; - import org.apache.xerces.xs.ElementPSVI; import org.apache.xerces.xs.ItemPSVI; @@ -27,12 +25,20 @@ */ public class SurrogatePairLengthTest extends BaseTest { - // Can only test when the property is set - static { - System.setProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", "true"); + private static final String PROPERTY = "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"; + private static final String LENGTH_ERROR = "cvc-length-valid"; + + // Tests run sequentially within a shared JVM, so setUp/tearDown + // can safely set and reset the system property before each test. + protected void setUp() throws Exception { + super.setUp(); + System.setProperty(PROPERTY, "true"); } - private static final String LENGTH_ERROR = "cvc-length-valid"; + protected void tearDown() throws Exception { + System.clearProperty(PROPERTY); + super.tearDown(); + } protected String getXMLDocument() { return "surrogate.xml"; @@ -50,15 +56,8 @@ public SurrogatePairLengthTest(String name) { super(name); } - // Can only test when the property is set - public void testSetTrue() { - try { - validateDocument(); - } catch (Exception e) { - e.printStackTrace(); - Assert.fail("Validation failed: " + e.getMessage()); - } - + public void testSetTrue() throws Exception { + validateDocument(); checkValidResult(); } From 7d961595219b5ec5bbfc97bca886113a86b7fdc4 Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 12:36:23 +0000 Subject: [PATCH 3/7] Use reflection to toggle TypeValidator flag instead of AccessController The previous approach added a runtime method with AccessController to TypeValidator, which is undesirable. Instead, we remove the 'final' keyword from the existing private static field (no other change to the initialization logic), then use simple Field.setAccessible/set in the test's setUp/tearDown to toggle the flag. No AccessController, no forked JVM, no JVM --add-opens flags needed. --- .../xerces/impl/dv/xs/TypeValidator.java | 19 ++++++++++--------- .../config/SurrogatePairLengthTest.java | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java index fd0dc2758..359a148d2 100644 --- a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java +++ b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java @@ -39,8 +39,15 @@ */ public abstract class TypeValidator { - // Checked at runtime to allow tests to set the property via System.setProperty() - // before each test. Tests execute sequentially within a shared JVM. + private static boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + try { + return Boolean.getBoolean("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength") ? Boolean.TRUE : Boolean.FALSE; + } + catch (SecurityException ex) {} + return Boolean.FALSE; + }}) == Boolean.TRUE; /** * Which facets are allowed for this type. @@ -131,19 +138,13 @@ public int compare(Object value1, Object value2) { public int getDataLength(Object value) { if (value instanceof String) { final String str = (String)value; - if (!getCodePointCountEnabled()) { + if (!USE_CODE_POINT_COUNT_FOR_STRING_LENGTH) { return str.length(); } return getCodePointLength(str); } return -1; } - - private static boolean getCodePointCountEnabled() { - return AccessController.doPrivileged((PrivilegedAction) () -> - Boolean.getBoolean("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength") - ); - } /** * Get the number of digits of the value. diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index 3a0ab0728..5530e0825 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -17,6 +17,9 @@ package schema.config; +import java.lang.reflect.Field; + +import org.apache.xerces.impl.dv.xs.TypeValidator; import org.apache.xerces.xs.ElementPSVI; import org.apache.xerces.xs.ItemPSVI; @@ -27,16 +30,29 @@ public class SurrogatePairLengthTest extends BaseTest { private static final String PROPERTY = "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"; private static final String LENGTH_ERROR = "cvc-length-valid"; + private static final Field codePointCountField; + + static { + try { + Field f = TypeValidator.class.getDeclaredField("USE_CODE_POINT_COUNT_FOR_STRING_LENGTH"); + f.setAccessible(true); + codePointCountField = f; + } catch (Exception e) { + throw new RuntimeException(e); + } + } // Tests run sequentially within a shared JVM, so setUp/tearDown - // can safely set and reset the system property before each test. + // can safely set and reset the flag before each test. protected void setUp() throws Exception { super.setUp(); System.setProperty(PROPERTY, "true"); + codePointCountField.set(null, true); } protected void tearDown() throws Exception { System.clearProperty(PROPERTY); + codePointCountField.set(null, false); super.tearDown(); } From f3f5bbc2127860b69fab7d8e359bad04cd900cef Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 12:45:30 +0000 Subject: [PATCH 4/7] Address review: inline strings, setUp refactor, save original value - Inline PROPERTY and LENGTH_ERROR constants per review feedback - Move all reflection setup from static block to setUp() - Save original field value before modifying, restore in tearDown - Update build.xml comment: explicitly state not safe for parallel execution --- build.xml | 6 +- .../config/SurrogatePairLengthTest.java | 57 ++++++++----------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/build.xml b/build.xml index 9068914f9..0e22139dd 100644 --- a/build.xml +++ b/build.xml @@ -844,9 +844,9 @@ Authors: --> - + diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index 5530e0825..141f612fb 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -28,70 +28,63 @@ */ public class SurrogatePairLengthTest extends BaseTest { - private static final String PROPERTY = "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"; - private static final String LENGTH_ERROR = "cvc-length-valid"; - private static final Field codePointCountField; - - static { - try { - Field f = TypeValidator.class.getDeclaredField("USE_CODE_POINT_COUNT_FOR_STRING_LENGTH"); - f.setAccessible(true); - codePointCountField = f; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - // Tests run sequentially within a shared JVM, so setUp/tearDown - // can safely set and reset the flag before each test. + private Field codePointCountField; + private boolean originalCodePointCount; + protected void setUp() throws Exception { super.setUp(); - System.setProperty(PROPERTY, "true"); - codePointCountField.set(null, true); + System.setProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", "true"); + Field f = TypeValidator.class.getDeclaredField("USE_CODE_POINT_COUNT_FOR_STRING_LENGTH"); + f.setAccessible(true); + codePointCountField = f; + originalCodePointCount = f.getBoolean(null); + f.set(null, true); } - + protected void tearDown() throws Exception { - System.clearProperty(PROPERTY); - codePointCountField.set(null, false); + System.clearProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"); + if (codePointCountField != null) { + codePointCountField.set(null, originalCodePointCount); + } super.tearDown(); } - + protected String getXMLDocument() { return "surrogate.xml"; } - + protected String getSchemaFile() { return "surrogate.xsd"; } - + protected String[] getRelevantErrorIDs() { - return new String[] { LENGTH_ERROR }; + return new String[] { "cvc-length-valid" }; } - + public SurrogatePairLengthTest(String name) { super(name); } - + public void testSetTrue() throws Exception { validateDocument(); checkValidResult(); } - + private void checkValidResult() { - assertNoError(LENGTH_ERROR); - + assertNoError("cvc-length-valid"); + assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity()); assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode .getValidationAttempted()); assertElementName("root", fRootNode.getElementDeclaration().getName()); - + ElementPSVI child = super.getChild(1); assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child .getValidationAttempted()); assertElementName("e1", child.getElementDeclaration().getName()); assertTypeName("length", child.getTypeDefinition().getName()); - + child = super.getChild(2); assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity()); assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child From e4d692b349fd00e740f910f6929606f594cc1948 Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 13:03:33 +0000 Subject: [PATCH 5/7] Use separate forked JVM for SurrogatePairLengthTest Revert the reflection-based approach. Instead, SurrogatePairLengthTest now runs in its own forked JVM via a separate task in build.xml. The test uses a static initializer to set the system property before TypeValidator loads, so its private static final field picks it up. No changes to TypeValidator.java. No reflection, no AccessController. --- build.xml | 19 +++++++++++----- .../xerces/impl/dv/xs/TypeValidator.java | 2 +- .../config/SurrogatePairLengthTest.java | 22 +------------------ 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/build.xml b/build.xml index 0e22139dd..263ba56ef 100644 --- a/build.xml +++ b/build.xml @@ -844,18 +844,25 @@ Authors: --> - - - + - + + + + + + + diff --git a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java index 359a148d2..56fb2a8c6 100644 --- a/src/org/apache/xerces/impl/dv/xs/TypeValidator.java +++ b/src/org/apache/xerces/impl/dv/xs/TypeValidator.java @@ -39,7 +39,7 @@ */ public abstract class TypeValidator { - private static boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH = AccessController.doPrivileged(new PrivilegedAction() { + private static final boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH = AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { try { diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index 141f612fb..cd0e81c42 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -17,9 +17,6 @@ package schema.config; -import java.lang.reflect.Field; - -import org.apache.xerces.impl.dv.xs.TypeValidator; import org.apache.xerces.xs.ElementPSVI; import org.apache.xerces.xs.ItemPSVI; @@ -28,25 +25,8 @@ */ public class SurrogatePairLengthTest extends BaseTest { - private Field codePointCountField; - private boolean originalCodePointCount; - - protected void setUp() throws Exception { - super.setUp(); + static { System.setProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", "true"); - Field f = TypeValidator.class.getDeclaredField("USE_CODE_POINT_COUNT_FOR_STRING_LENGTH"); - f.setAccessible(true); - codePointCountField = f; - originalCodePointCount = f.getBoolean(null); - f.set(null, true); - } - - protected void tearDown() throws Exception { - System.clearProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"); - if (codePointCountField != null) { - codePointCountField.set(null, originalCodePointCount); - } - super.tearDown(); } protected String getXMLDocument() { From 0fd3579f55000940aba3e2b96455fdac8b057e42 Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 14:39:54 +0000 Subject: [PATCH 6/7] Use forked JVM with sysproperty and setUp/tearDown TypeValidator's private static final field reads the system property at class load time, so it must be set before the class loads. The task now sets it via so it's available before any class loading in the forked JVM. The test uses setUp/tearDown to save and restore the property value for correct test hygiene. --- build.xml | 1 + .../schema/config/SurrogatePairLengthTest.java | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 263ba56ef..18daf27e2 100644 --- a/build.xml +++ b/build.xml @@ -860,6 +860,7 @@ Authors: errorproperty="test.failed" showoutput="yes"> + diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index cd0e81c42..c39dbdf49 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -25,8 +25,22 @@ */ public class SurrogatePairLengthTest extends BaseTest { - static { - System.setProperty("org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", "true"); + private static final String PROPERTY = "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"; + private String originalProperty; + + protected void setUp() throws Exception { + super.setUp(); + originalProperty = System.getProperty(PROPERTY); + System.setProperty(PROPERTY, "true"); + } + + protected void tearDown() throws Exception { + if (originalProperty != null) { + System.setProperty(PROPERTY, originalProperty); + } else { + System.clearProperty(PROPERTY); + } + super.tearDown(); } protected String getXMLDocument() { From b3d016b8ad56d0b0a0cc623e41d23309a8962b9c Mon Sep 17 00:00:00 2001 From: elharo Date: Sun, 19 Jul 2026 14:54:56 +0000 Subject: [PATCH 7/7] Set property before super.setUp() to catch TypeValidator loading TypeValidator loads during BaseTest.setUp() (via sf.newSchema()). Setting the system property before calling super.setUp() ensures it is available when TypeValidator's static final field is initialized. No static initializer, no sysproperty in build.xml, no reflection. Property strings inlined, value saved and restored in tearDown. --- build.xml | 1 - tests/schema/config/SurrogatePairLengthTest.java | 14 +++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/build.xml b/build.xml index 18daf27e2..263ba56ef 100644 --- a/build.xml +++ b/build.xml @@ -860,7 +860,6 @@ Authors: errorproperty="test.failed" showoutput="yes"> - diff --git a/tests/schema/config/SurrogatePairLengthTest.java b/tests/schema/config/SurrogatePairLengthTest.java index c39dbdf49..69b415f43 100644 --- a/tests/schema/config/SurrogatePairLengthTest.java +++ b/tests/schema/config/SurrogatePairLengthTest.java @@ -25,20 +25,24 @@ */ public class SurrogatePairLengthTest extends BaseTest { - private static final String PROPERTY = "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"; private String originalProperty; protected void setUp() throws Exception { + originalProperty = System.getProperty( + "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"); + System.setProperty( + "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", "true"); super.setUp(); - originalProperty = System.getProperty(PROPERTY); - System.setProperty(PROPERTY, "true"); } protected void tearDown() throws Exception { if (originalProperty != null) { - System.setProperty(PROPERTY, originalProperty); + System.setProperty( + "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength", + originalProperty); } else { - System.clearProperty(PROPERTY); + System.clearProperty( + "org.apache.xerces.impl.dv.xs.useCodePointCountForStringLength"); } super.tearDown(); }