J5M application deployment

The J5M application can be deployed as a special JAR archive using the J5M mechanism, or you can do it programmatically. Using the J5M mechanism is straightforward, simple, and fast. All you need to do is to create the special JAR archive which can be deployed.

You can deploy the special JAR file or its unpacked content.

The format is similar to WAR:

<root>
 |
 +--- WEB-INF/
       +--- classes/
       +--- lib/
             +--- library1.jar
             +--- library2.jar
             +--- ...

The structure forms three class loader domains:

  • WEB-INF/classes/ with your application classes (*.class files) in Java directory scheme copying the structure of packages
  • WEB-INF/lib/ with your application JARs and the 3rd party JARs
  • <root> with the rest of the archive

The priority for class loading is:

  1. WEB-INF/classes/
  2. JARs in WEB-INF/lib/
  3. <root> (mostly for resource loading)

Create the deployment JAR file in Maven

The special JAR file can be easily assembled in Maven. Your POM must include:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>create-distro</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>src/main/assembly/dist.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

You may also include a dependency to the J5M classes, if your application uses them (it does in a typical situation):

    <dependencies>
        <dependency>
            <groupId>egothor</groupId>
            <artifactId>j5m-kernel</artifactId>
            <version>4.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

Finally, you must include dist.xml file (referenced in POM, see descriptor tag):

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>j5m</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>README*</include>
                <include>LICENSE*</include>
                <include>NOTICE*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/classes</directory>
            <outputDirectory>/WEB-INF/classes/</outputDirectory>
            <includes>
                <include>**</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/site</directory>
            <outputDirectory>docs</outputDirectory>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/WEB-INF/lib/</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>false</unpack>
            <scope>runtime</scope>
            <excludes>
                <exclude>egothor:j5m-*</exclude><!-- would be excluded by J5M (anyway) -->
            </excludes>
        </dependencySet>
    </dependencySets>
</assembly>

Execute maven clean package and deploy the special JAR located in the target/ directory:

//domain1/test1 > deploy app /workspace/demo/target/j5m-demo-4.0.2-j5m.jar
OK: deploy app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8

Check the application spaces:

//domain1/test1 > ps
Nugget:   //domain1/test1 (-1 run-level)
Capacity: (1 heart-beat) (0 dead) (1 all)
Application spaces: 1
Chunks: #2 Alloc: 18 kB Requested: 18 kB Dedup ratio: 1.0
app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8 app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8

68D2F915 e:LG SecureSystemClassLoader{nick=test1@(http:j5m:nugget <no signer certificates>)} /controller
=== LOG ===
--- LOG ---
PREFERED [test1]

The application id and class loader are app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8. You can start a distant object from the application manually:

//domain1/test1 > exec /hello egothor.j5m.demo.SayHelloImpl app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8
Jun 24, 2014 8:54:28 PM j5m.nugget.base.SandboxingDomainCombiner <init> INFO: sandboxing on ProtectionDomain  (http:j5m:user:app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8 <no signer certificates>)
 app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8
 <no principals>
 null

Jun 24, 2014 8:54:28 PM j5m.nugget.base.DistantInstance invokeCallback INFO: invoke "startup" timeout=5,000
Jun 24, 2014 8:54:28 PM j5m.nugget.util.SafeInvoker invoke INFO: invoking an action and will wait for 5,000ms
Yahahahaha! :-)
Jun 24, 2014 8:54:28 PM j5m.nugget.base.DistantInstance invokeCallback INFO: finished "startup"
Jun 24, 2014 8:54:28 PM j5m.nugget.NuggetImpl directExec INFO: watchdog installed j5m.nugget.base.DistantInstance@4ec2c76
Jun 24, 2014 8:54:28 PM j5m.mcast.net.MulticastRegistry bindReferenceToObject INFO: bind //domain1/hello/test1@82586742 to egothor.j5m.demo.SayHelloImpl@58a6f590 at test1 with null, lease 10,000 MILLISECONDS in j5m.mcast.net.MulticastRegistry@88d6e1a
Jun 24, 2014 8:54:28 PM j5m.kernel.naming.EmbedRegistry store INFO: j5m.kernel.naming.EmbedRegistry@31225229 storing key //domain1/hello/test1@82586742
Jun 24, 2014 8:54:28 PM j5m.nugget.NuggetImpl tryBind INFO: exported //domain1/hello/test1@82586742
OK: exec

