shashank created CAMEL-25218:
--------------------------------

             Summary: camel-jsonpath - jsonpath on a file from the ftp or ftps 
consumer with the charset option fails with ClassCastException (FTPFile cannot 
be cast to java.io.File)
                 Key: CAMEL-25218
                 URL: https://issues.apache.org/jira/browse/CAMEL-25218
             Project: Camel
          Issue Type: Bug
          Components: camel-jsonpath
            Reporter: shashank


{{JsonPathEngine.doRead}} has a special case for a {{GenericFile}} with a 
charset:

{code:java}
} else if (json instanceof GenericFile) {
    GenericFile<?> genericFile = (GenericFile<?>) json;
    if (genericFile.getCharset() != null) {
        // special treatment for generic file with charset
        InputStream inputStream = new FileInputStream((File) 
genericFile.getFile());
        return JsonPath.using(configuration).parse(inputStream, 
genericFile.getCharset()).read(path);
    }
}
{code}

The cast assumes the file consumer. The ftp and ftps consumers also set the 
endpoint {{charset}} on the {{RemoteFile}} they create 
({{FtpConsumer.asRemoteFile}}: {{answer.setCharset(charset)}}), but its file is 
an {{org.apache.commons.net.ftp.FTPFile}}, and the content is in the body. So 
every jsonpath expression on such a message fails:

{noformat}
org.apache.camel.ExpressionEvaluationException: java.lang.ClassCastException: 
class org.apache.commons.net.ftp.FTPFile cannot be cast to class java.io.File
{noformat}

for example 
{{from("ftp://host/inbox?charset=ISO-8859-1";).split().jsonpath("$.orders[*]")}}.
 Without the charset option the same route works (the body is read as a stream 
and its encoding detected), but then a file in a charset other than UTF-8/16/32 
is decoded wrongly, which is why the option is set.

h3. Reproduction

A unit test sends a {{GenericFile}} whose file is not a {{java.io.File}} 
(standing in for {{FTPFile}}, as camel-jsonpath has no camel-ftp dependency), 
with the charset set and the JSON content in the body, to 
{{transform().jsonpath("$.store.book[0].title", String.class)}}: on main it 
fails with {{ClassCastException}} for UTF-8 and for ISO-8859-1; the control 
without a charset passes. The same with a real {{RemoteFile<FTPFile>}} built as 
{{FtpConsumer.asRemoteFile}} does gives the {{FTPFile cannot be cast to class 
java.io.File}} error above. The code is the same in 3.0.0, 4.0.0, 4.14.0, 
4.18.0 and 4.22.0.

h3. Proposed fix

Open the stream by the kind of file:

{code:java}
if (genericFile.getCharset() != null) {
    // special treatment for generic file with charset: a remote file (such as 
from the ftp consumer) is
    // not a java.io.File, and its content is the body of the generic file
    InputStream inputStream = genericFile.getFile() instanceof File file
            ? new FileInputStream(file)
            : 
exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, 
exchange, genericFile);
    if (inputStream != null) {
        // json-path closes the stream
        return JsonPath.using(configuration).parse(inputStream, 
genericFile.getCharset()).read(path);
    }
}
{code}

A local file is read exactly as before ({{JsonPath.parse(InputStream, String)}} 
closes the stream itself, so there is no leak there). For a remote file the 
{{GenericFile}} type converter gives the raw bytes of the body (loading it 
through the binding if needed), which are parsed in the consumer charset. With 
the fix the new test and the whole camel-jsonpath suite pass (133 tests, 
camel-core built from the same commit).

Duplicate check (2026-09-30): JIRA "jsonpath" with "GenericFile", "ftp", 
"ClassCastException" or "charset": CAMEL-8346, CAMEL-8905 (both fixed in 2.x, 
file consumer only). No pull request about it.

_Filed with Claude Code on behalf of allthingssecurity._




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to