diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLMarshaller.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLMarshaller.java
index cef173a3c99..0905f7760fd 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLMarshaller.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLMarshaller.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -821,6 +821,7 @@ protected void marshal(Object object, MarshalRecord marshalRecord, ABSTRACT_SESS
}else{
marshalRecord.afterContainmentMarshal(null, object);
}
+ marshalRecord.flush();
}
/**
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/CustomCharacterEscapeHandler.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/CustomCharacterEscapeHandler.java
new file mode 100644
index 00000000000..0b0a9e33d75
--- /dev/null
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/CustomCharacterEscapeHandler.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+package org.eclipse.persistence.testing.oxm.xmlmarshaller;
+
+import org.eclipse.persistence.oxm.CharacterEscapeHandler;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class CustomCharacterEscapeHandler implements CharacterEscapeHandler {
+
+ @Override
+ public void escape(char[] buf, int start, int len, boolean isAttValue, Writer out) throws IOException {
+ for (int i = start; i < start + len; i++) {
+ char ch = buf[i];
+ if (ch == '%') {
+ out.write("*");
+ continue;
+ }
+ out.write(ch);
+ }
+ String end = "";
+ }
+}
diff --git a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/XMLMarshalTestCases.java b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/XMLMarshalTestCases.java
index 6f8354bf0e7..7a247a576bc 100644
--- a/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/XMLMarshalTestCases.java
+++ b/moxy/eclipselink.moxy.test/src/org/eclipse/persistence/testing/oxm/xmlmarshaller/XMLMarshalTestCases.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -30,9 +30,11 @@
import javax.xml.transform.stream.StreamResult;
import org.eclipse.persistence.exceptions.XMLMarshalException;
+import org.eclipse.persistence.oxm.CharacterEscapeHandler;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLMarshaller;
+import org.eclipse.persistence.oxm.record.FormattedOutputStreamRecord;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.w3c.dom.Attr;
@@ -437,6 +439,24 @@ public void testMarshalNonRootObjectToWriter() {
this.assertEquals("userdomain", writer.toString());
}
+ /**
+ * Test for custom CharacterEscapeHandler and FormattedOutputStreamRecord with custom ByteArrayOutputStream output.
+ */
+ public void testMarshalWithCharacterEscapeHandlerToFormattedOutputStreamRecord() {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ FormattedOutputStreamRecord record = new FormattedOutputStreamRecord();
+ record.setOutputStream(byteArrayOutputStream);
+ EmailAddress emailAddress = new EmailAddress();
+ emailAddress.setDomain("%domain%%%");
+ emailAddress.setUserID("%user%%%");
+ marshaller.setFormattedOutput(false);
+ marshaller.setFragment(true);
+ CharacterEscapeHandler characterEscapeHandler = new CustomCharacterEscapeHandler();
+ marshaller.setCharacterEscapeHandler(characterEscapeHandler);
+ marshaller.marshal(emailAddress, record);
+ this.assertEquals("*user****domain***", removeWhiteSpaceFromString(byteArrayOutputStream.toString()));
+ }
+
//Null Test Cases=========================================================================================
public void testMarshalObjectToNullContentHandler() {
SAXDocumentBuilder output = null;