JMS Application Container Swiftlet
Overview
The JMS Application Container Swiftlet (sys$jac) provides a managed environment for deploying and running Java applications with a JMS interface inside the SwiftMQ router. It supports both static (configured via XML) and hot-deployed (bundle-based) applications, offering lifecycle management, classpath isolation, and integration with the SwiftMQ scheduler for scheduled execution.
Features
Static JMS Application Containers
Static JMS Application Containers are defined directly in the router configuration under the static-containers entity list. Each static container specifies a Java class with a static main method to be executed. The configuration allows specifying arguments for the main method, a shutdown method, a startup delay, and whether the application should run on a virtual or platform thread.
Classpath entries for the application are managed per container, ensuring isolation between applications. System properties can also be set for each container, and these are applied to the JVM before the application starts. The lifecycle of each static container is managed by the Swiftlet, supporting enable/disable operations, and ensuring that classpath or system property changes require the application to be disabled first.
Classpath Isolation
Each static container can define its own classpath via the classpath entity list. This ensures that applications do not interfere with each other's dependencies. Changes to the classpath are only permitted when the application is disabled.
System Property Injection
System properties defined in the system-properties entity list are set on the JVM before the application starts. These properties are updated dynamically as new properties are added or removed, but changes require the application to be disabled first.
Lifecycle Management
Applications can be enabled or disabled via the enabled property. When enabled, the Swiftlet loads the specified main class and invokes its static main method. If the main-return-is-stop property is set to true, returning from the main method will automatically disable the application. A static shutdown method can be specified for graceful shutdown.
Threading Model
The use-virtual-thread property determines whether the application runs on a virtual thread (default) or a platform thread. This allows for efficient resource usage and compatibility with different Java versions.
Configuration Example:
<swiftlet name="sys$jac">
<static-containers>
<static-container name="myApp" enabled="true" main-class="com.example.MyApp" main-class-arguments="arg1 arg2" main-return-is-stop="true" shutdown-method-name="shutdown" use-virtual-thread="false" startup-delay="1000">
<system-properties>
<system-property name="my.prop" value="somevalue"/>
</system-properties>
<classpath>
<path-entry name="lib1" value="/opt/myapp/lib1.jar"/>
<path-entry name="lib2" value="/opt/myapp/lib2.jar"/>
</classpath>
</static-container>
</static-containers>
</swiftlet>
Hot Deployment of JMS Applications
The Swiftlet supports hot deployment of JMS applications via the SwiftMQ Deploy Swiftlet. Applications are packaged as bundles with a deployment descriptor specifying the main class, shutdown method, arguments, system properties, and optional scheduling information. When a bundle is added to the jms-app deploy space, the Swiftlet creates a dedicated class loader, applies system properties, and starts the application according to its descriptor.
Hot deployed applications can be scheduled for automatic start/stop using the SwiftMQ Scheduler Swiftlet. The deployment descriptor supports specifying a schedule with time expressions, calendars, date ranges, and maximum runtime. The Swiftlet integrates with the scheduler to manage the lifecycle of hot deployed applications according to the defined schedule.
Deployment Descriptor
Each bundle must include a deployment descriptor XML specifying the main-class, shutdown-method-name, optional main-class-arguments, startup-delay, main-return-is-stop, use-virtual-thread, system-properties, and an optional schedule element.
Scheduling Support
If a schedule is defined in the deployment descriptor, the Swiftlet registers a temporary schedule with the Scheduler Swiftlet. The application is started and stopped according to the schedule, and logging can be enabled for lifecycle events.
Lifecycle and Isolation
Each hot deployed application runs in its own class loader and has its own set of system properties. The Swiftlet manages the application's lifecycle, invoking the main and shutdown methods as appropriate, and cleans up resources when the bundle is removed.
Integration with SwiftMQ Scheduler
The Swiftlet integrates with the SwiftMQ Scheduler Swiftlet to allow both static and hot deployed applications to be started and stopped according to defined schedules. For static containers, a job factory named Application Invoker is registered, allowing scheduled invocation of static applications by name. For hot deployed applications, a dedicated job factory is created per application, and schedules are registered dynamically based on the deployment descriptor.
Schedules support time expressions, calendars, date ranges, and maximum runtimes, providing fine-grained control over application execution.
Job Factories
The Swiftlet registers job factories for both static and hot deployed applications, enabling scheduled execution via the Scheduler Swiftlet.
Job Schedule Entity
For hot deployed applications, the current schedule is visible in the Job Schedule entity under each hot deploy usage entry, showing all relevant scheduling properties.
Configuration Guide
Defining and Running a Static JMS Application
Use this scenario to configure a static JMS application that starts automatically on router startup, with a custom classpath and system properties.
- Add a new
static-containerentry understatic-containersin thesys$jacSwiftlet configuration. - Specify the
main-class, setenabledto true, and provide any required arguments. - Add classpath entries under
classpathand system properties undersystem-propertiesas needed. - Optionally specify a
shutdown-method-namefor graceful shutdown and setmain-return-is-stopif the application should stop when its main method returns.
<swiftlet name="sys$jac">
<static-containers>
<static-container name="exampleApp" enabled="true" main-class="com.example.Main" main-class-arguments="start --verbose" main-return-is-stop="true" shutdown-method-name="shutdown" use-virtual-thread="true" startup-delay="5000">
<system-properties>
<system-property name="env" value="production"/>
</system-properties>
<classpath>
<path-entry name="lib" value="/opt/example/lib/example.jar"/>
</classpath>
</static-container>
</static-containers>
</swiftlet>
Hot Deploying a JMS Application with a Schedule
Use this scenario to deploy a JMS application as a bundle and schedule it to run at specific times using the Scheduler Swiftlet.
- Package the application as a bundle with a deployment descriptor specifying the main class, shutdown method, arguments, and schedule.
- Deploy the bundle to the
jms-appdeploy space using the Deploy Swiftlet. - The Swiftlet will automatically create a hot deploy container, register the schedule, and start/stop the application according to the defined schedule.
Scheduler Jobs
Application Invoker
Description: Invokes a static Application
Configuration Reference
The top-level entity in routerconfig.xml is <swiftlet name="sys$jac">.
<static-containers> in <swiftlet name="sys$jac">
Static Containers
Each <static-container> entry is identified by its name attribute (the Static Container).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
startup-delay |
Long | 0 |
No | No | Delay (ms) to wait before start |
enabled |
Boolean | false |
No | No | Enables/Disables this Container |
main-class |
String | — | Yes | No | The class name with the main method |
main-class-arguments |
String | — | No | No | The Arguments of the Main Class (blank is Delimiter) |
main-return-is-stop |
Boolean | false |
No | No | Is the return from the main method is equal to stop? |
shutdown-method-name |
String | — | No | No | Optional static Shutdown Method Name |
use-virtual-thread |
Boolean | true |
No | No | Uses a virtual thread to run this app, otherwise a platform thread |
<swiftlet name="sys$jac">
<static-containers>
<static-container name="..." main-class="..."/>
</static-containers>
</swiftlet>
<system-properties> in <static-containers>
System Properties
Each <system-property> entry is identified by its name attribute (the System Property).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
value |
String | — | Yes | No | Property Value |
<swiftlet name="sys$jac">
<static-containers>
<static-container name="...">
<system-properties>
<system-property name="..." value="..."/>
</system-properties>
</static-container>
</static-containers>
</swiftlet>
<classpath> in <static-containers>
Classpath
Each <path-entry> entry is identified by its name attribute (the Path Entry).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
value |
String | — | Yes | No | Path Entry |
<swiftlet name="sys$jac">
<static-containers>
<static-container name="...">
<classpath>
<path-entry name="..." value="..."/>
</classpath>
</static-container>
</static-containers>
</swiftlet>
Changelog
13.1.2 (2025-04-15)
- Modified JACSwiftlet
- Modified configuration; Modified Descriptor