From fded12912f75fec3713021ae3bcf0f57d1e3f74e Mon Sep 17 00:00:00 2001 From: liferoad Date: Tue, 10 Mar 2026 20:49:22 -0400 Subject: [PATCH 1/2] Fix #21317: Replace colons with underscores in window filenames for Windows compatibility The default FilenamePolicy uses Instant.toString() for Beam Windows, which produces ISO-8601 format (e.g., 2021-12-31T23:00:00.000Z) containing colons. Colons are illegal characters in Windows file paths, causing InvalidPathException when using TextIO.write().withWindowedWrites() on Windows. This fix replaces colons with underscores ONLY on Windows to ensure cross-platform compatibility without breaking existing filenames on other OSes. Fixes #21317 --- .../org/apache/beam/sdk/io/DefaultFilenamePolicy.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java index 77e667e88ee7..63ef614a13f6 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java @@ -353,7 +353,15 @@ private String windowToString(BoundedWindow window) { } if (window instanceof IntervalWindow) { IntervalWindow iw = (IntervalWindow) window; - return String.format("%s-%s", iw.start().toString(), iw.end().toString()); + // Use ISO-8601 format but replace colons with underscores for Windows compatibility + // since colons are illegal characters in Windows file paths. + String startStr = iw.start().toString(); + String endStr = iw.end().toString(); + if (System.getProperty("os.name").startsWith("Windows")) { + startStr = startStr.replace(':', '_'); + endStr = endStr.replace(':', '_'); + } + return String.format("%s-%s", startStr, endStr); } return window.toString(); } From d91be41be358bada2bd7cb09aa73b3c79bb6c440 Mon Sep 17 00:00:00 2001 From: liferoad Date: Wed, 11 Mar 2026 20:22:08 -0400 Subject: [PATCH 2/2] fix: Add null check for the `os.name` system property before checking for Windows. --- .../java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java index 63ef614a13f6..1573a34c8840 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DefaultFilenamePolicy.java @@ -357,7 +357,8 @@ private String windowToString(BoundedWindow window) { // since colons are illegal characters in Windows file paths. String startStr = iw.start().toString(); String endStr = iw.end().toString(); - if (System.getProperty("os.name").startsWith("Windows")) { + String osName = System.getProperty("os.name"); + if (osName != null && osName.startsWith("Windows")) { startStr = startStr.replace(':', '_'); endStr = endStr.replace(':', '_'); }