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

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 7fab53f1e8 TODO-248: Narrow marshaller serialize/parse I/O to streams 
only (drop File/StringBuilder)
7fab53f1e8 is described below

commit 7fab53f1e852844c6e1776e81a0425942a3bcac5
Author: James Bognar <[email protected]>
AuthorDate: Thu Jul 16 10:14:32 2026 -0400

    TODO-248: Narrow marshaller serialize/parse I/O to streams only (drop 
File/StringBuilder)
    
    Uniformly stream-only I/O at the 10.0.0 boundary (Option B):
    - Thin (not delete) SerializerPipe/ParserPipe: remove dead 
File/StringBuilder
      instanceof branches, fileCharset/isFile params, and the always-false 
autoClose
      field; retain close/flush lifecycle, charset decoding, debug capture, and
      ParserReader position tracking.
    - Token streaming goes stream-only across classic + token surfaces; 
parseTokens
      methods drop the getFileCharset() argument.
    - Delete CBOR/MsgPack TokenWriter.forOutput factories (thin OutputStream 
aliases);
      sessions now call constructors directly. JSON/JSONL forOutput kept (dual
      Writer/OutputStream). Refresh stale TokenWritable/TokenReadable Javadoc.
    - Migrate classic callers (MenuItemWidget StringBuilder -> 
StringBuilderWriter)
      and ~16 token/record/marshaller test suites (StringBuilder -> 
StringWriter).
    - Fix SerializedRequestAttrVar ($SA) arg-swap bug.
    
    Co-authored-by: Cursor <[email protected]>
---
 .../marshall/cbor/CborSerializerSession.java       |  8 +-
 .../juneau/marshall/cbor/CborTokenWriter.java      | 21 -----
 .../juneau/marshall/json/JsonParserSession.java    |  5 +-
 .../marshall/json/JsonSerializerSession.java       |  3 +-
 .../juneau/marshall/json/JsonTokenWriter.java      | 12 +--
 .../juneau/marshall/json5/Json5ParserSession.java  |  5 +-
 .../marshall/json5l/Json5lParserSession.java       |  5 +-
 .../juneau/marshall/jsonl/JsonlParserSession.java  |  5 +-
 .../juneau/marshall/jsonl/JsonlTokenReader.java    |  4 +-
 .../juneau/marshall/jsonl/JsonlTokenWriter.java    |  9 +--
 .../marshall/msgpack/MsgPackSerializerSession.java |  6 +-
 .../marshall/msgpack/MsgPackTokenWriter.java       | 21 -----
 .../marshall/parser/InputStreamParserSession.java  |  1 -
 .../org/apache/juneau/marshall/parser/Parser.java  |  3 -
 .../apache/juneau/marshall/parser/ParserPipe.java  | 44 ++--------
 .../juneau/marshall/parser/ParserSession.java      |  9 ---
 .../marshall/parser/ReaderParserSession.java       |  4 +-
 .../juneau/marshall/serializer/Serializer.java     |  3 -
 .../juneau/marshall/serializer/SerializerPipe.java | 55 +++----------
 .../marshall/serializer/SerializerSession.java     |  8 +-
 .../serializer/WriterSerializerSession.java        |  2 +-
 .../juneau/marshall/stream/TokenReadable.java      |  2 +-
 .../juneau/marshall/stream/TokenWritable.java      |  5 +-
 .../cbor/CborTokenStreamCoverage_Test.java         | 17 ++--
 .../json/CanonicalSerializerTokens_Test.java       | 12 +--
 .../juneau/marshall/json/JsonTokenStream_Test.java | 94 +++++++++++-----------
 .../marshall/json/JsonTokenWriterEdges_Test.java   | 17 ----
 .../marshall/json5/Json5TokenStream_Test.java      | 16 ++--
 .../marshall/json5l/Json5lTokenStream_Test.java    | 10 ++-
 .../marshall/jsonl/JsonlSessionCoverage_Test.java  | 17 ----
 .../marshall/jsonl/JsonlTokenStream_Test.java      | 50 ++++++------
 .../marshaller/MarshallerStreamShortcuts_Test.java | 11 +--
 .../msgpack/MsgPackTokenStreamCoverage_Test.java   | 17 ++--
 .../serializer/SerializerSession_Test.java         |  4 +-
 .../marshall/stream/ArrayRecordStream_Test.java    |  2 +-
 .../marshall/stream/MultiRecordStream_Test.java    |  9 ++-
 .../juneau/marshall/stream/RecordStream_Test.java  |  2 +-
 .../marshall/stream/StreamInternals_Test.java      | 18 ++---
 .../juneau/marshaller/MarshallUtils_Test.java      | 51 ++++++------
 .../rest/server/vars/SerializedRequestAttrVar.java |  2 +-
 .../juneau/rest/server/widget/MenuItemWidget.java  |  4 +-
 .../rest/server/vars/RestServerVars_Test.java      | 12 ++-
 42 files changed, 208 insertions(+), 397 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborSerializerSession.java
index c3b25b5403..cd35a795ee 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborSerializerSession.java
@@ -137,12 +137,16 @@ public class CborSerializerSession extends 
OutputStreamSerializerSession impleme
         * format &mdash; no text-formatting concepts apply); <c>uriContext</c>,
         * <c>uriResolution</c>, <c>uriRelativity</c>, <c>listener</c>.
         *
-        * @param output The output.  Accepts {@link OutputStream} or {@link 
File}.
+        * @param output The output.  Accepts an {@link OutputStream}.
         * @return A new {@link CborTokenWriter}.
         * @throws IOException If the output type is not supported or could not 
be opened.
         */
        @Override /* TokenWritable */
        public TokenWriter serializeTokens(Object output) throws IOException {
+               if (output == null)
+                       throw new IOException("Output cannot be null.");
+               if (!(output instanceof OutputStream os))
+                       throw new IOException("Cannot convert object of type " 
+ output.getClass().getName() + " to an OutputStream.");
                var walk = new PojoWalker.Options(
                        isKeepNullProperties(),
                        isTrimEmptyMaps(),
@@ -151,7 +155,7 @@ public class CborSerializerSession extends 
OutputStreamSerializerSession impleme
                        isSortCollections(),
                        isTrimStrings(),
                        getMarshallingContext());
-               return CborTokenWriter.forOutput(output, new 
CborTokenWriter.Settings(walk));
+               return new CborTokenWriter(os, new 
CborTokenWriter.Settings(walk));
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborTokenWriter.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborTokenWriter.java
index be44aff550..8f61b167a1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborTokenWriter.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/cbor/CborTokenWriter.java
@@ -101,27 +101,6 @@ public class CborTokenWriter implements TokenWriter {
                this.settings = settings;
        }
 
-       /**
-        * Internal factory used by {@link 
CborSerializerSession#serializeTokens(Object)} to coerce
-        * supported output types ({@link OutputStream}, {@link File}) to a 
CBOR writer.
-        *
-        * @param output The output object.
-        * @param settings The settings.
-        * @return A new {@link CborTokenWriter}.
-        * @throws IOException If the output type is not supported or could not 
be opened.
-        */
-       public static CborTokenWriter forOutput(Object output, Settings 
settings) throws IOException {
-               if (output == null)
-                       throw new IOException("Output cannot be null.");
-               if (output instanceof OutputStream os)
-                       return new CborTokenWriter(os, null, settings);
-               if (output instanceof File f) {
-                       var os = new BufferedOutputStream(new 
FileOutputStream(f));
-                       return new CborTokenWriter(os, os, settings);
-               }
-               throw new IOException("Cannot convert object of type " + 
output.getClass().getName() + " to an OutputStream.");
-       }
-
        @Override /* TokenWriter */
        public TokenWriter startObject() throws IOException {
                assertOpen();
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonParserSession.java
index 716ce04cb9..7eb8be44e3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonParserSession.java
@@ -836,7 +836,7 @@ public class JsonParserSession extends ReaderParserSession 
implements TokenReada
         * {@code @Schema} annotations (only applied on the POJO databind path).
         *
         * @param input The input.  Accepts {@link Reader}, {@link 
CharSequence}, {@link InputStream},
-        *      <code><jk>byte</jk>[]</code>, or {@link File}.
+        *      or <code><jk>byte</jk>[]</code>.
         * @return A new {@link JsonTokenReader}.
         * @throws IOException If a problem occurred opening the underlying 
input.
         */
@@ -851,8 +851,7 @@ public class JsonParserSession extends ReaderParserSession 
implements TokenReada
                        false /* strict */,
                        isAutoCloseStreams(),
                        isUnbuffered(),
-                       getStreamCharset(),
-                       getFileCharset());
+                       getStreamCharset());
                return new JsonTokenReader(pipe, new 
JsonTokenReader.Settings(isTrimStrings()), this);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonSerializerSession.java
index 3d134e9744..bb04839c8a 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonSerializerSession.java
@@ -298,8 +298,7 @@ public class JsonSerializerSession extends 
WriterSerializerSession implements To
         * DOES honor the databind settings (<c>keepNullProperties</c>, 
<c>trimEmptyMaps</c>,
         * <c>trimEmptyCollections</c>, <c>sortMaps</c>, 
<c>sortCollections</c>, <c>trimStrings</c>).
         *
-        * @param output The output.  Accepts {@link Writer}, {@link 
OutputStream}, {@link File}, or
-        *      {@link StringBuilder}.
+        * @param output The output.  Accepts {@link Writer} or {@link 
OutputStream}.
         * @return A new {@link JsonTokenWriter}.
         * @throws IOException If the output type is not supported or could not 
be opened.
         */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonTokenWriter.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonTokenWriter.java
index 2bef7407af..e2590b4845 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonTokenWriter.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json/JsonTokenWriter.java
@@ -23,7 +23,6 @@ import java.io.*;
 import java.math.*;
 import java.nio.charset.*;
 
