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)
- ✅ Google Pixel (Android Stock)
- ⚠️ Other manufacturers — not tested
-
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,
- 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 two 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 |
Input parameters
| Parameter | Type | Required | Possible values | Android Compatibility | AndroMate Compatibility | Default |
|---|---|---|---|---|---|---|
javaCodeEntries |
Array | Yes | Ordered array of "Set Variable" and/or "Code" entry objects — see Entry types section |
Android 13 (API 33) → Android 16 (API 36) | 1.1.0 → 1.1.0 | [] |
Output parameters
This task produces no output variables. It returns VoidResult.
| Field | Type | Trigger condition | Default |
|---|---|---|---|
| — | VoidResult | Always | — |
To pass values out of BeanShell into the workflow, use a Set Variable entry to inject a workflow variable into the BeanShell scope, modify it inside a Code entry, then use a
SetVariabletask afterward to write it back. 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" and "Set 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. |
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 -->|Unknown| E6[❌ JAVA-CODE-ERROR-006]
Loop -->|All entries done| Success([✅ VoidResult])
E3 --> Error([❌ Exception])
E4 --> Error
E6 --> Error
E7 --> 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
- 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 two 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
- 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}"
}
]
}
]
}