High Quality JMS Messaging.

Static Containers

A static JMS application container enables you to run any application (it doesn't have to be a JMS application; you can also start your favorite servlet engine) by configuring the resp. container definitions via the router's configuration file or via SwiftMQ Explorer/CLI. Once it is configured, it can be enabled which means it is started. An enabled JMS application can only be disabled if it provides a custom shutdown method. This method must be "public static" with a "void" return type. The name of the method is configurable since it is discovered by Java reflection.

Configuration

The configuration of a static JMS application consists of

The following example shows the configuration of 2 static containers, a subscriber and a publisher, where the publisher is started 20 seconds after the subscriber:

    <swiftlet name="sys$jac">
      <static-containers>
        <static-container name="01"
              main-class="TestSubscriber"
              main-class-arguments="1 smqp://intravm/timeout=10000 IVMTopicConnectionFactory testtopic 1"
              main-return-is-stop="true"
              enabled="true">
          <classpath>
            <path-entry name="01" value="d:/testdriver"/>
          </classpath>
          <system-properties>
            <system-property name="test" value="test"/>
          </system-properties>
        </static-container>
        <static-container name="02"
                main-class="TestPublisher"
                main-class-arguments="smqp://intravm/timeout=10000 IVMTopicConnectionFactory testtopic 1"
                shutdown-method-name="stop"
                startup-delay="2000"
                enabled="true">
          <classpath>
            <path-entry name="01" value="d:/testdriver"/>
          </classpath>
          <system-properties/>
        </static-container>
      </static-containers>
    </swiftlet>

Note that the containers are started in order of the "name" attribute of the "static-container" element. However, since they run asynchronously in different threads, the "startup-delay" ensures that the publisher starts after the subscriber is already running.

The publisher has a "shutdown-method-name" defined. The name of the method is "stop". Thus, the class TestPublisher has to have this method:

Example:

    public static void stop()
    {
      // do whatever to stop this app!
      try
      {
        connection.close();
      } catch (JMSException e)
      {
      }
    }

The shutdown method enables you to enable/disable (start/stop) the TestPublisher at any time via SwiftMQ Explorer/CLI, so you can easily restart this application. You cannot do this with the TestSubscriber, because it doesn't have a shutdown method. However, since it has attribute "main-return-is-stop" set to true, the container is disabled after TestSubscriber returns from its "main" method. Thereafter it can be started again.

Start/Stop of a static Application Container

A static JMS application is started by enabling its container via the "enabled" attribute. This leads to a call to the "main" method of the program in a different thread from the thread pool "jac.runner".

The call to the main method may return immediately or it may block until the program has finished. From SwiftMQ 5.0.0 above it is possible to specify if the return from the "main" method should mark the container as disabled. This can be done via the attribute "main-return-is-stop". The default value is false.

Therefore, a JMS application within the "main" method or with a returned "main" method but with attribute "main-return-is-stop" set to false is still enabled, thus running. Such an application can only be stopped by invoking the shutdown method.

A JMS application without a shutdown method cannot be stopped, except via the return from the "main" method which has to be specified via attribute "main-return-is-stop".

A shutdown method should always be able to asynchonously close and cleanup all resources (e.g. connections, threads etc) without blocking.

Classloaders

Each configured static container uses his own dedicated classloader. The parent classloader is the one which loaded the SwiftletManager class, hence, all SwiftMQ jar files are already present in the classpath and you don't have to define it again.

Since a dedicated classloader is used for each container, it is possible to run the same application in different instances, even if the static "main" or a shutdown method will be called. These methods are called on physically different classes, thus all static references within these classes (such as a static connection object) are contained in each container but they are different; a "connection.close()" will therefore only close it in one instance but not in the other.

If you delete the configuration of a static container, the classes are physically removed. If you change the application and create a new configuration, the new classes are loaded and you will have the same effect as with hot deployment.

Example

This example shows how to create and use a static container via the SwiftMQ Explorer. We use the TestPublisher from the previously mentioned configuration.

First of all, start the router and the SwiftMQ Explorer. Connect with the SwiftMQ Explorer to the router and expand the router node in the navigator frame. Go to the "JMS Application Container Swiftlet" node, expand it and do a right click on node "Static Containers":

Select "Create a new Entity" and fill the fields. Don't enable it, because you don't have a correct class path yet.

Do a right click on the "Classpath" node and select "Create a new Entity":

Create a new path entry. The "name" specifies the order of the class path entries. You can create as many entries as you want. The value is the actual path entry. It can be everything you normally specify in class paths (jars, zips, directories).

If your application needs system properties to be set, go to the "System Properties" node and select "Create a new Entity":

Specify the system property. You can create as many entries as you want. Keep in mind that these system properties are visible for all applications since they run within the same virtual machine.

Well, that's it. Now you have configured your application. You should now save your configuration.

To start it, toggle the "Enabled" attribute. The application will now be started with a delay of 2 seconds. You can see a new entry in the "Usage" section:

To stop it, toggle the "Enabled" attribute. The application will now be stopped by calling its defined shutdown method. The "Usage" entry will be removed: