This is an automated email from the ASF dual-hosted git repository.
Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 8e285fd0fa9f CAMEL-26644: Normalize file component path separators for
getFile/directory consistency (#29250)
8e285fd0fa9f is described below
commit 8e285fd0fa9f96ef876e9a6ab042831786768665
Author: Salvatore Mongiardo <[email protected]>
AuthorDate: Thu Nov 5 19:22:13 2026 +0100
CAMEL-26644: Normalize file component path separators for getFile/directory
consistency (#29250)
On Linux/macOS, a backslash in the file: URI path (e.g. file:target\subdir)
was preserved by getFile() but normalized to / by
getConfiguration().getDirectory(),
causing the producer to create a spurious backslash-named directory and the
consumer
to miss files. Apply FileUtil.normalizePath(remaining) in
FileComponent.buildFileEndpoint()
so getFile().getPath() and getDirectory() return consistent values on all
platforms.
---
.../apache/camel/component/file/FileComponent.java | 2 +
.../file/FileComponentPathSeparatorTest.java | 86 ++++++++++++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 9 +++
3 files changed, 97 insertions(+)
diff --git
a/components/camel-file/src/main/java/org/apache/camel/component/file/FileComponent.java
b/components/camel-file/src/main/java/org/apache/camel/component/file/FileComponent.java
index 67df9131f7c0..c002a75729f3 100644
---
a/components/camel-file/src/main/java/org/apache/camel/component/file/FileComponent.java
+++
b/components/camel-file/src/main/java/org/apache/camel/component/file/FileComponent.java
@@ -57,6 +57,8 @@ public class FileComponent extends GenericFileComponent<File>
{
+ " Use the fileName option to
set the dynamic expression.");
}
+ remaining = FileUtil.normalizePath(remaining);
+
File file = new File(remaining);
FileEndpoint result = new FileEndpoint(uri, this);
diff --git
a/components/camel-file/src/test/java/org/apache/camel/component/file/FileComponentPathSeparatorTest.java
b/components/camel-file/src/test/java/org/apache/camel/component/file/FileComponentPathSeparatorTest.java
new file mode 100644
index 000000000000..1a9c0bb0fe18
--- /dev/null
+++
b/components/camel-file/src/test/java/org/apache/camel/component/file/FileComponentPathSeparatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import java.util.HashMap;
+
+import org.apache.camel.util.FileUtil;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class FileComponentPathSeparatorTest {
+
+ @Test
+ public void shouldNormalizeBackslashesInAbsolutePath() throws Exception {
+ FileComponent component = new FileComponent();
+ FileEndpoint endpoint = (FileEndpoint) component.buildFileEndpoint(
+ "file:C:\\Users\\test\\target", "C:\\Users\\test\\target", new
HashMap<>());
+
+ String directory = endpoint.getConfiguration().getDirectory();
+ String filePath = endpoint.getFile().getPath();
+
+ String expected = FileUtil.normalizePath("C:/Users/test/target");
+ assertEquals(expected, directory);
+ assertEquals(expected, filePath);
+ }
+
+ @Test
+ public void shouldNormalizeBackslashesInRelativePath() throws Exception {
+ FileComponent component = new FileComponent();
+ FileEndpoint endpoint = (FileEndpoint) component.buildFileEndpoint(
+ "file:target\\subdir", "target\\subdir", new HashMap<>());
+
+ String directory = endpoint.getConfiguration().getDirectory();
+ String filePath = endpoint.getFile().getPath();
+
+ String expected = FileUtil.normalizePath("target/subdir");
+ assertEquals(expected, directory);
+ assertEquals(expected, filePath);
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ public void shouldPreserveForwardSlashPaths() throws Exception {
+ FileComponent component = new FileComponent();
+ FileEndpoint endpoint = (FileEndpoint) component.buildFileEndpoint(
+ "file:/home/user/target", "/home/user/target", new
HashMap<>());
+
+ String directory = endpoint.getConfiguration().getDirectory();
+ String filePath = endpoint.getFile().getPath();
+
+ String expected = FileUtil.normalizePath("/home/user/target");
+ assertEquals(expected, directory);
+ assertEquals(expected, filePath);
+ }
+
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ public void shouldNormalizePosixBackslashOnNonWindows() throws Exception {
+ FileComponent component = new FileComponent();
+ FileEndpoint endpoint = (FileEndpoint) component.buildFileEndpoint(
+ "file:/tmp/a\\b", "/tmp/a\\b", new HashMap<>());
+
+ String directory = endpoint.getConfiguration().getDirectory();
+ String filePath = endpoint.getFile().getPath();
+
+ assertEquals("/tmp/a/b", directory);
+ assertEquals("/tmp/a/b", filePath);
+ }
+}
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 9a115537a237..8d76abb015b2 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -1618,6 +1618,15 @@ as soon as the encoding changed a byte, a body read with
another charset (such a
characters. The checksum is now calculated from the bytes written to the file,
and the body is decoded as it is
without `checksumFileAlgorithm`. Checksums of such files differ from the ones
written before.
+=== camel-file - path separator normalization for getFile/directory consistency
+
+On Linux and macOS, a backslash in the `file:` URI path (e.g.
`file:target\subdir`) is now normalized
+to a forward slash, so that `getFile().getPath()` and
`getConfiguration().getDirectory()` return the
+same value. Previously, `getFile()` preserved the backslash while
`getDirectory()` replaced it with `/`,
+which could cause the producer to create a spurious directory with a backslash
in its name and the
+consumer to miss files in a backslash-named directory. On Windows, where
`java.io.File` already
+normalizes both separators to `\`, this change has no effect.
+
=== camel-flatpack - with splitRows each message has its own row, and a
failing row fails the producer
With `splitRows=true` (the default), every row message shared the one parsed
`DataSet`, so the next row moved the row