This document describes the usage of the BeanShell API for dynamically executing Java code via HTTP requests and returning structured JSON responses.
The API supports returning different data formats such as List ([]), Map/Object ({}), and String ("").
- BeanShell API Documentation
- ESCAPE API Documentation
- Upload JAR API Documentation
- Calling APIs Inside Java Code
- Setting Up Locally
POST /api/scripts
Content-Type: application/jsonExample request body:
{
"language": "beanshell",
"script": "<Java code here>"
}
Generic structure of API response:
{
"timestamp": "YYYY-MM-DDTHH:MM:SS.sssZ",
"data": <Returned data>,
"status": 200,
"error": null,
"language": "beanshell"
}
{
"language": "beanshell",
"script": "return \"Hello from BeanShell!\";"
}
Expected Output:
"data": "Hello from BeanShell!" {
"language": "beanshell",
"script": "import java.util.*; return Arrays.asList(\"apple\", \"banana\", \"cherry\");"
}
Expected Output:
"data": ["apple", "banana", "cherry"] {
"language": "beanshell",
"script": "import java.util.*; Map<String,Object> map=new LinkedHashMap<>(); map.put(\"key\",\"value\"); map.put(\"status\",\"ok\"); return map;"
}
Expected Output:
"data": {
"key": "value",
"status": "ok"
} {
"language": "beanshell",
"script": "System.out.println(\"Hello World\"); System.out.println(\"Generated Password: 12345\");"
}
Expected Output:
"data": {
"output": "Hello World\nGenerated Password: 12345"
} {
"language": "beanshell",
"script": "System.out.println(\"This will not be included\"); return \"Final Result\";"
}
Expected Output:
"data": "Final Result"If the script contains syntax or runtime errors:
{
"language": "beanshell",
"script": "int x = \"wrong\";"
}
Expected Output:
"data": null,
"status": 500,
"error": "Encountered \"=\" at line 1..."This API escapes raw Java code into a format usable in /api/scripts.
POST /api/escape
Content-Type: text/plainimport java.net.*;
import java.io.*;
URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
conn.disconnect();
return content.toString(); {
"escaped": "<escaped Java Code>",
"length": <int length>
}
Same as BeanShell API.
No error handling — pure escaping.
POST /api/upload-jar
Content-Type: multipart/form-dataSend a JAR file using multipart/form-data.
Example using Postman:
- Set Method =
POST - Set URL =
http://localhost:8080/api/upload-jar - In the Body tab:
- Select form-data
- Add a key
file(type = File) - Choose a
.jarfile from your system and send the request.
cURL Example:
curl -X POST "http://localhost:8080/api/upload-jar" -H "Content-Type: multipart/form-data" -F "file=@com.google.gson_2.10.1.jar"Generic structure of API response:
{
"status": "<uploaded|already_exists|error>",
"path": "Absolute file path where the JAR was stored",
"timestamp": "YYYY-MM-DDTHH:MM:SS.sssZ",
"error": null
}Example of API response:
{
"status": "uploaded",
"path": "D:\\project\\uploaded-jars\\example.jar",
"timestamp": "2025-08-18T12:34:56Z"
}{
"status": "uploaded",
"path": "D:\\isc-extended-workflow-helper\\uploaded-jars\\com.google.gson_2.10.1.jar",
"timestamp": "2025-08-18T12:34:56Z"
}{
"status": "already_exists",
"path": "D:\\isc-extended-workflow-helper\\uploaded-jars\\com.google.gson_2.10.1.jar",
"timestamp": "2025-08-17T14:22:31Z"
}{
"error": "Only .jar files are allowed"
}{
"error": "File is empty"
}If the server encounters an unexpected issue (e.g., file write issue, disk permission errors, invalid directory), response format:
{
"status": 500,
"error": "Internal server error message"
}Once a JAR is uploaded, it can be dynamically loaded in BeanShell scripts using:
addClassPath("D:\\isc-extended-workflow-helper\\beanshell-runner\\uploaded-jars\\com.google.gson_2.10.1.jar"); //add the path that was returned by Upload JAR API
//add another JAR Location
//add another JAR Location
import com.google.gson.Gson; //Normal, library import statements for the jar that was uploaded
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
gson = new Gson();
// Create array [ "foo", "bar" ]
JsonArray arr = new JsonArray();
arr.add(new JsonPrimitive("foo"));
arr.add(new JsonPrimitive("bar"));
// Create object { "foo":true, "bar":true, "foo-bar":false }
JsonObject orgs = new JsonObject();
orgs.add("foo", new JsonPrimitive(true));
orgs.add("bar", new JsonPrimitive(true));
orgs.add("foo-bar", new JsonPrimitive(false));
// Wrap into parent object
JsonObject root = new JsonObject();
root.add("array", arr);
root.add("orgs", orgs);
// Return as Map so Spring serializes it as JSON object
return gson.fromJson(root, java.util.Map.class);Expected Output:
{
"timestamp": "2025-08-18T13:15:29.938366600Z",
"data": {
"array": [
"foo",
"bar"
],
"orgs": {
"foo": true,
"bar": true,
"foo-bar": false
}
},
"status": 200,
"error": null,
"language": "beanshell"
}POST /api/scripts
Content-Type: application/jsonNote: Must be escaped before sending to
/api/scripts.
import java.net.*;
import java.io.*;
URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
conn.disconnect();
return content.toString(); {
"timestamp": "YYYY-MM-DDTHH:MM:SS.sssZ",
"data": <Returned data>,
"status": 200,
"error": null,
"language": "beanshell"
}
{
"language": "beanshell",
"script": "int x = \"wrong\";"
}
Expected Output:
"timestamp": "",
"data": null,
"status": 500,
"error": "Encountered \"=\" at line 1..."Install dependencies:
mvn clean install -Dmaven.test.skip=trueRun with API calling enabled:
mvn spring-boot:run -DskipTests -Dspring-boot.run.jvmArguments="--add-opens java.base/sun.net.www.protocol.https=ALL-UNNAMED"Run without API calling:
mvn exec:javaBase URL:
http://localhost:8080/
Endpoints:
/api/scripts/api/escape/test/beanshell/run(testing only, will be removed)
This project is licensed under the GNU AGPLv3 License - see the LICENSE file for details.
Created and maintained by Neeraj.
If you find this project useful, please consider supporting development: Future developments
- Signature Jar Validation during uploads
- Powershell Integration
- JWT Authentication (proposed but highly unlikely to implement due to hosting in client env.)