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)