Java Module Project Structure Overview

After implementing a module, a ZIP archive containing the module JARs, dependencies, and the scaleoutPackage.json can be deployed through the ScaleOut Active Caching UI. This ZIP archive is referred to as the ModulePackage

Module Dependencies

Module Clients (API or MSG) should reference the com.scaleoutsoftware.modules:client library.

<dependency>
    <groupId>com.scaleoutsoftware.modules</groupId>
    <artifactId>client</artifactId>
    <version>1.0.0</version>
</dependency>

Module Package Entry Point

The ActiveCaching service uses the module package’s defined entry point to launch the module across a cluster of ScaleOut StateServer hosts. The scaleout-msg-module and scaleout-api-module archetypes generate an entry point that does not require any additional configuration. The generated entry point is available in the src/main/packageDirs/Main.java.

The following is an example from the ShoppingCart demo:

public class Main {
    public static void main(String[] args) {
        // instantiate the module package
        ModulePackage modulePackage = new ModulePackage();
        // define the ApiModuleOptions
        ApiModuleOptions<ShoppingCart> apiModuleOptions = new ApiModuleOptionsBuilder<ShoppingCart>(ShoppingCart.class).build();
        // add the API module to the package
        modulePackage.addApiModule("ShoppingCart", new ShoppingCartApiProcessor(), apiModuleOptions);
        try {
            // wait for events
            modulePackage.waitForEvents();
        } catch (ModuleRegistrationException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Notably, the entry point is responsible for the following:

  1. Instantiating the ModulePackage.

  2. Instantiating the ModuleOptions.

  3. Adding the user-created module to the ModulePackage

  4. Calling waitForEvents() on the ModulePackage instance.

Testing a Module Locally

Requirements: ScaleOut StateServer is installed and running locally.

Developers can test the module package by:

  1. Creating a unit test or standalone app.

  2. Instantiating the ModulePackage.

  3. Instantiating the ModuleOptions.

  4. Adding the user created module to the ModulePackage

  5. Calling runLocalDevelopmentEnvironment() on the ModulePackage instance.

This non-blocking method allows the module to be self-hosted and handle incoming endpoint invocations for API modules and receive MSGs for MSG modules on a local server.

In addition to running the module package locally, developers can run a module client locally as well.

The code to create a MSG module client suitable for local testing is syntactically similar to creating a traditional MSG module client. Instead of specifying a GridConnection and build() – call buildLocalDevelopmentClient on the MsgModuleClientBuilder:

MsgModuleClient<Flight> client = new MsgModuleClientBuilder<Flight>("Flight", Flight.class).buildLocalDevelopmentClient();

scaleoutPackage.json

The scaleoutPackage.json metadata file is used to describe the module. The fields are:

Property

Description

modules

An array of Modules (see below)

cmdLineParams

The entry point into the Module

Module JSON definition

Property

Description

moduleName

The name of the module

runtime

java or dotnet

moduleType

api or msg

Adding Automatic Module Packaging to Maven Projects

The following package plugins will allow your Maven project to generate a ZIP archive for deployment. This task relies on the scaleoutPackage.json configuration file to be created/configured and then placed in the src/main/resources directory.

Begin by creating deployment.xml in the src\assembly directory (create the assembly directory if it does not already exist) with the following contents:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 https://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>deployment</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <!-- Compiled JAR -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <includes>
                <include>${project.build.finalName}.jar</include>
            </includes>
        </fileSet>

        <!-- Dependencies -->
        <fileSet>
            <directory>${project.build.directory}/dependency-jars</directory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>

        <!-- scaleoutPackage.json -->
        <fileSet>
            <directory>src/main/resources</directory>
            <includes>
                <include>scaleoutPackage.json</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

Next, add the following plugins to the project’s pom.xml under the <build><plugins> tag:

<!-- other plugins above... -->
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.6.0</version>
  <executions>
    <execution>
      <id>make-zip</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <finalName>${project.artifactId}</finalName>
        <appendAssemblyId>false</appendAssemblyId>
        <descriptors>
          <descriptor>src/assembly/deployment.xml</descriptor>
        </descriptors>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>3.6.0</version>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/dependency-jars</outputDirectory>
        <includeScope>runtime</includeScope>
      </configuration>
    </execution>
  </executions>
</plugin>
<!-- other plugins below... -->

Now run the following:

mvn package

Adding Automatic Module Packaging to Gradle Projects

The following packageForDeployment ZIP task will generate a package for Gradle projects. This task relies on the scaleoutPackage.json configuration file to be created/configured and then placed in the src/main/resources directory. Add the following to your Gradle build:

tasks.register('packageForDeployment', Zip) {
    group = 'distribution'
    description = 'Packages build output, dependencies, and scaleoutPackage.json into a deployable ZIP'

    // The output zip will be named like: project-name.zip
    archiveFileName = "${project.name}.zip"
    destinationDirectory = layout.buildDirectory.dir("deployment")

    // Include the compiled JAR
    from(jar) {
        into('')
    }

    // Include all runtime dependencies (flattened)
    from(configurations.runtimeClasspath) {
        into('')
        // Optional: filter to include only JARs
        include '*.jar'
    }

    // Include scaleoutPackage.json from resources
    from('src/main/resources') {
        include 'scaleoutPackage.json'
        into('')
    }

    // Fail the build if scaleoutPackage.json is missing
    doFirst {
        def scaleoutPackageFile = file('src/main/resources/scaleoutPackage.json')
        if (!scaleoutPackageFile.exists()) {
            throw new GradleException("Missing required file: src/main/resources/scaleoutPackage.json")
        }
    }
}

Then run the following to generate the YourProjectName.zip ZIP package in the project’s build/deployment/ directory.

./gradlew clean build packageForDeployment

ModulePackage ZIP Archive

After implementing a module, a ZIP archive containing the module JARs, dependencies, and the scaleoutPackage.json can be deployed through the ScaleOut Active Caching UI.

You can generate the deployable ZIP archive through your build tool by packaging the scaleoutPackage.json, the project artifact, and the project’s dependencies. Alternatively, if using a different java build tool you can manually create the module package ZIP archive. To do this, collect the java project’s build output as a JAR, the dependency JARs, the scaleoutPackage.json configuration file, and compress them into a ZIP archive.

The sequence for creating the module package ZIP archive is as follows:

  • Compile module classes

  • JAR module classes

  • Copy build output into a common directory, i.e. _MyModule_

  • Copy all dependencies of module classes into the MyModule directory

  • Copy scaleoutPackage.json into MyModule directory

The MyModule directory structure should now appear as follows:

    MyModule
|
 \
  scaleoutPackage.json
  MyModule-1.0.jar
  hosting-1.0.0.jar
  ... more dependencies ...

ZIP the _contents_ of the MyModule directory. Now the module package can be uploaded to the ScaleOut Active Caching web UI.

API Javadoc

API javadoc is available on the ScaleOut Software website.