-import org.apache.juneau.commons.io.*;
 import org.apache.juneau.marshall.stream.*;
 
 /**
@@ -543,8 +542,8 @@ public class JsonTokenWriter implements TokenWriter {
 
        /**
         * Internal factory used by {@link 
JsonSerializer#serializeTokens(Object)}.  Coerces the supported
-        * output types ({@link Writer} / {@link OutputStream} / {@link File} / 
{@link StringBuilder})
-        * into a {@link Writer} the JSON encoder can target.
+        * output types ({@link Writer} / {@link OutputStream}) into a {@link 
Writer} the JSON encoder can
+        * target.
         *
         * @param output The output object.
         * @param settings The output-formatting settings.
@@ -558,13 +557,6 @@ public class JsonTokenWriter implements TokenWriter {
                        return new JsonTokenWriter(w, null, false, settings);
                if (output instanceof OutputStream os)
                        return new JsonTokenWriter(new OutputStreamWriter(os, 
StandardCharsets.UTF_8), null, true, settings);
-               if (output instanceof File f) {
-                       var os = new BufferedOutputStream(new 
FileOutputStream(f));
-                       var w = new OutputStreamWriter(os, 
StandardCharsets.UTF_8);
-                       return new JsonTokenWriter(w, os, true, settings);
-               }
-               if (output instanceof StringBuilder sb)
-                       return new JsonTokenWriter(new StringBuilderWriter(sb), 
null, false, settings);
                throw new IOException("Cannot convert object of type " + 
output.getClass().getName() + " to a Writer.");
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5/Json5ParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5/Json5ParserSession.java
index a5e7ab75bd..4df0838010 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5/Json5ParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5/Json5ParserSession.java
@@ -102,7 +102,7 @@ public class Json5ParserSession extends JsonParserSession {
         * missing values) are applied unconditionally as part of the format.
         *
         * @param input The input.  Accepts {@link Reader}, {@link 
CharSequence}, {@link InputStream},
-        *      <code><jk>byte</jk>[]</code>, or {@link File}.
+        *      or <code><jk>byte</jk>[]</code>.
         * @return A new {@link Json5TokenReader}.
         * @throws IOException If a problem occurred opening the underlying 
input.
         */
