Cameleer

Java language

The java language (also joor) evaluates Java snippets against the message, with exchange, message and body available as variables.

Name: java · Also: joor · Crate: cameleer-script · Cargo feature: script · Apache Camel: Java, jOOR

When to use it

  • Reuse Java snippets from existing Camel java/joor expressions.
  • Write a transformation with streams, String.format or java.time when the team thinks in Java.

Syntax

Apache Camel compiles these snippets with the JDK at startup. Cameleer interprets them instead: there is no JDK, no compiler and no classpath. The snippet is Java syntax evaluated with Java semantics (integer division, ArithmeticException, Java toString): typed locals and var, casts, if/for/while/switch (also switch expressions and type patterns), lambdas, method references, text blocks, classes, records and enums declared in the snippet, try/catch, and the common JDK API (String, Math, List/Map/Set, Arrays, Collections, Optional, streams and Collectors, java.time). Not available: other JDK or third-party classes, reflection, threads, and compile-time checks (generics are not checked).

A single expression is its own result; a snippet with statements ends with return.

Variables and helpers:

namewhat it is
exchangethe exchange (exchange.getIn(), exchange.getMessage(), exchange.setProperty(..))
messagethe message (message.getHeader("x"), message.getHeader("x", String.class), message.setBody(..))
bodythe message body (cast it: ((String) body))
optionalBodythe body as an Optional
bodyAs(Type.class)the body converted to a type
header(name), headerAs(name, Type.class)a header
exchangeProperty(name), variable(name)a property, a variable

Examples

Format a summary with streams

yaml example: java-stream-summary
- route:
    id: java-summary
    from:
      uri: direct:java-summary
      steps:
        - setBody:
            java: |
              var parts = ((String) body).split(",");
              int total = Arrays.stream(parts).mapToInt(p -> Integer.parseInt(p.trim())).sum();
              return String.format("%d readings, total %d", parts.length, total);
text
4, 8, 15, 16
text
4 readings, total 43

A script step that sets a header

yaml example: java-script-step
- route:
    id: java-script
    from:
      uri: direct:java-script
      steps:
        - script:
            joor: |
              exchange.getMessage().setHeader("len", body.toString().length());
              message.setBody(((String) body).toUpperCase());
        - setBody:
            simple: "${body}/${header.len}"
text
camel
text
CAMEL/5

Expressions

json
{"body": "hello", "headers": {"amount": 250, "name": "Ada"}}
expressionresult
((String) body).toUpperCase()HELLO
message.getHeader("name")Ada
"Hi " + message.getHeader("name", String.class)Hi Ada
var n = (Integer) message.getHeader("amount"); return n > 100;true
exchange.getIn().getBody(String.class).substring(1)ello
7 / 23

Options

optiondefaultdescription
resultType(none)Convert the result to this type.

Rust DSL

rust
b.from("direct:java-rust")
    .set_body(cameleer_script::joor("((String) body).length() * 2"));

Common questions

Is my Java code compiled?

No. It is parsed and interpreted at route start, so a syntax error fails the route at startup, but type errors (wrong generics, missing returns) are not reported.

What is the difference between java and joor?

None in Cameleer: both names select the same interpreter. Camel 4 renamed joor to java.

Found a problem?

If something on this page doesn't match what Cameleer does, or you hit a bug while building with it, please help fix it, whether you are a person or a coding agent: open an issue that describes what you saw, then fork the repository, fix it, add or update a test, run cargo test --workspace, and open a pull request. CONTRIBUTING.md explains the ground rules.

Edit this page on GitHub