From d28474039aaee53b4302b99ad25adcde0ba5f7ba Mon Sep 17 00:00:00 2001 From: lenamonj Date: Mon, 7 Sep 2026 18:14:26 -0400 Subject: [PATCH] Fix FileWriterWithEncoding.Builder ignoring any Charset but the default The builder seeded its CharsetEncoder from the default Charset and threw IllegalStateException when the Charset and the encoder disagreed, so both setCharset and setCharsetEncoder failed for anything but the platform default. Keep the pair consistent the way ReaderInputStream.Builder does: setCharset refreshes the encoder and setCharsetEncoder sets the Charset. The mismatch guard has nothing left to catch and is removed. The class Javadoc's Charset example passed a Charset to setCharsetEncoder, which does not compile; it now calls setCharset. --- .../io/output/FileWriterWithEncoding.java | 15 ++++++++---- .../io/output/FileWriterWithEncodingTest.java | 24 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java index de19d2af135..f0e32594c83 100644 --- a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java +++ b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java @@ -73,7 +73,7 @@ public class FileWriterWithEncoding extends ProxyWriter { * FileWriterWithEncoding w = FileWriterWithEncoding.builder() * .setPath(path) * .setAppend(false) - * .setCharsetEncoder(StandardCharsets.UTF_8) + * .setCharset(StandardCharsets.UTF_8) * .get();} * * @@ -125,9 +125,6 @@ public FileWriterWithEncoding get() throws IOException { } private Object getEncoder() { - if (charsetEncoder != null && getCharset() != null && !charsetEncoder.charset().equals(getCharset())) { - throw new IllegalStateException(String.format("Mismatched Charset(%s) and CharsetEncoder(%s)", getCharset(), charsetEncoder.charset())); - } return charsetEncoder != null ? charsetEncoder : getCharset(); } @@ -142,6 +139,13 @@ public Builder setAppend(final boolean append) { return this; } + @Override + public Builder setCharset(final Charset charset) { + super.setCharset(charset); + charsetEncoder = getCharset().newEncoder(); + return this; + } + /** * Sets charsetEncoder to use for encoding. * @@ -150,6 +154,9 @@ public Builder setAppend(final boolean append) { */ public Builder setCharsetEncoder(final CharsetEncoder charsetEncoder) { this.charsetEncoder = charsetEncoder; + if (charsetEncoder != null) { + super.setCharset(charsetEncoder.charset()); + } return this; } diff --git a/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java b/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java index a0d644d8d7d..a425e38d6b7 100644 --- a/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java +++ b/src/test/java/org/apache/commons/io/output/FileWriterWithEncodingTest.java @@ -17,6 +17,7 @@ package org.apache.commons.io.output; import static org.apache.commons.io.test.TestUtils.checkFile; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -32,6 +33,7 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -42,6 +44,8 @@ */ class FileWriterWithEncodingTest { + private static final String NON_ASCII = "caf\u00e9"; + @TempDir public File temporaryFolder; @@ -204,6 +208,26 @@ void testDifferentEncoding() throws Exception { } } + @Test + void testBuilder_nonDefaultCharset() throws Exception { + for (final Charset charset : Arrays.asList(StandardCharsets.UTF_16, StandardCharsets.ISO_8859_1)) { + try (Writer writer = FileWriterWithEncoding.builder().setFile(file2).setCharset(charset).get()) { + writer.write(NON_ASCII); + } + assertArrayEquals(NON_ASCII.getBytes(charset), Files.readAllBytes(file2.toPath())); + } + } + + @Test + void testBuilder_nonDefaultCharsetEncoder() throws Exception { + for (final Charset charset : Arrays.asList(StandardCharsets.UTF_16, StandardCharsets.ISO_8859_1)) { + try (Writer writer = FileWriterWithEncoding.builder().setFile(file2).setCharsetEncoder(charset.newEncoder()).get()) { + writer.write(NON_ASCII); + } + assertArrayEquals(NON_ASCII.getBytes(charset), Files.readAllBytes(file2.toPath())); + } + } + @Test void testSameEncoding_Charset_constructor() throws Exception { try (FileWriterWithEncoding writer = new FileWriterWithEncoding(file2, Charset.defaultCharset())) {