Skip to main content

VM-Based Deployment

WSO2 Integrator projects compile to executable JAR files that run on any JVM, making virtual machines a straightforward deployment target. You can deploy as standalone JARs for individual services or use consolidated packages to run multiple integrations from a single runtime.

Prerequisites

RequirementDetails
Java RuntimeJDK 17 or later
Operating SystemLinux (recommended), macOS, or Windows
MemoryMinimum 512 MB, recommended 1 GB+ per instance
BallerinaDistribution installed on the build machine

Building the executable JAR

Use the bal build command to produce a standalone executable JAR.

bal build

This generates a fat JAR in the target/bin/ directory:

target/
bin/
my_integration.jar

Run it directly:

java -jar target/bin/my_integration.jar

Build options

FlagDescription
--cloud=dockerAlso generate Docker artifacts
--graalvmBuild a GraalVM native image
--observability-includedBundle observability dependencies
-DskipTestsSkip test execution during build

Standalone JAR deployment

The simplest approach is to copy the JAR to the target VM and run it.

Step 1 -- transfer the JAR

scp target/bin/my_integration.jar user@production-vm:/opt/integrations/

Step 2 -- configure the runtime

Create a Config.toml in the same directory as the JAR (or set the BAL_CONFIG_FILES environment variable):

[myIntegration.http]
port = 9090

[myIntegration.db]
host = "db.internal.example.com"
port = 5432
username = "svc_user"
password = "encrypted:xxxxx"

Step 3 -- run as a systemd service

Create a systemd unit file at /etc/systemd/system/my-integration.service:

[Unit]
Description=WSO2 Integration Service
After=network.target

[Service]
Type=simple
User=ballerina
Group=ballerina
WorkingDirectory=/opt/integrations
ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar my_integration.jar
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment=BAL_CONFIG_FILES=/opt/integrations/Config.toml

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable my-integration
sudo systemctl start my-integration
sudo systemctl status my-integration

Step 4 -- verify the deployment

curl http://localhost:9090/health

Consolidated package deployment

For organizations running multiple integrations, a consolidated deployment bundles several integration packages into a single runtime.

Creating a consolidated package

  1. Create a consolidation project:
bal new consolidated_deploy -t lib
  1. Add each integration as a dependency in Ballerina.toml:
[package]
org = "myorg"
name = "consolidated_deploy"
version = "1.0.0"

[[dependency]]
org = "myorg"
name = "order_service"
version = "1.2.0"

[[dependency]]
org = "myorg"
name = "inventory_sync"
version = "1.0.3"

[[dependency]]
org = "myorg"
name = "notification_handler"
version = "2.1.0"
  1. Build the consolidated JAR:
bal build

Running the consolidated package

java -jar target/bin/consolidated_deploy.jar

All services start within the same JVM process, sharing resources.

Consolidated Config.toml

Provide configuration for all included integrations in a single file:

# Order Service configuration
[order_service.http]
port = 9091

[order_service.db]
host = "db.internal.example.com"

# Inventory Sync configuration
[inventory_sync.schedule]
cronExpression = "0 */5 * * * ?"

[inventory_sync.endpoint]
url = "https://erp.example.com/api"

# Notification Handler configuration
[notification_handler.email]
smtpHost = "smtp.example.com"
smtpPort = 587

JVM tuning for production

Recommended JVM flags for production deployments:

java \
-Xms512m \
-Xmx1024m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/integrations/ \
-Dballerina.observability.enabled=true \
-jar my_integration.jar
JVM FlagPurpose
-Xms / -XmxInitial and maximum heap size
-XX:+UseG1GCUse the G1 garbage collector (recommended)
-XX:MaxGCPauseMillisTarget max GC pause time
-XX:+HeapDumpOnOutOfMemoryErrorGenerate heap dump on OOM

Log management

Direct logs to files with rotation:

java -jar my_integration.jar 2>&1 | tee -a /var/log/integrations/my_integration.log

Or configure logging in Config.toml:

[ballerina.log]
level = "INFO"

Health checks and monitoring

Expose a health endpoint for load balancers and monitoring systems:

import ballerina/http;

service /health on new http:Listener(9091) {
resource function get .() returns http:Ok {
return http:OK;
}
}

What's next