Next, you can start another object:

//domain1/test1 > exec /walker egothor.j5m.demo.Walker app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8
Jun 24, 2014 8:56:48 PM j5m.nugget.base.SandboxingDomainCombiner <init> INFO: sandboxing on ProtectionDomain  (http:j5m:user:app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8 <no signer certificates>)
 app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8
 <no principals>
 null

Jun 24, 2014 8:56:48 PM j5m.nugget.base.DistantInstance invokeCallback INFO: invoke "initialize" timeout=5,000
Walker context obtained
Jun 24, 2014 8:56:48 PM j5m.nugget.util.SafeInvoker invoke INFO: invoking an action and will wait for 5,000ms
Jun 24, 2014 8:56:48 PM j5m.nugget.base.DistantInstance invokeCallback INFO: finished "initialize"
Jun 24, 2014 8:56:48 PM j5m.nugget.NuggetImpl directExec INFO: allocating application thread group app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8
Jun 24, 2014 8:56:48 PM j5m.nugget.NuggetImpl directExec INFO: watchdog installed j5m.nugget.base.DistantInstance@40d9e437
Jun 24, 2014 8:56:48 PM j5m.mcast.net.MulticastRegistry bindReferenceToObject INFO: bind //domain1/walker/test1@1088021559 to egothor.j5m.demo.Walker@5a814da4 at test1 with [Lj5m.api.DistantParameter;@7eccc48f, lease 10,000 MILLISECONDS in j5m.mcast.net.MulticastRegistry@88d6e1a
Jun 24, 2014 8:56:48 PM j5m.kernel.naming.EmbedRegistry store INFO: j5m.kernel.naming.EmbedRegistry@31225229 storing key //domain1/walker/test1@1088021559
Jun 24, 2014 8:56:48 PM j5m.nugget.NuggetImpl tryBind INFO: exported //domain1/walker/test1@1088021559
OK: exec
zzzz? Hello!
zzzz? Hello!
zzzz? Hello!
...

To stop the walker, use kill (object id can be obtained via ps or see "watchdog installed j5m.nugget.base.DistantInstance@40d9e437" log record above):

//domain1/test1 > kill 40d9e437
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl kill INFO: disconnecting heartbeat and fencing /walker
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl tryUnbind INFO: trying unbind /walker
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl tryUnbind INFO: unexported //domain1/walker/test1@1088021559
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl kill INFO: calling shutdown on /walker
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl kill INFO: shutdown ended correctly /walker
Jun 24, 2014 8:58:18 PM j5m.nugget.NuggetImpl kill INFO: moved into dead-queue /walker
OK: kill
Jun 24, 2014 8:58:18 PM j5m.nugget.base.DistantInstance kissOfDeath INFO: kissOfDeath interrupt "/walker"
Jun 24, 2014 8:58:18 PM j5m.nugget.base.DistantInstance kissOfDeath INFO: kissOfDeath join "/walker" 100ms
zzzz? Hello!
Jun 24, 2014 8:58:18 PM j5m.nugget.base.DistantInstance kissOfDeath INFO: kissOfDeath brutal, "/walker" ignores our soft touches

At this point, /walker disappears and /hello still lives:

//domain1/1401711477495 > ps
Nugget:   //domain1/test1 (-1 run-level)
Capacity: (2 heart-beat) (0 dead) (2 all)
Application spaces: 1
Chunks: #2 Alloc: 18 kB Requested: 18 kB Dedup ratio: 1.0
app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8 app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8

68D2F915 e:LG SecureSystemClassLoader{nick=test1@(http:j5m:nugget <no signer certificates>)} /controller
 4EC2C76 e:LG app:da5616782df7d39dd0b7a1bec3926ed21b1ad0b8 /hello
=== LOG ===
[Tuesday, June 24, 2014 8:58:18 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:58:13 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:58:08 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:58:03 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:58 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:53 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:48 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:43 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:38 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:33 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:28 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:23 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:18 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:13 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:08 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:57:03 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:56:58 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:56:53 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
[Tuesday, June 24, 2014 8:56:48 PM CEST] 1 //domain1/hello/test1@82586742 hosted at test1
--- LOG ---
PREFERED [test1]
test1 19/19