@@ -117,8 +117,7 @@ public class Json5ParserSession extends JsonParserSession {
                        false /* strict */,
                        isAutoCloseStreams(),
                        isUnbuffered(),
-                       getStreamCharset(),
-                       getFileCharset());
+                       getStreamCharset());
                return new Json5TokenReader(pipe, new 
JsonTokenReader.Settings(isTrimStrings()), this);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5l/Json5lParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5l/Json5lParserSession.java
index 19cf887a6c..c864c32acd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5l/Json5lParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/json5l/Json5lParserSession.java
@@ -100,7 +100,7 @@ public class Json5lParserSession extends Json5ParserSession 
{
         * {@link Json5ParserSession#parseTokens(Object)}.
         *
         * @param input The input.  Accepts {@link Reader}, {@link 
CharSequence}, {@link InputStream},
-        *      <code><jk>byte</jk>[]</code>, or {@link File}.
+        *      or <code><jk>byte</jk>[]</code>.
         * @return A new {@link Json5lTokenReader}.
         * @throws IOException If a problem occurred opening the underlying 
input.
         */
@@ -115,8 +115,7 @@ public class Json5lParserSession extends Json5ParserSession 
{
                        false /* strict */,
                        isAutoCloseStreams(),
                        isUnbuffered(),
-                       getStreamCharset(),
-                       getFileCharset());
+                       getStreamCharset());
                return new Json5lTokenReader(pipe, new 
JsonTokenReader.Settings(isTrimStrings()), this);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlParserSession.java
index 0e1aa656eb..cfe5e13771 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlParserSession.java
@@ -103,7 +103,7 @@ public class JsonlParserSession extends JsonParserSession {
         * honored/ignored builder properties as {@link 
JsonParserSession#parseTokens(Object)}.
         *
         * @param input The input.  Accepts {@link Reader}, {@link 
CharSequence},
-        *      {@link InputStream}, <code><jk>byte</jk>[]</code>, or {@link 
File}.
+        *      {@link InputStream}, or <code><jk>byte</jk>[]</code>.
         * @return A new {@link JsonlTokenReader}.
         * @throws IOException If a problem occurred opening the underlying 
input.
         */
@@ -118,8 +118,7 @@ public class JsonlParserSession extends JsonParserSession {
                        false /* strict */,
                        isAutoCloseStreams(),
                        isUnbuffered(),
-                       getStreamCharset(),
-                       getFileCharset());
+                       getStreamCharset());
                return new JsonlTokenReader(pipe, new 
JsonTokenReader.Settings(isTrimStrings()), this);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenReader.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenReader.java
index 2d25d4768b..c45b72e15e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenReader.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenReader.java
@@ -33,10 +33,10 @@ import org.apache.juneau.marshall.stream.*;
  * only when the underlying input is exhausted.
  *
  * <p>
- * The most ergonomic way to consume a JSONL file is via {@link #read(Class)}, 
which binds one
+ * The most ergonomic way to consume a JSONL stream is via {@link 
#read(Class)}, which binds one
  * line to a POJO per call:
  * <p class='bjava'>
- *     <jk>try</jk> (TokenReader <jv>r</jv> = 
Jsonl.<jsf>DEFAULT</jsf>.parseTokens(<jv>file</jv>)) {
+ *     <jk>try</jk> (TokenReader <jv>r</jv> = 
Jsonl.<jsf>DEFAULT</jsf>.parseTokens(<jv>reader</jv>)) {
  *             <jk>while</jk> (<jv>r</jv>.canRead()) {
  *                     MyRecord <jv>rec</jv> = 
<jv>r</jv>.read(MyRecord.<jk>class</jk>);
  *                     process(<jv>rec</jv>);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenWriter.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenWriter.java
index 61cabf682a..bf6e97a748 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenWriter.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/jsonl/JsonlTokenWriter.java
@@ -20,7 +20,6 @@ import java.io.*;
 import java.math.*;
 import java.nio.charset.*;
 
-import org.apache.juneau.commons.io.*;
 import org.apache.juneau.marshall.json.*;
 import org.apache.juneau.marshall.stream.*;
 
@@ -75,7 +74,7 @@ public class JsonlTokenWriter implements TokenWriter {
        /**
         * Internal factory that mirrors {@link 
JsonTokenWriter#forOutput(Object, JsonTokenWriter.Settings)}
         * so the per-format {@code tokenWriter(...)} factory can hand in any 
of the supported output
-        * types ({@link Writer}, {@link OutputStream}, {@link File}, {@link 
StringBuilder}).
+        * types ({@link Writer}, {@link OutputStream}).
         *
         * @param output The output object.
         * @param settings The output-formatting settings.
@@ -89,12 +88,6 @@ public class JsonlTokenWriter implements TokenWriter {
                        return new JsonlTokenWriter(w, settings);
                if (output instanceof OutputStream os)
                        return new JsonlTokenWriter(new OutputStreamWriter(os, 
StandardCharsets.UTF_8), settings);
-               if (output instanceof File f) {
-                       var os = new BufferedOutputStream(new 
FileOutputStream(f));
-                       return new JsonlTokenWriter(new OutputStreamWriter(os, 
StandardCharsets.UTF_8), settings, os);
-               }
-               if (output instanceof StringBuilder sb)
-                       return new JsonlTokenWriter(new 
StringBuilderWriter(sb), settings);
                throw new IOException("Cannot convert object of type " + 
output.getClass().getName() + " to a Writer.");
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackSerializerSession.java
index bf153a7217..502645d22e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackSerializerSession.java
@@ -142,6 +142,10 @@ public class MsgPackSerializerSession extends 
OutputStreamSerializerSession impl
         */
        @Override /* TokenWritable */
        public TokenWriter serializeTokens(Object output) throws IOException {
+               if (output == null)
+                       throw new IOException("Output cannot be null.");
+               if (!(output instanceof OutputStream os))
+                       throw new IOException("Cannot convert object of type " 
+ output.getClass().getName() + " to an OutputStream.");
                var walk = new PojoWalker.Options(
                        isKeepNullProperties(),
                        isTrimEmptyMaps(),
@@ -150,7 +154,7 @@ public class MsgPackSerializerSession extends 
OutputStreamSerializerSession impl
                        isSortCollections(),
                        isTrimStrings(),
                        getMarshallingContext());
-               return MsgPackTokenWriter.forOutput(output, new 
MsgPackTokenWriter.Settings(walk));
+               return new MsgPackTokenWriter(os, new 
MsgPackTokenWriter.Settings(walk));
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackTokenWriter.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackTokenWriter.java
index 35fbaf0964..75361f9db9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackTokenWriter.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/msgpack/MsgPackTokenWriter.java
@@ -99,27 +99,6 @@ public class MsgPackTokenWriter implements TokenWriter {
                this.settings = settings;
        }
 
-       /**
-        * Internal factory used by {@link 
MsgPackSerializerSession#serializeTokens(Object)} to coerce
-        * supported output types ({@link OutputStream}, {@link File}) to a 
MsgPack writer.
-        *
-        * @param output The output object.
-        * @param settings The settings.
-        * @return A new {@link MsgPackTokenWriter}.
-        * @throws IOException If the output type is not supported or could not 
be opened.
-        */
-       public static MsgPackTokenWriter forOutput(Object output, Settings 
settings) throws IOException {
-               if (output == null)
-                       throw new IOException("Output cannot be null.");
-               if (output instanceof OutputStream os)
-                       return new MsgPackTokenWriter(os, null, settings);
-               if (output instanceof File f) {
-                       var os = new BufferedOutputStream(new 
FileOutputStream(f));
-                       return new MsgPackTokenWriter(os, os, settings);
-               }
-               throw new IOException("Cannot convert object of type " + 
output.getClass().getName() + " to an OutputStream.");
-       }
-
        /** The active write target for child bytes (top buffer or finalOut). */
        private OutputStream activeOut() {
                return buffers.isEmpty() ? finalOut : buffers.peek();
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/InputStreamParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/InputStreamParserSession.java
index 982338f10c..dbce81a0eb 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/InputStreamParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/InputStreamParserSession.java
@@ -117,7 +117,6 @@ public class InputStreamParserSession extends ParserSession 
{
         *              <li><jk>null</jk>
         *              <li>{@link InputStream}
         *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link File}
         *              <li>{@link CharSequence} containing encoded bytes 
according to the {@link 
org.apache.juneau.marshall.MarshallingContext.Builder#binaryFormat(BinaryFormat)}
 setting.
         *      </ul>
         * @return
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/Parser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/Parser.java
index 9394d7c578..1371ffc7c6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/Parser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/Parser.java
@@ -808,15 +808,12 @@ public class Parser extends MarshallingContextable {
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
         *              <li><code><jk>byte</jk>[]</code> containing UTF-8 
encoded text (or charset defined by
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
-        *              <li>{@link File} containing system encoded text (or 
charset defined by
-        *                      {@link 
ReaderParser.Builder#fileCharset(Charset)} property value).
         *      </ul>
         *      <br>Stream-based parsers can handle the following input class 
types:
         *      <ul>
         *              <li><jk>null</jk>
         *              <li>{@link InputStream}
         *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link File}
         *              <li>{@link CharSequence} containing encoded bytes 
according to the {@link InputStreamParser.Builder#binaryFormat(BinaryFormat)} 
setting.
         *      </ul>
         * @param type
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserPipe.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserPipe.java
index f9808d291f..ccfb37b506 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserPipe.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserPipe.java
@@ -36,7 +36,6 @@ import org.apache.juneau.marshall.*;
  *     <li>{@link CharSequence}
  *     <li>{@link InputStream}
  *     <li><code><jk>byte</jk>[]</code>
- *     <li>{@link File}
  *     <li><code><jk>null</jk></code>
  * </ul>
  *
@@ -45,14 +44,13 @@ import org.apache.juneau.marshall.*;
  * <ul>
  *     <li>{@link InputStream}
  *     <li><code><jk>byte</jk>[]</code>
- *     <li>{@link File}
  *     <li>{@link String} - Hex-encoded bytes.  (not BASE-64!)
  *     <li><code><jk>null</jk></code>
  * </ul>
  *
  * <p>
- * Note that Readers and InputStreams will NOT be automatically closed when 
{@link #close()} is called, but
- * streams and readers created from other types (e.g. Files) WILL be 
automatically closed.
+ * Note that Readers and InputStreams will NOT be automatically closed when 
{@link #close()} is called
+ * unless the {@code autoCloseStreams} setting is enabled.
  *
  * <h5 class='section'>See Also:</h5><ul>
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/SerializersAndParsers";>Serializers 
and Parsers</a>
@@ -81,12 +79,12 @@ public class ParserPipe implements Closeable {
         * Shortcut constructor, typically for straight string input.
         *
         * <p>
-        * Equivalent to calling <code><jk>new</jk> ParserPipe(input, 
<jk>false</jk>, <jk>false</jk>, <jk>null</jk>, <jk>null</jk>);</code>
+        * Equivalent to calling <code><jk>new</jk> ParserPipe(input, 
<jk>false</jk>, <jk>false</jk>, <jk>false</jk>, <jk>false</jk>, 
<jk>null</jk>);</code>
         *
         * @param input The input object.
         */
        public ParserPipe(Object input) {
-               this(input, false, false, false, false, null, null);
+               this(input, false, false, false, false, null);
        }
 
        /**
@@ -135,22 +133,16 @@ public class ParserPipe implements Closeable {
         *      If <jk>true</jk>, we read one character at a time from 
underlying readers when the readers are expected to be parsed
         *      multiple times.
         *      <br>Otherwise, we read character data into a reusable buffer.
-        * @param fileCharset
-        *      The charset to expect when reading from {@link File Files}.
         * @param streamCharset
         *      The charset to expect when reading from {@link InputStream 
InputStreams}.
         */
-       public ParserPipe(Object input, boolean debug, boolean strict, boolean 
autoCloseStreams, boolean unbuffered, Charset streamCharset, Charset 
fileCharset) {
-               boolean isFile = input instanceof File;
+       public ParserPipe(Object input, boolean debug, boolean strict, boolean 
autoCloseStreams, boolean unbuffered, Charset streamCharset) {
                this.input = input;
                this.debug = debug;
                this.strict = strict;
                this.autoCloseStreams = autoCloseStreams;
                this.unbuffered = unbuffered;
-               Charset cs = isFile ? fileCharset : streamCharset;
-               if (cs == null)
-                       cs = (isFile ? Charset.defaultCharset() : UTF8);
-               this.charset = cs;
+               this.charset = streamCharset != null ? streamCharset : UTF8;
                if (input instanceof CharSequence cs2)
                        this.inputString = cs2.toString();
                this.binaryFormat = null;
@@ -230,15 +222,6 @@ public class ParserPipe implements Closeable {
                        inputString = input2;
                        inputStream = new 
ByteArrayInputStream(convertFromString(input2));
                        doClose = false;
-               } else if (input instanceof File input2) {
-                       if (debug) {
-                               var b = readBytes(input2);
-                               inputString = toHex(b);
-                               inputStream = new ByteArrayInputStream(b);
-                       } else {
-                               inputStream = new FileInputStream(input2);
-                               doClose = true;
-                       }
                } else {
                        throw ioex("Cannot convert object of type %s to an 
InputStream.", cn(input));
                }
@@ -302,21 +285,6 @@ public class ParserPipe implements Closeable {
                                inputString = read(reader);
                                reader = new StringReader(inputString);
                        }
-               } else if (input instanceof File input2) {
-                       CharsetDecoder cd = charset.newDecoder();
-                       if (strict) {
-                               cd.onMalformedInput(CodingErrorAction.REPORT);
-                               
cd.onUnmappableCharacter(CodingErrorAction.REPORT);
-                       } else {
-                               cd.onMalformedInput(CodingErrorAction.REPLACE);
-                               
cd.onUnmappableCharacter(CodingErrorAction.REPLACE);
-                       }
-                       reader = new InputStreamReader(new 
FileInputStream(input2), cd);
-                       if (debug) {
-                               inputString = read(reader);
-                               reader = new StringReader(inputString);
-                       }
-                       doClose = true;
                } else {
                        throw ioex("Cannot convert object of type %s to an 
InputStream.", cn(input));
                }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserSession.java
index 5324ab611f..4a061f8be5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ParserSession.java
@@ -495,15 +495,12 @@ public class ParserSession extends MarshallingSession {
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
         *              <li><code><jk>byte</jk>[]</code> containing UTF-8 
encoded text (or charset defined by
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
-        *              <li>{@link File} containing system encoded text (or 
charset defined by
-        *                      {@link 
ReaderParser.Builder#fileCharset(Charset)} property value).
         *      </ul>
         *      <br>Stream-based parsers can handle the following input class 
types:
         *      <ul>
         *              <li><jk>null</jk>
         *              <li>{@link InputStream}
         *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link File}
         *      </ul>
         * @param type
         *      The object type to create.
@@ -602,15 +599,12 @@ public class ParserSession extends MarshallingSession {
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
         *              <li><code><jk>byte</jk>[]</code> containing UTF-8 
encoded text (or charset defined by
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)} property value).
-        *              <li>{@link File} containing system encoded text (or 
charset defined by
-        *                      {@link 
ReaderParser.Builder#fileCharset(Charset)} property value).
         *      </ul>
         *      <br>Stream-based parsers can handle the following input class 
types:
         *      <ul>
         *              <li><jk>null</jk>
         *              <li>{@link InputStream}
         *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link File}
         *      </ul>
         * @param type
         *      The object type to create.
@@ -981,15 +975,12 @@ public class ParserSession extends MarshallingSession {
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)}).
         *              <li><code><jk>byte</jk>[]</code> containing UTF-8 
encoded text (or whatever the encoding specified by
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)}).
-        *              <li>{@link File} containing system encoded text (or 
whatever the encoding specified by
-        *                      {@link 
ReaderParser.Builder#fileCharset(Charset)}).
         *      </ul>
         *      <br>For byte-based parsers, this can be any of the following 
types:
         *      <ul>
         *              <li><jk>null</jk>
         *              <li>{@link InputStream}
         *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link File}
         *              <li>{@link CharSequence} containing encoded bytes 
according to the {@link InputStreamParser.Builder#binaryFormat(BinaryFormat)} 
setting.
         *      </ul>
         * @return
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ReaderParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ReaderParserSession.java
index b517511cc0..f0fd45833c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ReaderParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/parser/ReaderParserSession.java
@@ -196,8 +196,6 @@ public class ReaderParserSession extends ParserSession {
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)}).
         *              <li><code><jk>byte</jk>[]</code> containing UTF-8 
encoded text (or whatever the encoding specified by
         *                      {@link 
ReaderParser.Builder#streamCharset(Charset)}).
-        *              <li>{@link File} containing system encoded text (or 
whatever the encoding specified by
-        *                      {@link 
ReaderParser.Builder#streamCharset(Charset)}).
         *      </ul>
         * @return
         *      A new {@link ParserPipe} wrapper around the specified input 
object.
@@ -207,7 +205,7 @@ public class ReaderParserSession extends ParserSession {
        })
        @Override /* Overridden from ParserSesson */
        public final ParserPipe createPipe(Object input) {
-               return setPipe(new ParserPipe(input, isDebug(), true, 
ctx.isAutoCloseStreams(), ctx.isUnbuffered(), streamCharset, fileCharset));
+               return setPipe(new ParserPipe(input, isDebug(), true, 
ctx.isAutoCloseStreams(), ctx.isUnbuffered(), streamCharset));
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/Serializer.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/Serializer.java
index 6ff77941b6..6d0ec9ba8e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/Serializer.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/Serializer.java
@@ -1187,13 +1187,10 @@ public class Serializer extends 
MarshallingTraverseContext {
         *      <ul>
         *              <li>{@link Writer}
         *              <li>{@link OutputStream} - Output will be written as 
UTF-8 encoded stream.
-        *              <li>{@link File} - Output will be written as 
system-default encoded stream.
-        *              <li>{@link StringBuilder} - Output will be written to 
the specified string builder.
         *      </ul>
         *      <br>Stream-based serializers can handle the following output 
class types:
         *      <ul>
         *              <li>{@link OutputStream}
-        *              <li>{@link File}
         *      </ul>
         * @throws SerializeException If a problem occurred trying to convert 
the output.
         * @throws IOException Thrown by the underlying stream.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerPipe.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerPipe.java
index fc2cf4da49..f9c23dcaed 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerPipe.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerPipe.java
@@ -18,8 +18,6 @@ package org.apache.juneau.marshall.serializer;
 
 import static org.apache.juneau.commons.utils.IoUtils.*;
 import static org.apache.juneau.commons.utils.Shorts.*;
-import static org.apache.juneau.commons.utils.ThrowableUtils.*;
-
 import java.io.*;
 import java.nio.charset.*;
 
@@ -34,28 +32,21 @@ import org.apache.juneau.commons.utils.*;
  * <ul>
  *     <li>{@link Writer}
  *     <li>{@link OutputStream} - Output will be written as UTF-8 encoded 
stream.
- *     <li>{@link File} - Output will be written as system-default encoded 
stream.
- *     <li>{@link StringBuilder}
  * </ul>
  *
  * <p>
- * For stream-based serializers, the output object can be any of the following:
- * <ul>
- *     <li>{@link OutputStream}
- *     <li>{@link File}
- * </ul>
+ * For stream-based serializers, the output object must be an {@link 
OutputStream}.
  *
  * <h5 class='section'>See Also:</h5><ul>
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/SerializersAndParsers";>Serializers 
and Parsers</a>
  * </ul>
  */
 @SuppressWarnings({
-       "resource" // outputStream/writer wrap the caller-supplied output; 
their lifecycle is managed here via close() honoring the autoClose flag.
+       "resource" // outputStream/writer wrap the caller-supplied output; the 
caller retains ownership and close() only flushes.
 })
 public class SerializerPipe implements Closeable {
 
        private final Object output;
-       private final boolean autoClose;
 
        private OutputStream outputStream;
        private Writer writer;
@@ -68,7 +59,6 @@ public class SerializerPipe implements Closeable {
         */
        SerializerPipe(Object output) {
                this.output = output;
-               this.autoClose = false;
                this.charset = null;
        }
 
@@ -76,15 +66,11 @@ public class SerializerPipe implements Closeable {
         * Writer-based constructor.
         *
         * @param output The object to pipe the serializer output to.
+        * @param streamCharset The charset to use when writing to an {@link 
OutputStream}.  If <jk>null</jk>, defaults to UTF-8.
         */
-       SerializerPipe(Object output, Charset streamCharset, Charset 
fileCharset) {
-               boolean isFile = (output instanceof File);
+       SerializerPipe(Object output, Charset streamCharset) {
                this.output = output;
-               this.autoClose = isFile;
-               Charset cs = isFile ? fileCharset : streamCharset;
-               if (cs == null)
-                       cs = isFile ? Charset.defaultCharset() : UTF8;
-               this.charset = cs;
+               this.charset = streamCharset != null ? streamCharset : UTF8;
        }
 
        /**
@@ -94,8 +80,6 @@ public class SerializerPipe implements Closeable {
        public void close() {
                try {
                        IoUtils.flush(writer, outputStream);
-                       if (autoClose)
-                               IoUtils.close(writer, outputStream);
                } catch (IOException e) {
                        throw brex(e);
                }
@@ -108,11 +92,7 @@ public class SerializerPipe implements Closeable {
         * Subclasses can override this method to implement their own 
specialized output streams.
         *
         * <p>
-        * This method can be used if the output object is any of the following 
class types:
-        * <ul>
-        *      <li>{@link OutputStream}
-        *      <li>{@link File}
-        * </ul>
+        * This method can be used if the output object is an {@link 
OutputStream}.
         *
         * @return
         *      The output object wrapped in an output stream.
@@ -126,8 +106,6 @@ public class SerializerPipe implements Closeable {
 
                if (output instanceof OutputStream output2)
                        outputStream = output2;
-               else if (output instanceof File output2)
-                       outputStream = new BufferedOutputStream(new 
FileOutputStream(output2));
                else
                        throw ioex("Cannot convert object of type %s to an 
OutputStream.", cn(output));
 
@@ -152,7 +130,6 @@ public class SerializerPipe implements Closeable {
         * <ul>
         *      <li>{@link Writer}
         *      <li>{@link OutputStream} - Output will be written as UTF-8 
encoded stream.
-        *      <li>{@link File} - Output will be written as system-default 
encoded stream.
         * </ul>
         *
         * @return
@@ -165,20 +142,12 @@ public class SerializerPipe implements Closeable {
                if (output == null)
                        throw new SerializeException("Output cannot be null.");
 
-               try {
-                       if (output instanceof Writer output2)
-                               writer = output2;
-                       else if (output instanceof OutputStream output2)
-                               writer = new OutputStreamWriter(output2, 
charset);
-                       else if (output instanceof File output2)
-                               writer = new OutputStreamWriter(new 
BufferedOutputStream(new FileOutputStream(output2)));
-                       else if (output instanceof StringBuilder output2)
-                               writer = new StringBuilderWriter(output2);
-                       else
-                               throw new SerializeException("Cannot convert 
object of type " + cn(output) + " to a Writer.");
-               } catch (FileNotFoundException e) {
-                       throw castException(SerializeException.class, e);
-               }
+               if (output instanceof Writer output2)
+                       writer = output2;
+               else if (output instanceof OutputStream output2)
+                       writer = new OutputStreamWriter(output2, charset);
+               else
+                       throw new SerializeException("Cannot convert object of 
type " + cn(output) + " to a Writer.");
 
                return new NoCloseWriter(writer);
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerSession.java
index 90328db7d7..7d6cb2921b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/SerializerSession.java
@@ -1201,14 +1201,8 @@ public class SerializerSession extends 
MarshallingTraverseSession {
         *      <ul>
         *              <li>{@link Writer}
         *              <li>{@link OutputStream} - Output will be written as 
UTF-8 encoded stream.
-        *              <li>{@link File} - Output will be written as 
system-default encoded stream.
-        *              <li>{@link StringBuilder}
-        *      </ul>
-        *      <br>For byte-based serializers, this can be any of the 
following types:
-        *      <ul>
-        *              <li>{@link OutputStream}
-        *              <li>{@link File}
         *      </ul>
+        *      <br>For byte-based serializers, this must be an {@link 
OutputStream}.
         * @return
         *      A new {@link ParserPipe} wrapper around the specified input 
object.
         */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/WriterSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/WriterSerializerSession.java
index 454b28570a..e3cf393b67 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/WriterSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/serializer/WriterSerializerSession.java
@@ -295,7 +295,7 @@ public class WriterSerializerSession extends 
SerializerSession {
 
        @Override /* Overridden from SerializerSession */
        protected SerializerPipe createPipe(Object output) {
-               return new SerializerPipe(output, streamCharset, fileCharset);
+               return new SerializerPipe(output, streamCharset);
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenReadable.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenReadable.java
index bee71628be..4aea539a7f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenReadable.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenReadable.java
@@ -42,7 +42,7 @@ public interface TokenReadable extends RecordReadable {
         * Opens a low-level {@link TokenReader} cursor over the specified 
input.
         *
         * @param input The input.  Subtypes define the supported types 
(typically
-        *      {@link Reader} / {@link CharSequence} / {@link InputStream} / 
{@code byte[]} / {@link File}).
+        *      {@link Reader} / {@link CharSequence} / {@link InputStream} / 
<code><jk>byte</jk>[]</code>).
         * @return A new {@link TokenReader} cursor positioned at {@link 
TokenType#NOT_AVAILABLE}.
         * @throws IOException If a problem occurred reading the underlying 
input.
         */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenWritable.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenWritable.java
index a9d77133d4..bfda1c5a8a 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenWritable.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/stream/TokenWritable.java
@@ -40,8 +40,9 @@ public interface TokenWritable extends RecordWritable {
        /**
         * Opens a low-level {@link TokenWriter} push generator targeting the 
specified output.
         *
-        * @param output The output.  Subtypes define the supported types 
(typically
-        *      {@link Writer} / {@link OutputStream} / {@link File} / {@link 
StringBuilder}).
+        * @param output The output.  Subtypes define the supported types: byte 
formats (cbor, msgpack)
+        *      accept an {@link OutputStream}; char formats (json, json5, 
jsonl, jsonschema, jcs) accept a
+        *      {@link Writer} or an {@link OutputStream} (encoded as UTF-8).
         * @return A new {@link TokenWriter}.
         * @throws IOException If a problem occurred opening the underlying 
output.
         */
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/cbor/CborTokenStreamCoverage_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/cbor/CborTokenStreamCoverage_Test.java
index 364fe72ef2..87bfa2a503 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/cbor/CborTokenStreamCoverage_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/cbor/CborTokenStreamCoverage_Test.java
@@ -307,24 +307,19 @@ class CborTokenStreamCoverage_Test extends TestBase {
                        assertArrayEquals(bos.toByteArray(), 
bos2.toByteArray());
                }
 
-               @Test void w02_forOutput() throws Exception {
+               @Test void w02_constructorAndSessionTypeRejection() throws 
Exception {
                        var bos = new ByteArrayOutputStream();
-                       try (var w = CborTokenWriter.forOutput(bos, 
CborTokenWriter.Settings.DEFAULT)) {
+                       try (var w = new CborTokenWriter(bos, 
CborTokenWriter.Settings.DEFAULT)) {
                                w.number(1);
                        }
                        assertTrue(bos.toByteArray().length > 0);
 
-                       var f = File.createTempFile("cbortok", ".cbor");
-                       f.deleteOnExit();
-                       try (var w = CborTokenWriter.forOutput(f, 
CborTokenWriter.Settings.DEFAULT)) {
-                               w.startArray().number(1).number(2).endArray();
-                       }
-                       assertTrue(f.length() > 0);
-
+                       // The Object-to-OutputStream narrowing (and 
null/illegal-type rejection) lives on the
+                       // session (the Object interface boundary); the writer 
takes a statically-typed OutputStream.
                        assertThrowsWithMessage(IOException.class, "Output 
cannot be null.",
-                               () -> CborTokenWriter.forOutput(null, 
CborTokenWriter.Settings.DEFAULT));
+                               () -> 
CborSerializer.DEFAULT.serializeTokens(null));
                        assertThrowsWithMessage(IOException.class, "Cannot 
convert object of type",
-                               () -> CborTokenWriter.forOutput("not-a-stream", 
CborTokenWriter.Settings.DEFAULT));
+                               () -> 
CborSerializer.DEFAULT.serializeTokens("not-a-stream"));
                }
 
                @Test void w03_numberOverloadsRoundTrip() throws Exception {
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/CanonicalSerializerTokens_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/CanonicalSerializerTokens_Test.java
index 191c65435a..e280cc366a 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/CanonicalSerializerTokens_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/CanonicalSerializerTokens_Test.java
@@ -18,6 +18,8 @@ package org.apache.juneau.marshall.json;
 
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.io.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.marshall.jcs.*;
 import org.junit.jupiter.api.*;
@@ -28,12 +30,12 @@ import org.junit.jupiter.api.*;
  * disabled (canonical output can't be expressed through the generic walker).
  */
 @SuppressWarnings({
-       "resource" // Token writers wrap in-memory StringBuilders; nothing to 
clean up.
+       "resource" // Token writers wrap in-memory StringWriters; nothing to 
clean up.
 })
 class CanonicalSerializerTokens_Test extends TestBase {
 
        @Test void a01_jcsSerializeTokensEmitsRawJson() throws Exception {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = JcsSerializer.DEFAULT.serializeTokens(sb)) {
                        w.startObject();
                        w.fieldName("a"); w.number(1L);
@@ -43,13 +45,13 @@ class CanonicalSerializerTokens_Test extends TestBase {
        }
 
        @Test void a02_jcsSerializeTokensDisablesObjectBridge() throws 
Exception {
-               try (var w = JcsSerializer.DEFAULT.serializeTokens(new 
StringBuilder())) {
+               try (var w = JcsSerializer.DEFAULT.serializeTokens(new 
StringWriter())) {
                        assertThrows(UnsupportedOperationException.class, () -> 
w.object(1));
                }
        }
 
        @Test void a03_jsonSchemaSerializeTokensEmitsRawJson() throws Exception 
{
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = JsonSchemaSerializer.DEFAULT.serializeTokens(sb)) {
                        w.startArray();
                        w.number(1L);
@@ -60,7 +62,7 @@ class CanonicalSerializerTokens_Test extends TestBase {
        }
 
        @Test void a04_jsonSchemaSerializeTokensDisablesObjectBridge() throws 
Exception {
-               try (var w = JsonSchemaSerializer.DEFAULT.serializeTokens(new 
StringBuilder())) {
+               try (var w = JsonSchemaSerializer.DEFAULT.serializeTokens(new 
StringWriter())) {
                        assertThrows(UnsupportedOperationException.class, () -> 
w.object(1));
                }
        }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenStream_Test.java
index 3143c81e19..5ab671e352 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenStream_Test.java
@@ -281,7 +281,7 @@ class JsonTokenStream_Test extends TestBase {
        @Nested class C_writer extends TestBase {
 
                @Test void c01_emptyObject() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject().endObject();
                        }
@@ -289,7 +289,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c02_emptyArray() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray().endArray();
                        }
@@ -297,7 +297,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c03_simpleObject() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.number(1);
@@ -310,7 +310,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c04_nested() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                w.fieldName("a");
@@ -330,7 +330,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c05_stringEscaping() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray();
                                w.string("a\nb");
@@ -342,7 +342,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c06_numberOverloads() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray();
                                w.number(7L);
@@ -356,7 +356,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c07_stringNullEmitsNull() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray();
                                w.string(null);
@@ -366,7 +366,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c08_binaryAsBase64String() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray();
                                w.binary(new byte[]{1, 2, 3, 4});
@@ -376,14 +376,14 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c09_capability() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                assertTrue(w.isStreaming());
                        }
                }
 
                @Test void c10_doubleFieldNameRejected() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                w.fieldName("a");
@@ -392,7 +392,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c11_fieldNameOutsideObjectRejected() throws 
Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                assertThrows(IllegalStateException.class, () -> 
w.fieldName("a"));
                                w.startArray();
@@ -401,7 +401,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c12_writeEndKindMismatch() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                assertThrows(IllegalStateException.class, 
w::endArray);
@@ -409,7 +409,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c13_nonFiniteDoubleRejected() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startArray();
                                assertThrows(IOException.class, () -> 
w.number(Double.NaN));
@@ -437,7 +437,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void c16_writeAfterCloseThrows() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        var w = toJsonTokens(sb);
                        w.startArray().endArray();
                        w.close();
@@ -464,7 +464,7 @@ class JsonTokenStream_Test extends TestBase {
        @Nested class D_roundTrip extends TestBase {
 
                @Test void d01_basicRoundTrip() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                w.fieldName("greeting"); w.string("hello");
@@ -497,7 +497,7 @@ class JsonTokenStream_Test extends TestBase {
                        // Build the same value twice: once via the token 
writer, once via JsonSerializer.DEFAULT.
                        // Outputs should be byte-for-byte equal because both 
produce compact RFC-8259 JSON with
                        // double-quoted keys and no whitespace.
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = toJsonTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.number(1);
@@ -528,7 +528,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void e02_jsonSerializerDeclaresFull() throws Exception {
                        assertInstanceOf(TokenWritable.class, 
JsonSerializer.DEFAULT);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                assertWriterStreaming(w);
                        }
@@ -539,7 +539,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void f01_useWhitespacePrettyPrints() throws Exception {
                        var ser = 
JsonSerializer.create().useWhitespace().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.number(1);
@@ -564,7 +564,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void f02_useWhitespaceEmptyContainersStayCompact() throws 
Exception {
                        var ser = 
JsonSerializer.create().useWhitespace().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("empties");
@@ -587,7 +587,7 @@ class JsonTokenStream_Test extends TestBase {
                @Test void f03_quoteCharOverride() throws Exception {
                        // Single-quote output (e.g. for embedding in HTML 
attributes).
                        var ser = 
JsonSerializer.create().quoteChar('\'').build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("greeting"); w.string("o'reilly");
@@ -598,7 +598,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void f04_escapeSolidus() throws Exception {
                        var ser = 
JsonSerializer.create().escapeSolidus().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startArray();
                                w.string("path/to/thing");
@@ -609,7 +609,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void f05_trimStringsOnWriter() throws Exception {
                        var ser = JsonSerializer.create().trimStrings().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("  padded  "); w.string("  value  
");
@@ -621,7 +621,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void f06_defaultSerializerStaysCompact() throws Exception 
{
                        // JsonSerializer.DEFAULT should still produce the 
canonical compact form.
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.number(1);
@@ -666,7 +666,7 @@ class JsonTokenStream_Test extends TestBase {
                        // useWhitespace + maxIndent=2 means levels 0..2 indent 
(0/2/4 spaces), and levels >= 2
                        // emit no further per-level indent.  The structural 
newlines themselves still appear.
                        var ser = 
JsonSerializer.create().useWhitespace().maxIndent(2).build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("a");
@@ -716,14 +716,10 @@ class JsonTokenStream_Test extends TestBase {
                        }
                }
 
-               @Test void f13_fileCharsetHonored() throws Exception {
-                       var tmp = File.createTempFile("juneau-tokenstream-", 
".json");
-                       tmp.deleteOnExit();
-                       try (var os = new FileOutputStream(tmp)) {
-                               os.write(new byte[]{'"', (byte) 0xE9, '"'});  
// ISO_8859_1 'é'
-                       }
-                       var p = 
JsonParser.create().fileCharset(java.nio.charset.StandardCharsets.ISO_8859_1).build();
-                       try (var r = p.parseTokens(tmp)) {
+               @Test void f13_streamCharsetHonored() throws Exception {
+                       var bytes = new byte[]{'"', (byte) 0xE9, '"'};  // 
ISO_8859_1 'é'
+                       var p = 
JsonParser.create().streamCharset(java.nio.charset.StandardCharsets.ISO_8859_1).build();
+                       try (var r = p.parseTokens(new 
ByteArrayInputStream(bytes))) {
                                assertEquals(TokenType.VALUE_STRING, r.next());
                                assertEquals("é", r.getString());
                        }
@@ -734,7 +730,7 @@ class JsonTokenStream_Test extends TestBase {
                        // the token output.  We pick one writer-side flag 
(addBeanTypesJson + sortMaps) and one
                        // reader-side flag (debugOutputLines + listener=null).
                        var ser = 
JsonSerializer.create().addBeanTypesJson().sortMaps().keepNullProperties().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("z"); w.number(1);
@@ -883,7 +879,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void h01_simpleScalar() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(42);
                        }
@@ -891,7 +887,7 @@ class JsonTokenStream_Test extends TestBase {
                }
 
                @Test void h02_nullEmitsNil() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(null);
                        }
@@ -903,7 +899,7 @@ class JsonTokenStream_Test extends TestBase {
                        b.name = "alice";
                        b.age = 30;
                        b.tags = List.of("x", "y");
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(b);
                        }
@@ -915,7 +911,7 @@ class JsonTokenStream_Test extends TestBase {
                        var b1 = new HBean(); b1.name = "a"; b1.age = 1;
                        var b2 = new HBean(); b2.name = "b"; b2.age = 2;
                        var beans = List.of(b1, b2);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(beans);
                        }
@@ -928,7 +924,7 @@ class JsonTokenStream_Test extends TestBase {
                        m.put("b", List.of("x", "y"));
                        m.put("c", new int[]{10, 20});
                        m.put("d", Map.of("nested", true));
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -937,7 +933,7 @@ class JsonTokenStream_Test extends TestBase {
 
                @Test void h06_byteArrayEmitsBinary() throws Exception {
                        var bytes = new byte[]{1, 2, 3, 4};
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(bytes);
                        }
@@ -952,7 +948,7 @@ class JsonTokenStream_Test extends TestBase {
                        var payload = new HBean();
                        payload.name = "alice";
                        payload.age = 30;
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("envelopeVersion"); w.number(1);
@@ -970,7 +966,7 @@ class JsonTokenStream_Test extends TestBase {
                        m.put("m", 3);
                        // With sortMaps, keys come out in alphabetical order.
                        var ser = JsonSerializer.create().sortMaps().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -982,7 +978,7 @@ class JsonTokenStream_Test extends TestBase {
                        var m = new LinkedHashMap<String, Integer>();
                        m.put("z", 1);
                        m.put("a", 2);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -998,7 +994,7 @@ class JsonTokenStream_Test extends TestBase {
                        // But the actual default on JsonSerializer.DEFAULT is 
to skip nulls during a databind
                        // emit; verify that the walker honors the configured 
setting.
                        var skipNullsSer = 
JsonSerializer.create().keepNullProperties(false).build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = skipNullsSer.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -1010,7 +1006,7 @@ class JsonTokenStream_Test extends TestBase {
                        m.put("a", 1);
                        m.put("b", null);
                        var ser = 
JsonSerializer.create().keepNullProperties().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -1022,7 +1018,7 @@ class JsonTokenStream_Test extends TestBase {
                        m.put("a", 1);
                        m.put("b", Map.of());
                        var ser = 
JsonSerializer.create().trimEmptyMaps().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -1034,7 +1030,7 @@ class JsonTokenStream_Test extends TestBase {
                        m.put("a", 1);
                        m.put("b", List.of());
                        var ser = 
JsonSerializer.create().trimEmptyCollections().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.object(m);
                        }
@@ -1044,7 +1040,7 @@ class JsonTokenStream_Test extends TestBase {
                @Test void h14_sortCollectionsHonored() throws Exception {
                        var l = List.of("c", "a", "b");
                        var ser = 
JsonSerializer.create().sortCollections().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = ser.serializeTokens(sb)) {
                                w.object(l);
                        }
@@ -1055,7 +1051,7 @@ class JsonTokenStream_Test extends TestBase {
                        // java.time.LocalDate has a swap registered in 
DefaultSwaps; object() should emit
                        // it as the swapped string form (ISO-8601), not as a 
bean walk over its public methods.
                        var date = java.time.LocalDate.of(2026, 
java.time.Month.JUNE, 12);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(date);
                        }
@@ -1074,7 +1070,7 @@ class JsonTokenStream_Test extends TestBase {
                        b.scores.put("math", 95);
                        b.scores.put("english", 87);
 
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(b);
                        }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenWriterEdges_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenWriterEdges_Test.java
index 3b5f385e47..11de3e4085 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenWriterEdges_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json/JsonTokenWriterEdges_Test.java
@@ -170,23 +170,6 @@ class JsonTokenWriterEdges_Test extends TestBase {
                assertEquals("\"x\"", bos.toString(StandardCharsets.UTF_8));
        }
 
-       @Test void a14_forOutputFile() throws Exception {
-               var f = File.createTempFile("juneau-jtw-", ".json");
-               f.deleteOnExit();
-               try (var w = JsonTokenWriter.forOutput(f, DEFAULT)) {
-                       w.number(42L);
-               }
-               assertEquals("42", new 
String(java.nio.file.Files.readAllBytes(f.toPath()), StandardCharsets.UTF_8));
-       }
-
-       @Test void a15_forOutputStringBuilder() throws Exception {
-               var sb = new StringBuilder();
-               try (var w = JsonTokenWriter.forOutput(sb, DEFAULT)) {
-                       w.bool(false);
-               }
-               assertEquals("false", sb.toString());
-       }
-
        @Test void a16_forOutputNullRejected() {
                assertThrowsWithMessage(IOException.class, "Output cannot be 
null.", () -> JsonTokenWriter.forOutput(null, DEFAULT));
        }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5/Json5TokenStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5/Json5TokenStream_Test.java
index 79d672520d..43dc1372c6 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5/Json5TokenStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5/Json5TokenStream_Test.java
@@ -19,6 +19,8 @@ package org.apache.juneau.marshall.json5;
 import static org.apache.juneau.marshall.stream.TokenStreamAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.io.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.marshall.stream.*;
 import org.junit.jupiter.api.*;
@@ -155,7 +157,7 @@ class Json5TokenStream_Test extends TestBase {
        @Nested class B_writer extends TestBase {
 
                @Test void b01_defaultQuoteCharIsSingle() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.string("hi");
@@ -166,7 +168,7 @@ class Json5TokenStream_Test extends TestBase {
                }
 
                @Test void b02_simpleAttrsUnquotedField() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("user_id"); w.number(42);
@@ -177,7 +179,7 @@ class Json5TokenStream_Test extends TestBase {
 
                @Test void b03_simpleAttrsQuotesNonIdentifier() throws 
Exception {
                        // Field names with special chars or reserved words 
still get quoted.
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("not-an-identifier"); w.number(1);
@@ -189,7 +191,7 @@ class Json5TokenStream_Test extends TestBase {
 
                @Test void b04_capability() throws Exception {
                        assertInstanceOf(TokenWritable.class, 
Json5Serializer.DEFAULT);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                assertWriterStreaming(w);
                        }
@@ -203,7 +205,7 @@ class Json5TokenStream_Test extends TestBase {
        @Nested class C_roundTrip extends TestBase {
 
                @Test void c01_roundTrip() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("name"); w.string("alice");
@@ -273,7 +275,7 @@ class Json5TokenStream_Test extends TestBase {
                        var b = new EBean();
                        b.name = "alice";
                        b.age = 30;
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.object(b);
                        }
@@ -287,7 +289,7 @@ class Json5TokenStream_Test extends TestBase {
                        var m = new java.util.LinkedHashMap<String, Object>();
                        m.put("a", 1);
                        m.put("b", java.util.List.of("x", "y"));
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5Serializer.DEFAULT.serializeTokens(sb)) {
                                w.object(m);
                        }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5l/Json5lTokenStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5l/Json5lTokenStream_Test.java
index ed879f9248..70fb6b0ec9 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5l/Json5lTokenStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/json5l/Json5lTokenStream_Test.java
@@ -20,6 +20,8 @@ import static 
org.apache.juneau.marshall.stream.TokenStreamAssertions.*;
 import static org.apache.juneau.test.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.io.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.marshall.stream.*;
 import org.junit.jupiter.api.*;
@@ -73,7 +75,7 @@ class Json5lTokenStream_Test extends TestBase {
        @Nested class B_writer extends TestBase {
 
                @Test void b01_strictDefault() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5lSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject(); w.fieldName("a"); w.number(1); 
w.endObject();
                                w.startObject(); w.fieldName("b"); w.number(2); 
w.endObject();
@@ -83,7 +85,7 @@ class Json5lTokenStream_Test extends TestBase {
 
                @Test void b02_sugarUnquotedKeysSingleQuotes() throws Exception 
{
                        var s = Json5lSerializer.create().json5Sugar().build();
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = s.serializeTokens(sb)) {
                                w.startObject(); w.fieldName("a"); 
w.string("x"); w.endObject();
                                w.startObject(); w.fieldName("b"); 
w.string("y"); w.endObject();
@@ -93,7 +95,7 @@ class Json5lTokenStream_Test extends TestBase {
 
                @Test void b03_capability() throws Exception {
                        assertInstanceOf(TokenWritable.class, 
Json5lSerializer.DEFAULT);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
Json5lSerializer.DEFAULT.serializeTokens(sb)) {
                                assertWriterStreaming(w);
                        }
@@ -114,7 +116,7 @@ class Json5lTokenStream_Test extends TestBase {
                }
 
                @Test void c02_roundTrip() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (RecordWriter w = 
Json5lSerializer.DEFAULT.serializeArrayRecords(sb)) {
                                assertTrue(w.isStreaming());
                                w.write(java.util.Map.of("x", 1));
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlSessionCoverage_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlSessionCoverage_Test.java
index 364f638dd2..5cc03350a6 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlSessionCoverage_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlSessionCoverage_Test.java
@@ -204,23 +204,6 @@ class JsonlSessionCoverage_Test extends TestBase {
                        assertEquals("1\n", sw.toString());
                }
 
-               @Test void c05_forOutputStringBuilder() throws Exception {
-                       var sb = new StringBuilder();
-                       try (var w = JsonlTokenWriter.forOutput(sb, SETTINGS)) {
-                               w.bool(true);
-                       }
-                       assertEquals("true\n", sb.toString());
-               }
-
-               @Test void c06_forOutputFile() throws Exception {
-                       var f = File.createTempFile("juneau-jltw-", ".jsonl");
-                       f.deleteOnExit();
-                       try (var w = JsonlTokenWriter.forOutput(f, SETTINGS)) {
-                               w.number(42L);
-                       }
-                       assertEquals("42\n", new 
String(java.nio.file.Files.readAllBytes(f.toPath()), StandardCharsets.UTF_8));
-               }
-
                @Test void c07_forOutputNullRejected() {
                        assertThrowsWithMessage(IOException.class, "Output 
cannot be null.", () -> JsonlTokenWriter.forOutput(null, SETTINGS));
                }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlTokenStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlTokenStream_Test.java
index dbb2cd8f3b..ba733abb26 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlTokenStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/jsonl/JsonlTokenStream_Test.java
@@ -23,8 +23,6 @@ import static org.junit.jupiter.api.Assertions.*;
 
 import java.io.*;
 import java.nio.charset.*;
-import java.nio.file.*;
-
 import org.apache.juneau.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.marshall.json.*;
@@ -89,7 +87,7 @@ class JsonlTokenStream_Test extends TestBase {
        @Nested class B_writer extends TestBase {
 
                @Test void b01_singleObjectGetsTrailingNewline() throws 
Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject();
                                w.fieldName("a"); w.number(1);
@@ -99,7 +97,7 @@ class JsonlTokenStream_Test extends TestBase {
                }
 
                @Test void b02_multipleObjects() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject(); w.fieldName("a"); w.number(1); 
w.endObject();
                                w.startObject(); w.fieldName("b"); w.number(2); 
w.endObject();
@@ -108,7 +106,7 @@ class JsonlTokenStream_Test extends TestBase {
                }
 
                @Test void b03_topLevelScalars() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                w.number(1);
                                w.number(2);
@@ -119,14 +117,14 @@ class JsonlTokenStream_Test extends TestBase {
 
                @Test void b04_capability() throws Exception {
                        assertInstanceOf(TokenWritable.class, 
JsonlSerializer.DEFAULT);
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                assertWriterStreaming(w);
                        }
                }
 
                @Test void b05_writeAfterCloseThrows() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        var w = JsonlSerializer.DEFAULT.serializeTokens(sb);
                        w.startObject().endObject();
                        w.close();
@@ -190,7 +188,7 @@ class JsonlTokenStream_Test extends TestBase {
        @Nested class D_roundTrip extends TestBase {
 
                @Test void d01_writeThenRead() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                w.startObject(); w.fieldName("x"); w.number(1); 
w.endObject();
                                w.startObject(); w.fieldName("x"); w.number(2); 
w.endObject();
@@ -222,7 +220,7 @@ class JsonlTokenStream_Test extends TestBase {
                @Test void e01_objectEmitsTrailingNewline() throws Exception {
                        var b1 = new EBean(); b1.name = "alice"; b1.age = 30;
                        var b2 = new EBean(); b2.name = "bob";   b2.age = 40;
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                w.object(b1);
                                w.object(b2);
@@ -238,7 +236,7 @@ class JsonlTokenStream_Test extends TestBase {
                                java.util.Map.of("x", 1),
                                java.util.Map.of("x", 2),
                                java.util.Map.of("x", 3));
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(sb)) {
                                for (var r : records)
                                        w.object(r);
@@ -248,15 +246,14 @@ class JsonlTokenStream_Test extends TestBase {
        }
 
        // 
=================================================================================
-       // F. File-backed writer resource ownership
+       // F. Owned-resource lifecycle + stream round-trip
        // 
=================================================================================
 
-       @Nested class F_fileResource extends TestBase {
+       @Nested class F_ownedResource extends TestBase {
 
                @Test void f01_closeClosesOwnedStream() throws Exception {
-                       // The File factory registers the stream it opened as 
'owned'; close() must close it.
-                       // Use the package-private (out, settings, owned) 
constructor with a probe Closeable to
-                       // directly assert the owned resource is closed.
+                       // The (out, settings, owned) constructor records a 
Closeable as 'owned'; close() must close it.
+                       // Use a probe Closeable to directly assert the owned 
resource is closed.
                        var closed = Flag.create();
                        Closeable probe = closed::set;
                        var w = new JsonlTokenWriter(new StringWriter(), 
JsonTokenWriter.Settings.DEFAULT, probe);
@@ -275,21 +272,20 @@ class JsonlTokenStream_Test extends TestBase {
                        assertEquals(1, closeCount.get());
                }
 
-               @Test void f03_fileWriterFlushesFullContent() throws Exception {
-                       // End-to-end: the File factory's BufferedOutputStream 
is owned and closed, so the full
-                       // content (including JSONL trailing newlines) is on 
disk after close().
-                       var tmp = 
File.createTempFile("juneau-jsonl-tokenstream-", ".jsonl");
-                       tmp.deleteOnExit();
-                       try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(tmp)) {
+               @Test void f03_streamWriterFlushesFullContent() throws 
Exception {
+                       // End-to-end: on close() the underlying 
OutputStreamWriter is flushed, so the full JSONL
+                       // content (including trailing newlines) reaches the 
target OutputStream.
+                       var baos = new ByteArrayOutputStream();
+                       try (var w = 
JsonlSerializer.DEFAULT.serializeTokens(baos)) {
                                w.startObject(); w.fieldName("a"); w.number(1); 
w.endObject();
                                w.startObject(); w.fieldName("b"); w.number(2); 
w.endObject();
                        }
-                       // Raw-bytes proof: the owned file stream was 
flushed+closed, so the full JSONL content
-                       // (including trailing newlines) is on disk after 
close().
-                       assertString("{\"a\":1}\n{\"b\":2}\n", 
Files.readString(tmp.toPath(), StandardCharsets.UTF_8));
+                       // Raw-bytes proof: the OutputStreamWriter was flushed 
on close, so the full JSONL content
+                       // (including trailing newlines) is present.
+                       assertString("{\"a\":1}\n{\"b\":2}\n", 
baos.toString(StandardCharsets.UTF_8));
 
-                       // BCT state proof: stream the records back off disk 
and assert each parsed record's shape.
-                       try (var r = JsonlParser.DEFAULT.parseTokens(tmp)) {
+                       // BCT state proof: stream the records back and assert 
each parsed record's shape.
+                       try (var r = JsonlParser.DEFAULT.parseTokens(new 
ByteArrayInputStream(baos.toByteArray()))) {
                                assertTrue(r.canRead());
                                assertBean(r.read(java.util.Map.class), "a", 
"1");
                                assertTrue(r.canRead());
@@ -316,7 +312,7 @@ class JsonlTokenStream_Test extends TestBase {
 
                @Test void g02_roundTrip() throws Exception {
                        // Write several records via serializeArrayRecords(...).
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (RecordWriter w = 
JsonlSerializer.DEFAULT.serializeArrayRecords(sb)) {
                                assertTrue(w.isStreaming());
                                w.write(java.util.Map.of("x", 1));
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/marshaller/MarshallerStreamShortcuts_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/marshaller/MarshallerStreamShortcuts_Test.java
index c03e86a05d..b09fab6540 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/marshaller/MarshallerStreamShortcuts_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/marshaller/MarshallerStreamShortcuts_Test.java
@@ -19,6 +19,7 @@ package org.apache.juneau.marshall.marshaller;
 import static org.apache.juneau.test.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -45,7 +46,7 @@ class MarshallerStreamShortcuts_Test extends TestBase {
        }
 
        @Test void a02_writeTokens() throws Exception {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = Json.ofTokens(sb)) {
                        w.startArray().number(1).endArray();
                }
@@ -61,7 +62,7 @@ class MarshallerStreamShortcuts_Test extends TestBase {
        }
 
        @Test void a04_writeRecords() throws Exception {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = Json.ofRecords(sb)) {
                        w.write(Map.of("a", 1));
                }
@@ -79,7 +80,7 @@ class MarshallerStreamShortcuts_Test extends TestBase {
        }
 
        @Test void a06_writeArrayRecords() throws Exception {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = Json.ofArrayRecords(sb)) {
                        w.write(1);
                        w.write(2);
@@ -89,7 +90,7 @@ class MarshallerStreamShortcuts_Test extends TestBase {
 
        @Test void a07_jsonlArrayRecordsAreLineDelimited() throws Exception {
                // JSONL aliases its line record stream — no surrounding [...] 
brackets.
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = Jsonl.ofArrayRecords(sb)) {
                        w.write(Map.of("x", 1));
                        w.write(Map.of("x", 2));
@@ -112,7 +113,7 @@ class MarshallerStreamShortcuts_Test extends TestBase {
        }
 
        @Test void a09_writeTokensClassCastForNonTokenFormat() {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                assertThrows(ClassCastException.class, () -> 
Csv.DEFAULT.writeTokens(sb));
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/msgpack/MsgPackTokenStreamCoverage_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/msgpack/MsgPackTokenStreamCoverage_Test.java
index 215df5dd3b..f14ef15514 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/msgpack/MsgPackTokenStreamCoverage_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/msgpack/MsgPackTokenStreamCoverage_Test.java
@@ -310,24 +310,19 @@ class MsgPackTokenStreamCoverage_Test extends TestBase {
                        assertArrayEquals(bos.toByteArray(), 
bos2.toByteArray());
                }
 
-               @Test void w02_forOutput() throws Exception {
+               @Test void w02_constructorAndSessionTypeRejection() throws 
Exception {
                        var bos = new ByteArrayOutputStream();
-                       try (var w = MsgPackTokenWriter.forOutput(bos, 
MsgPackTokenWriter.Settings.DEFAULT)) {
+                       try (var w = new MsgPackTokenWriter(bos, 
MsgPackTokenWriter.Settings.DEFAULT)) {
                                w.number(1);
                        }
                        assertTrue(bos.toByteArray().length > 0);
 
-                       var f = File.createTempFile("msgpacktok", ".mp");
-                       f.deleteOnExit();
-                       try (var w = MsgPackTokenWriter.forOutput(f, 
MsgPackTokenWriter.Settings.DEFAULT)) {
-                               w.startArray().number(1).number(2).endArray();
-                       }
-                       assertTrue(f.length() > 0);
-
+                       // The Object-to-OutputStream narrowing (and 
null/illegal-type rejection) lives on the
+                       // session (the Object interface boundary); the writer 
takes a statically-typed OutputStream.
                        assertThrowsWithMessage(IOException.class, "Output 
cannot be null.",
-                               () -> MsgPackTokenWriter.forOutput(null, 
MsgPackTokenWriter.Settings.DEFAULT));
+                               () -> 
MsgPackSerializer.DEFAULT.serializeTokens(null));
                        assertThrowsWithMessage(IOException.class, "Cannot 
convert object of type",
-                               () -> 
MsgPackTokenWriter.forOutput("not-a-stream", 
MsgPackTokenWriter.Settings.DEFAULT));
+                               () -> 
MsgPackSerializer.DEFAULT.serializeTokens("not-a-stream"));
                }
 
                @Test void w03_numberOverloadsRoundTrip() throws Exception {
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/serializer/SerializerSession_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/serializer/SerializerSession_Test.java
index 897bdffa3f..da8a22e657 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/serializer/SerializerSession_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/serializer/SerializerSession_Test.java
@@ -1200,8 +1200,8 @@ class SerializerSession_Test extends TestBase {
                var s = JsonSerializer.DEFAULT.createSession().build();
                var method = 
SerializerSession.class.getDeclaredMethod("createPipe", Object.class);
                method.setAccessible(true);
-               var sb = new StringBuilder();
-               var pipe = method.invoke(s, sb);
+               var sw = new StringWriter();
+               var pipe = method.invoke(s, sw);
                assertNotNull(pipe);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/ArrayRecordStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/ArrayRecordStream_Test.java
index de72d545cd..6e0b0f0c10 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/ArrayRecordStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/ArrayRecordStream_Test.java
@@ -398,7 +398,7 @@ class ArrayRecordStream_Test extends TestBase {
                        }
                        return baos.toByteArray();
                }
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = ((ArrayRecordWritable) 
fmt.serializer).serializeArrayRecords(sb)) {
                        for (var b : beans)
                                w.write(b);
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/MultiRecordStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/MultiRecordStream_Test.java
index 22b9ff0dc0..3715d88bb8 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/MultiRecordStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/MultiRecordStream_Test.java
@@ -19,6 +19,7 @@ package org.apache.juneau.marshall.stream;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.junit.jupiter.api.Assumptions.*;
 
+import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -97,7 +98,7 @@ class MultiRecordStream_Test extends TestBase {
                assumeTrue(fmt != Format.SSE);
 
                var beans = List.of(new Bean("a", 1), new Bean("b", 2), new 
Bean("c", 3));
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = ((RecordWritable) 
fmt.serializer).serializeRecords(sb)) {
                        for (var b : beans)
                                w.write(b);
@@ -128,7 +129,7 @@ class MultiRecordStream_Test extends TestBase {
 
                var beans = List.of(new Bean("a", 1), new Bean("b", 2));
 
-               var streamed = new StringBuilder();
+               var streamed = new StringWriter();
                try (var w = ((RecordWritable) 
fmt.serializer).serializeRecords(streamed)) {
                        for (var b : beans)
                                w.write(b);
@@ -145,7 +146,7 @@ class MultiRecordStream_Test extends TestBase {
 
        @Test
        void d01_sseMultipleEvents() throws Exception {
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = SseSerializer.DEFAULT.serializeRecords(sb)) {
                        w.write(new SseEvent().setEvent("a").setData("1"));
                        w.write(new SseEvent().setEvent("b").setData("2"));
@@ -167,7 +168,7 @@ class MultiRecordStream_Test extends TestBase {
                assumeTrue(fmt.parser != null);
 
                var beans = List.of(new Bean("a", 1), new Bean("b", 2));
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                try (var w = ((RecordWritable) 
fmt.serializer).serializeRecords(sb)) {
                        for (var b : beans)
                                w.write(b);
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/RecordStream_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/RecordStream_Test.java
index 239ae40b26..ba71ff5f49 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/RecordStream_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/RecordStream_Test.java
@@ -600,7 +600,7 @@ class RecordStream_Test extends TestBase {
                        writeAll(fmt, ((RecordWritable) 
fmt.serializer).serializeRecords(baos), value);
                        return 
Base64.getEncoder().encodeToString(baos.toByteArray());
                }
-               var sb = new StringBuilder();
+               var sb = new StringWriter();
                writeAll(fmt, ((RecordWritable) 
fmt.serializer).serializeRecords(sb), value);
                return sb.toString();
        }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/StreamInternals_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/StreamInternals_Test.java
index 65cf863717..699478411e 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/StreamInternals_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshall/stream/StreamInternals_Test.java
@@ -344,7 +344,7 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void b09_arrayWriterBuffersAndEmitsArray() throws 
Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
RecordAdapter.arrayWriter(serializerSession(), sb)) {
                                assertFalse(w.isStreaming());
                                w.write(1);
@@ -355,7 +355,7 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void b10_arrayWriterRejectsWriteAfterClose() throws 
Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        var w = RecordAdapter.arrayWriter(serializerSession(), 
sb);
                        w.close();
                        assertThrowsWithMessage(IllegalStateException.class, 
"Array stream is closed", () -> w.write(1));
@@ -372,7 +372,7 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void b12_writerSingleShot() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = RecordAdapter.writer(serializerSession(), 
sb)) {
                                assertFalse(w.isStreaming());
                                w.write(Map.of("a", 1));
@@ -398,13 +398,13 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void b15_writerWrapsSerializeExceptionAsIOException() 
throws Exception {
-                       try (var w = RecordAdapter.writer(serializerSession(), 
new StringBuilder())) {
+                       try (var w = RecordAdapter.writer(serializerSession(), 
new StringWriter())) {
                                assertThrows(IOException.class, () -> 
w.write(new BadBean()));
                        }
                }
 
                @Test void 
b16_arrayWriterWrapsSerializeExceptionAsIOException() throws Exception {
-                       var w = RecordAdapter.arrayWriter(serializerSession(), 
new StringBuilder());
+                       var w = RecordAdapter.arrayWriter(serializerSession(), 
new StringWriter());
                        w.write(new BadBean());
                        // The buffered serialize happens on close(), wrapping 
the SerializeException as IOException.
                        assertThrows(IOException.class, w::close);
@@ -443,7 +443,7 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void c03_writerStreamsElements() throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        try (var w = 
StreamingArrayRecord.writer(JsonSerializer.DEFAULT.serializeTokens(sb))) {
                                assertTrue(w.isStreaming());
                                w.write(1);
@@ -454,7 +454,7 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void c04_writerRejectsWriteAfterCloseAndIsIdempotent() 
throws Exception {
-                       var sb = new StringBuilder();
+                       var sb = new StringWriter();
                        var w = 
StreamingArrayRecord.writer(JsonSerializer.DEFAULT.serializeTokens(sb));
                        w.write(1);
                        w.close();
@@ -490,10 +490,10 @@ class StreamInternals_Test extends TestBase {
                }
 
                @Test void d04_arrayRecordWritableCountDefaultDelegates() 
throws Exception {
-                       var marker = 
RecordAdapter.writer(JsonSerializer.DEFAULT.getSession(), new StringBuilder());
+                       var marker = 
RecordAdapter.writer(JsonSerializer.DEFAULT.getSession(), new StringWriter());
                        ArrayRecordWritable aw = output -> marker;
                        // The count-prefixed default ignores the count and 
delegates to the 1-arg form.
-                       assertSame(marker, aw.serializeArrayRecords(new 
StringBuilder(), 3));
+                       assertSame(marker, aw.serializeArrayRecords(new 
StringWriter(), 3));
                        assertTrue(aw.isArrayRecordStreaming());
                        marker.close();
                }
diff --git 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshaller/MarshallUtils_Test.java
 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshaller/MarshallUtils_Test.java
index 180d825a8c..aeeacac939 100644
--- 
a/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshaller/MarshallUtils_Test.java
+++ 
b/juneau-core/juneau-marshall/src/test/java/org/apache/juneau/marshaller/MarshallUtils_Test.java
@@ -20,6 +20,7 @@ import static 
org.apache.juneau.marshall.marshaller.MarshallUtils.*;
 import static org.apache.juneau.test.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -112,29 +113,25 @@ class MarshallUtils_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void c01_serializeToWriter_charFormats() throws Exception {
-               var sb = new StringBuilder();
-               json(MAP, sb);
-               assertNotNull(sb.toString());
-               assertTrue(!sb.isEmpty());
-
-               sb.setLength(0); json5(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); jsonl(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); jcs(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); hjson(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); xml(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); html(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); uon(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); urlEncoding(MAP, sb); 
assertTrue(!sb.isEmpty());
-               sb.setLength(0); yaml(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); csv("foo", sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); openApi(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); plainText(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); markdown(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); markdownDoc(MAP, sb); 
assertTrue(!sb.isEmpty());
-               sb.setLength(0); ini(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); toml(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); hocon(MAP, sb); assertTrue(!sb.isEmpty());
-               sb.setLength(0); proto(MAP, sb); assertTrue(!sb.isEmpty());
+               assertFalse(json(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(json5(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(jsonl(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(jcs(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(hjson(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(xml(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(html(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(uon(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(urlEncoding(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(yaml(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(csv("foo", new 
StringWriter()).toString().isEmpty());
+               assertFalse(openApi(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(plainText(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(markdown(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(markdownDoc(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(ini(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(toml(MAP, new StringWriter()).toString().isEmpty());
+               assertFalse(hocon(MAP, new 
StringWriter()).toString().isEmpty());
+               assertFalse(proto(MAP, new 
StringWriter()).toString().isEmpty());
        }
 
        @Test void c02_serializeToOutputStream_binaryFormats() throws Exception 
{
@@ -215,19 +212,19 @@ class MarshallUtils_Test extends TestBase {
 
        @Test void e04_parseStringClass_iniTomlHoconProto() throws Exception {
                // These require Map root.
-               var iniStr = ini(new A04_Bean(), new 
StringBuilder()).toString();
+               var iniStr = ini(new A04_Bean(), new StringWriter()).toString();
                var iniParsed = MarshallUtils.<JsonMap>ini(iniStr, 
JsonMap.class);
                assertNotNull(iniParsed);
 
-               var tomlStr = toml(new A04_Bean(), new 
StringBuilder()).toString();
+               var tomlStr = toml(new A04_Bean(), new 
StringWriter()).toString();
                var tomlParsed = MarshallUtils.<JsonMap>toml(tomlStr, 
JsonMap.class);
                assertNotNull(tomlParsed);
 
-               var hoconStr = hocon(new A04_Bean(), new 
StringBuilder()).toString();
+               var hoconStr = hocon(new A04_Bean(), new 
StringWriter()).toString();
                var hoconParsed = MarshallUtils.<JsonMap>hocon(hoconStr, 
JsonMap.class);
                assertNotNull(hoconParsed);
 
-               var protoStr = proto(new A04_Bean(), new 
StringBuilder()).toString();
+               var protoStr = proto(new A04_Bean(), new 
StringWriter()).toString();
                var protoParsed = MarshallUtils.<JsonMap>proto(protoStr, 
JsonMap.class);
                assertNotNull(protoParsed);
        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/vars/SerializedRequestAttrVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/vars/SerializedRequestAttrVar.java
index b3c0b20da1..6a723b3e02 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/vars/SerializedRequestAttrVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/vars/SerializedRequestAttrVar.java
@@ -70,7 +70,7 @@ public class SerializedRequestAttrVar extends StreamedVar {
                var o = req.getAttribute(key).orElse(key);
                Serializer s = 
req.getOpContext().getSerializers().getSerializer(s2[0]).orElse(null);
                if (nn(s))
-                       s.serialize(w, o);
+                       s.serialize(o, w);
        }
 
        @Override /* Overridden from Var */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/widget/MenuItemWidget.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/widget/MenuItemWidget.java
index d57fc3917a..79cc8940fb 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/widget/MenuItemWidget.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/server/widget/MenuItemWidget.java
@@ -177,8 +177,8 @@ public abstract class MenuItemWidget extends Widget {
                                .build();
                        // @formatter:on
                        session.indent = 2;
-                       try {
-                               session.serialize(o, sb);
+                       try (Writer w = new StringBuilderWriter(sb)) {
+                               session.serialize(o, w);
                        } catch (Exception e) {
                                throw toRex(e);
                        }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/server/vars/RestServerVars_Test.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/server/vars/RestServerVars_Test.java
index ec769b1df3..72f39ba2e7 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/server/vars/RestServerVars_Test.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/server/vars/RestServerVars_Test.java
@@ -385,17 +385,15 @@ class RestServerVars_Test extends TestBase {
 
        @Test void e06_serializedRequestAttrVar_resolveTo_serializerFound() 
throws Exception {
                // Serializer.serialize(Object,Object) is final so we use a 
real serializer (Json5).
-               // The production code calls s.serialize(w, o) where w is the 
Writer and o is the attribute
-               // value used as the output destination; we supply a 
StringBuilder so the serializer has a
-               // valid output target and can write successfully.
+               // The attribute value is serialized into the var-resolution 
Writer.
                var req = mock(RestRequest.class, RETURNS_DEEP_STUBS);
-               var outputSb = new StringBuilder();
                var attr = mock(RequestAttribute.class);
-               when(attr.orElse(any())).thenReturn(outputSb);
+               when(attr.orElse(any())).thenReturn("myValue");
                when(req.getAttribute(any())).thenReturn(attr);
                
when(req.getOpContext().getSerializers().getSerializer(any(String.class))).thenReturn(Optional.of(Json5Serializer.DEFAULT));
-               new SerializedRequestAttrVar().resolveTo(sessionWith(req), new 
StringWriter(), "application/json,myKey");
-               assertFalse(outputSb.toString().isEmpty());
+               var w = new StringWriter();
+               new SerializedRequestAttrVar().resolveTo(sessionWith(req), w, 
"application/json,myKey");
+               assertTrue(w.toString().contains("myValue"));
        }
 
        // 
-----------------------------------------------------------------------------------------

Reply via email to