Java Code
Summary
- Internal name:
JavaCode - Category: System
- Purpose: Execute inline Java code using a BeanShell scripting interpreter directly on the Android device.
- Task type: Normal
Compatibility
-
Minimum AndroMate version:
1.1.0 -
Maximum AndroMate version:
1.1.0 -
Minimum Android:
Android 13 (API 33) -
Maximum Android tested:
Android 16 (API 36) -
Supported manufacturers:
- Samsung (One UI 6.x / 7.x / 8.x)
- Other manufacturers - not supported yet (Xiaomi HyperOS and Google Pixel are being adapted)
-
Required permissions:
- None
Detailed description
The Java Code task executes inline Java code at runtime using BeanShell - a lightweight Java scripting engine that supports standard Java syntax. Code runs directly on the Android device inside the AndroMate process.
It is used to:
- Perform custom computations not available through built-in tasks
- Manipulate strings, numbers, and data structures
- Implement conditional logic or loops inside a single task
- Process results from previous tasks before passing them further
- Debug and inspect values during workflow development
The task handles:
- injecting workflow variables into the BeanShell interpreter scope via Set Variable entries,
- executing Java code blocks via Code entries,
- copying a BeanShell variable back into a workflow variable via Get Variable entries,
- intercepting
System.out.println()and forwarding output to the AndroMate execution console, - intercepting
System.err.println()and forwarding it as an error message in the console, - stripping
//and/* */comments before execution, - splitting code into balanced brace blocks and evaluating them sequentially.
Note:
System.out.println("...")messages written inside your BeanShell code are captured and displayed in the AndroMate execution console in real time. This is useful for debugging variable values or tracing execution flow.
How BeanShell works
BeanShell is a Java-compatible scripting engine. It supports:
- Standard Java syntax (variables, loops, conditionals, method calls)
- Java standard library classes (
String,Math,Integer,ArrayList, etc.) - Dynamic typing (no need to declare variable types explicitly)
- Multi-line code with balanced braces
{ }
Important limitations:
- No access to Android APIs (e.g., Context, Activity)
- No file system or network access from within the script
- Each JavaCode task runs in its own interpreter scope - variables do not persist between separate JavaCode tasks
Entry types
The javaCodeEntries array defines a sequence of operations executed in order. There are three entry types:
Entry type 1 - Set Variable
Injects a value into the BeanShell interpreter scope so it can be used inside subsequent Code entries.
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Set Variable" |
variableName |
String | Yes | Name of the variable in the BeanShell scope |
value |
String | Yes | Value to inject - can be a $workflow_variable reference |
Type resolution: The value string is automatically parsed to the most specific numeric type (Integer -> Long -> Float -> String).
Entry type 2 - Code
Executes a BeanShell Java code block.
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Code" |
code |
String | Yes | The BeanShell Java code to execute |
Entry type 3 - Get Variable
Reads a BeanShell variable (created by a previous Code entry) and stores its value in a workflow variable. It is the reverse of Set Variable.
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Get Variable" |
variableName |
String | Yes | Name of the variable in the BeanShell scope to read (no $ prefix) |
targetVariable_output |
String | Yes | Workflow variable that receives the value - must be a workflow variable name such as $result |
Order matters: entries run in sequence, so a Get Variable entry must come after the Code entry that creates the variable.
Value conversion: numbers, booleans and strings are stored as text; lists and arrays as a JSON array; maps as a JSON object.
targetVariable_outputholds the name of the variable to fill, so$resultis never replaced by its current value before execution.
Input parameters
| Parameter | Type | Required | Possible values | Android Compatibility | AndroMate Compatibility | Default |
|---|---|---|---|---|---|---|
javaCodeEntries |
Array | Yes | Ordered array of "Set Variable", "Code" and/or "Get Variable" entry objects - see Entry types section |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | [] |
Output parameters
This task returns VoidResult. Workflow variables are written only by Get Variable entries, into the variable named in targetVariable_output.
| Field | Type | Trigger condition | Default |
|---|---|---|---|
| - | VoidResult | Always | - |
To pass values out of BeanShell into the workflow, compute them in a Code entry, then add a Get Variable entry after it. BeanShell variables do not automatically update workflow context variables.
Exceptions
| Code | Exception Name | Description |
|---|---|---|
JAVA-CODE-ERROR-001 |
Unsupported Variable Type | The value provided in a Set Variable entry cannot be mapped to a supported type (int, long, float, String). |
JAVA-CODE-ERROR-003 |
Missing Variable Name or Value | A Set Variable entry is missing the variableName or value field. |
JAVA-CODE-ERROR-004 |
Missing Code Field | A Code entry is missing the code field. |
JAVA-CODE-ERROR-005 |
Malformed JSON Entry | One of the entries in javaCodeEntries contains malformed JSON. |
JAVA-CODE-ERROR-006 |
Unsupported Entry Type | An entry has an unknown type value - only "Code", "Set Variable" and "Get Variable" are supported. |
JAVA-CODE-ERROR-007 |
BeanShell Eval Error | The BeanShell interpreter failed to evaluate the code - syntax error, undefined variable, or runtime exception inside the script. |
JAVA-CODE-ERROR-008 |
Missing Get Variable Fields | A Get Variable entry is missing variableName or targetVariable_output. |
JAVA-CODE-ERROR-009 |
Java Variable Not Found | The BeanShell variable read by a Get Variable entry is not defined - run the Code entry that creates it before this entry. |
JAVA-CODE-ERROR-010 |
Invalid Output Variable | targetVariable_output is not a valid workflow variable name (for example $result). |
ERROR-000 |
Other Error | An unexpected runtime error occurred during execution. |
Execution flowchart
flowchart TD
Start([Start JavaCodeTask]) --> ReadEntries[Read javaCodeEntries array]
ReadEntries --> Loop{For each entry}
Loop --> CheckType{entry type ?}
CheckType -->|Set Variable| ValidateSetVar{variableName\n+ value present ?}
ValidateSetVar -->|No| E3[JAVA-CODE-ERROR-003]
ValidateSetVar -->|Yes| ParseType[Auto-parse value\nInt -> Long -> Float -> String]
ParseType --> InjectVar[Inject variable\ninto BeanShell scope]
InjectVar --> Loop
CheckType -->|Code| ValidateCode{code field\npresent ?}
ValidateCode -->|No| E4[JAVA-CODE-ERROR-004]
ValidateCode -->|Yes| StripComments[Strip // and /* */ comments]
StripComments --> SplitBlocks[Split into\nbalanced brace blocks]
SplitBlocks --> Eval[BeanShell eval\neach block]
Eval -->|EvalError| E7[JAVA-CODE-ERROR-007]
Eval -->|stdout| Console[System.out -> AndroMate Console]
Eval -->|stderr| ConsoleErr[System.err -> AndroMate Console]
Eval -->|Success| Loop
CheckType -->|Get Variable| ValidateGetVar{variableName + targetVariable_output\npresent and valid ?}
ValidateGetVar -->|No| E8[JAVA-CODE-ERROR-008 / 010]
ValidateGetVar -->|Yes| ReadVar[Read variable\nfrom BeanShell scope]
ReadVar -->|Undefined| E9[JAVA-CODE-ERROR-009]
ReadVar -->|Found| StoreVar[Store in workflow\nvariable]
StoreVar --> Loop
CheckType -->|Unknown| E6[JAVA-CODE-ERROR-006]
Loop -->|All entries done| Success([VoidResult])
E3 --> Error([Exception])
E4 --> Error
E6 --> Error
E7 --> Error
E8 --> Error
E9 --> Error
style Start fill:#e3f2fd
style Success fill:#c8e6c9
style Error fill:#ffcdd2
style ParseType fill:#fff9c4
style StripComments fill:#fff9c4
style SplitBlocks fill:#fff9c4
style Eval fill:#f3e5f5
style Console fill:#c8e6c9
style ConsoleErr fill:#ffe0e0
style InjectVar fill:#c8e6c9
style E3 fill:#ffcdd2
style E4 fill:#ffcdd2
style E6 fill:#ffcdd2
style E7 fill:#ffcdd2
How it works:
- Read entries: Loads the
javaCodeEntriesarray - For each entry - processes in order:
- Set Variable: validates fields -> auto-parses value type -> injects into BeanShell scope
- Code: strips comments -> splits into brace-balanced blocks -> evaluates each block
- Get Variable: validates fields -> reads the BeanShell variable -> stores it in the workflow variable
- Console output:
System.out.println()is intercepted and shown in the AndroMate console;System.erris shown as an error - Result: Returns
VoidResulton success
Code examples
Example 1 - Basic arithmetic and console output
{
"JavaCode": [
{
"id": "1",
"title": "Java Code",
"javaCodeEntries": [
{
"type": "Code",
"code": "int a = 10;\nint b = 20;\nint result = a + b;\nSystem.out.println(\"Result: \" + result);"
}
]
}
]
}
System.out.printlnoutput:Result: 30- visible in the AndroMate execution console.
Example 2 - Inject a workflow variable, compute, print
{
"JavaCode": [
{
"id": "2",
"title": "Java Code",
"javaCodeEntries": [
{
"type": "Set Variable",
"variableName": "rttMs",
"value": "$ntp_rtt"
},
{
"type": "Code",
"code": "double rttSec = rttMs / 1000.0;\nSystem.out.println(\"RTT in seconds: \" + rttSec);"
}
]
}
]
}
Example 3 - String manipulation
{
"JavaCode": [
{
"id": "3",
"title": "Java Code",
"javaCodeEntries": [
{
"type": "Set Variable",
"variableName": "rawOutput",
"value": "$cmd_result"
},
{
"type": "Code",
"code": "String trimmed = rawOutput.trim();\nboolean contains = trimmed.contains(\"unreachable\");\nSystem.out.println(\"Contains unreachable: \" + contains);"
}
]
}
]
}
Example 4 - Conditional logic with console trace
{
"JavaCode": [
{
"id": "4",
"title": "Java Code",
"javaCodeEntries": [
{
"type": "Set Variable",
"variableName": "httpStatus",
"value": "$http_status"
},
{
"type": "Code",
"code": "if (httpStatus == 200) {\n System.out.println(\"[OK] Request succeeded\");\n} else {\n System.err.println(\"[ERROR] Unexpected status: \" + httpStatus);\n}"
}
]
}
]
}
Example 5 - Loop and accumulation
{
"JavaCode": [
{
"id": "5",
"title": "Java Code",
"javaCodeEntries": [
{
"type": "Code",
"code": "int sum = 0;\nfor (int i = 1; i <= 5; i++) {\n sum += i;\n System.out.println(\"Step \" + i + \" -> sum = \" + sum);\n}\nSystem.out.println(\"Final sum: \" + sum);"
}
]
}
]
}
Input parameter details
1. Input parameter: javaCodeEntries
An ordered JSON array of entry objects executed sequentially. There are three entry types:
Entry type: "Set Variable"
Injects a workflow variable value into the BeanShell interpreter scope.
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Set Variable" |
variableName |
String | Yes | Name of the variable in BeanShell scope (no $ prefix) |
value |
String | Yes | Value to inject - supports $workflow_variable references |
Type auto-resolution: the string value is automatically parsed in order: Integer -> Long -> Float -> String. The resolved Java type is what BeanShell sees.
Entry type: "Code"
Executes a BeanShell Java code block.
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Code" |
code |
String | Yes | Java code to execute - multi-line supported |
Execution pipeline:
1. // and /* */ comments are stripped
2. Code is split into balanced brace blocks { }
3. Each block is evaluated sequentially by the BeanShell interpreter
4. System.out.println() -> forwarded to the AndroMate execution console
5. System.err.println() -> forwarded as an error in the console
Entry type: "Get Variable"
Copies a BeanShell variable into a workflow variable (reverse of Set Variable).
| Field | Type | Required | Description |
|---|---|---|---|
type |
String | Yes | Must be "Get Variable" |
variableName |
String | Yes | Name of the BeanShell variable to read (no $ prefix) |
targetVariable_output |
String | Yes | Workflow variable that receives the value, e.g. $result |
Rules:
1. Must come after the Code entry that defines the variable
2. targetVariable_output must be a workflow variable name ($name); it is used as a name and is never replaced by its current value
3. Lists/arrays are stored as a JSON array, maps as a JSON object, everything else as text
- Default:
[](empty array - task is a no-op)
Complete JSON example
{
"JavaCode": [
{
"id": "1",
"title": "Compute RTT statistics",
"javaCodeEntries": [
{
"type": "Set Variable",
"variableName": "rttMs",
"value": "$ntp_rtt"
},
{
"type": "Set Variable",
"variableName": "threshold",
"value": "200"
},
{
"type": "Code",
"code": "double rttSec = rttMs / 1000.0;\nSystem.out.println(\"RTT: \" + rttMs + \" ms (\" + rttSec + \" s)\");\nif (rttMs <= threshold) {\n System.out.println(\"RTT within acceptable range\");\n} else {\n System.err.println(\"RTT too high: \" + rttMs + \" ms\");\n}"
},
{
"type": "Get Variable",
"variableName": "rttSec",
"targetVariable_output": "$rtt_seconds"
}
]
}
]
}