This section describes the steps required to develop and deploy a JMon application. You can develop JMon applications with Apama in Apama Plugin for Eclipse or manually, outside Apama Plugin for Eclipse. When you use Apama Plugin for Eclipse, some development steps are performed automatically for you. This section describes all development steps and notes which steps Apama Plugin for Eclipse automatically performs.
For more information on developing JMon applications in Apama Plugin for Eclipse, see Working with Projects.
See also Writing EPL plug-ins in Java which describes how it is possible to call out to code written in Java even when the main application logic is written in EPL rather than JMon.
Steps for developing JMon applications in Apama Plugin for Eclipse
To develop JMon applications in Apama Plugin for Eclipse
Select File > New > Java Event or select File > New > Java Monitor.
Or, in the Project Explorer, right-click your project and select New > Java Event or select New > Java Monitor.
A wizard appears that lets you specify the event or monitor’s name, the package, a description, the Java source folder and Java package. Apama Plugin for Eclipse automatically adds an entry for the event or monitor to the jmon-jar.xml deployment descriptor file and regenerates the JMon JAR file to include the new event or monitor.
If you want to build your JAR files manually, right-click your project and select Apama > Build JAR Files. This is useful if you unselected the Build jar files automatically option in the apama_java.xml file, which is in the config directory of your project. One reason you might not want to build the JAR files automatically is that the build takes too long. When Build jar files automatically is selected, Apama Plugin for Eclipse builds the JAR files every time you modify a JMon file.
If there are events that you defined in JMon and you refer to those events, or listen for those events in EPL code, then you must define those events in EPL as well as JMon. If you do not also define the events in EPL, Apama Plugin for Eclipse flags EPL references to those events as errors.
Apama Plugin for Eclipse adds all JMon JAR files to the correlator initialization list and all non-JMon JAR files to the correlator class path.
If you want to build your project’s files outside Apama Plugin for Eclipse and Eclipse, right-click your project and select Apama > Generate Ant Buildfiles. Apama Plugin for Eclipse generates an Ant build file (with the name build-project_name.xml), which you can use only to build your project’s JMon JAR files outside of the Eclipse environment. Note that this is unrelated to the Apama Plugin for Eclipse feature for exporting an Ant build file that you can use for deployment.
Apama Plugin for Eclipse generates your application’s JMon JAR file in the jmon_config_name java application files folder of your project’s directory. By default, jmon_config_name is the project name.
You can manage the content of the JMon JAR file and jmon-jar.xml file by using the editor in Apama Plugin for Eclipse to update the apama_java.xml file, which is located in the project’s config folder. You can use this editor to do the following:
Set JMon metadata.
Set the injection order of the events and monitors.
Add non-JMon Java classes to the JMon JAR files.
Add JMon classes that were not created by the Apama wizards in Apama Plugin for Eclipse to the JMon JAR file.
Java prerequisites for using Apama's JMon API
When you install Apama, the installation script installs the JMon API as ap-correlator-extension-api.jar in the Apama lib directory.
Apama Plugin for Eclipse includes the required Java compiler for running your application.
Steps for developing JMon applications manually
To develop JMon applications outside Apama Plugin for Eclipse
Ensure that ap-correlator-extension-api.jar is in your Java CLASSPATH environment variable.
Create a folder in which to develop your application.
In this development folder, define one .java file for each event type and one .java file for each monitor class.
In your development folder, compile all your Java source code.
javac *.java
If ap-correlator-extension-api.jar is not already in your CLASSPATH environment variable, you can specify the –classpath command-line option to point to ap-correlator-extension-api.jar.
In your development folder, create a JAR file that contains the deployment descriptor and all class files. The command line format is as follows:
jar –cf application_name.jar META-INF/jmon-jar.xml *.class
Replace application_name with a name you choose for your application. On Windows, use backslashes (\) instead of forward slashes (/).
If your application uses an event type definition class that is also used by another JMon application, you must include the event type definition class in the JAR file of each application that uses it. If you do not include a shared event type definition class in your application’s JAR file, injection fails with an ApplicationVerificationException.
You cannot specify the location of a shared event type definition class in your CLASSPATH environment variable. The correlator uses a separate classloader for each application, and it cannot use the system classloader for event type definition classes.
If any of your application’s .class files are in your CLASSPATH environment variable, remove them. If the JRE can resolve a class path by using either your application’s JAR file or your CLASSPATH environment variable, Apama fails to load your application.
Deploying JMon applications
To deploy and run your application outside Apama Plugin for Eclipse
Start a correlator with Java enabled:
correlator –j other_options
Inject the application JAR file:
engine_inject –j application_name.jar
Apama creates an object instance of each monitor class defined in the deployment descriptor file and executes its onLoad method. If there are multiple monitor classes, they are injected in the order in which they are specified in the jmon-jar.xml file.
The classes in the application’s JAR file cannot also exist (have the same packaging and name) anywhere else on the classpath. If they do, it causes the application to fail to load.
When you start the correlator, you can pass properties and options to the embedded JVM with the –J option. Specify the -J option with each property or option you want to specify.
For example, you can use this mechanism to specify a global classpath for the JVM with: -J-Djava.class.path=path. Apama prepends its own internal classpath .jar files to the path you specify. If you specify both the CLASSPATH environment variable and a classpath on the correlator start-up command line, the classpath specified on the command line takes precedence. See also Specifying the classpath in deployment descriptor files for information about specifying the classpath for each individual application.
Removing JMon applications from the correlator
To stop and delete a running JMon application, execute the engine_delete operation:
If the application you want to delete is not running on the local host on the default correlator port, be sure to specify options that indicate the correlator that is running the application you want to delete.
Replace application_name with the name of the application as specified in the deployment descriptor. This is not necessarily the same as the name of the application’s JAR file.
Deleting a JMon application does the following:
Terminates the application’s active listeners.
Deletes the application’s monitor classes.
Leaves the event type definitions loaded in the correlator. To remove the event type definitions, execute engine_delete and specify the files that contain the event type definitions.
Creating deployment descriptor files
The JMon application’s JAR file must contain a deployment descriptor file. Inside the correlator, the JVM processes the application’s deployment descriptor file and uses it as a guide to the event types and monitor classes to load. The name of the deployment descriptor file must be jmon-jar.xml.
When you use the Java support in Apama Plugin for Eclipse to develop your JMon application, the deployment descriptor file is generated for you. If you develop your JMon application outside Apama Plugin for Eclipse, there are two ways to create a deployment descriptor file:
Manually write the deployment descriptor XML file. Use your favorite editor to create this XML file according to the Format for deployment descriptor files.
Insert Java annotations in your source files and run a utility to generate the deployment descriptor file. The annotations you can insert are defined in the java.apama.jmon.annotation package.
Of course, you can use the utility to generate the deployment descriptor file and then manually edit the result. If you then run the utility again, you would lose any manual changes you had made.
The technique you use is largely a matter of personal preference — hand-coded or machine-generated. If you have a very large application with many event types and monitors, you might prefer to insert the annotations and generate the deployment descriptor file. If you have a small application, you might find it easier to write the deployment descriptor file.
Format for deployment descriptor files
The format of the deployment descriptor file must be compliant with the XML defined by the following XML Document Type Definition (DTD):
http://www.apama.com/dtd/jmon-jar_1_2.dtd
You should become familiar with this DTD to understand the exact definition of the deployment descriptor file. However, the normal structure of the file is as follows. In the following format, all text inside XML element tags, which is in italic typeface, indicates placeholders for which you would supply an actual value.
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE jmon-jar PUBLIC "-//Apama, Inc.//DTD Java Monitors 1.2//EN"
"http://www.apama.com/dtd/jmon-jar_1_2.dtd"><jmon-jar><name>Application Name in the Correlator</name><version>Version Number</version><author>Author</author><company>Company Name</company><description>Description of this application</description><classpath>${sys:MY_THIRD_PARTY_DIR}/lib/foo.jar;
${sys:MY_THIRD_PARTY_DIR}/lib/bar.jar</classpath><application-classes><event><event-name>Event Type name in the Correlator</event-name><event-class>Event Type's class location</event-class><description>Description of Event Type</description></event><monitor><monitor-name>Monitor's name in the Correlator</monitor-name><monitor-class>Monitor's class location</monitor-class><description>Description of Monitor class</description></monitor></application-classes></jmon-jar>
The most important part of the deployment descriptor file is the application-classes element. This element must contain an event element for each event type your JMon application defines. It must also contain a monitor element for each monitor your JMon application defines.
The application name that you specify in the name element is important because it defines the JMon application’s name in the correlator. The engine_inspect management tool displays this name when it lists data for your application. If you want to delete your application, you specify this name. The application name must be unique across all currently loaded applications. If the application name is not unique, injection fails.
Specifying the classpath in deployment descriptor files
Each JMon or Java plug-in JAR is loaded in its own dedicated Java classloader, which by default has access only to its own classes, and those available globally in the correlator’s system classloader.
Note: The correlator’s system classloader includes some standard Apama libraries such as the ap-correlator-extension-api.jar and ap-util.jar JAR files plus any additional JAR files the user chooses to specify on the correlator command line using -J-Djava.class.path=path.
It is also possible to specify additional JAR files for use by a specific JMon application or Java plug-in, to provide access to any third-party libraries that the JAR requires. This approach is more self-contained than adding to the correlator’s global classloader.
The classpath string for a JMon application or Java plug-in is specified in its deployment descriptor XML file as follows:
If you are manually writing the deployment descriptor XML, add the optional classpath element just after the description element, for example:
<description>Description of this application</description><classpath>${sys:MY_THIRD_PARTY_DIR}/lib/foo.jar;
${sys:MY_THIRD_PARTY_DIR}/lib/bar.jar</classpath>
Note that the classpath element is only available in the 1.2 (and greater) versions of the JMon XML DTD (jmon-jar_1_2.dtd), so it may be necessary to update the DOCTYPE of the deployment descriptor to specify this DTD version if it does not already.
If you are generating the deployment descriptor automatically using Java annotations, then use the optional classpath attribute in the @Application annotation:
@Application(
name = "Simple",
author = "My Name",
version = "1.0",
company = "Apama",
description = "My simple JMon application or Java plug-in",
classpath = "${sys:MY_THIRD_PARTY_DIR}/lib/foo.jar;
${sys:MY_THIRD_PARTY_DIR}/lib/bar.jar"
)
If you are using Apama Plugin for Eclipse to generate the .jar and deployment descriptor, use the @Application annotation approach to specify the classpath.
In both cases, the classpath string consists of any number of classpath entries, delimited by semicolon characters (;). Note that the semicolon must be used even on platforms that typically use a colon or other character to separate path entries, and also that forward slashes (/) should be used instead of backslashes (\), in order to ensure that the application works in the same way regardless of the platform it is deployed on.
Avoid using absolute paths in the classpath, as this makes it difficult to use the application JAR on different machines. Instead, use ${...} placeholders to identify the first part of each path, for example, the installation directory of a third party whose libraries you wish to use. Currently two types of placeholder are supported:
${sys:MY_SYS_PROP_NAME} is replaced by a Java system property called MY_SYS_PROP_NAME
${env:MY_ENV_VAR_NAME} is replaced by an environment variable called MY_ENV_VAR_NAME
The values for system property placeholders can be specified on the correlator command line using: -J-DMY_SYS_PROP_NAME=path.
The correlator will log a warning for any path that cannot be found, but will fail to inject the application entirely if the classpath includes any ${...} placeholders that are not defined.
You can make the location of your project directory available by defining an environment variable in a YAML configuration file as described in Setting environment variables for Apama components. You can use ${PARENT_DIR} as the value of the property if the YAML file is located in your project directory root. If you do this, you can specify JAR files from your project directory. For example:
Defining event types in deployment descriptor files
The deployment descriptor file must define an event element for each event type class in your JMon application’s JAR file. Each event element must contain the following two elements:
event-name — The name by which this event type is to be defined within the correlator. The correlator has a single namespace. Consequently, this name must be unique across all applications. For example, Tick or SimpleApp.Tick. If you specify a package qualified name, it is the qualified name that must be unique.
event-class — The name of the Java class in which this event type is defined. This must correspond to the fully qualified name of the class, for example, Tick if the event type class is defined within the default Java package, or com.apama.example.types.Tick if the event type class is defined in the com.apama.example.types package. The file, for example, Tick.java, is expected to be located within a folder structure that maps to the packaging, as per standard Java convention.
The event element can optionally contain a third element. This is the description element. Specify a description of the event type. For example:
<event>
<event-name>Tick</event-name>
<event-class>Tick</event-class>
<description>Event that signals a stock trade</description>
</event>
JMon and EPL share a single namespace for event types. After an event type is loaded into the correlator, using either JMon or EPL, it is available for use in either environment. However, within a JMon application, you cannot instantiate variables of an event type defined in EPL.
When you try to inject an event type definition that has the same name as a loaded event type, the correlator checks whether the two definitions are duplicates. If they are, the correlator ignores the duplicate you are trying to load. If the definitions are different, the correlator generates an injection error.
Defining monitor classes in deployment descriptor files
The deployment descriptor file must define a monitor element for each monitor class in your JMon application’s JAR file. Each monitor element must contain the following two elements:
monitor-name — The name by which this monitor is to be defined within the correlator. The correlator has a single namespace. Consequently, this name must be unique across all applications. For example, SimpleMon or SimpleApp.SimpleMon. If you specify a package qualified name, it is the qualified name that must be unique.
monitor-class — The name of the Java class in which this monitor is defined. This must correspond to the fully qualified name of the class, for example, SimpleMon if the monitor class is defined within the default Java package, or com.apama.example.monitors.SimpleMon if the monitor class is defined in the com.apama.example.monitors package. The file, for example, SimpleMon.java, is expected to be located within a folder structure that maps to the packaging, as per standard Java convention.
The monitor element can optionally contain a third element. This is the description element. Specify a description of the monitor. For example:
<monitor>
<monitor-name>Simple</monitor-name>
<monitor-class>Simple</monitor-class>
<description>A simple JMon monitor, used to show functionality of
a new installation.</description>
</monitor>
Inserting annotations for deployment descriptor files
In your JMon source files, you can specify the following annotations:
@Application — This annotation indicates the name of the application, as well as the author, version, company, and description of the application. Insert this annotation in any one, and only one, of your JMon source files. Each value is required. This annotation must be after any import statements and before the class definition statement. For example:
@Application(
name = "Simple",
author = "Moray Grieve",
version = "1.0",
company = "Apama",
description = "Deployment descriptor for a simple JMon monitor",
classpath = "${sys:MY_THIRD_PARTY_DIR}/lib/foo.jar;
${sys:MY_THIRD_PARTY_DIR}/lib/bar.jar"
)
@MonitorType — This annotation indicates the definition of a monitor. In each monitor class, insert this annotation immediately before the monitor class definition statement. You can specify a name and a description for the monitor. The name is the fully qualified EPL name for the monitor. If you do not specify a name, the name defaults to the fully qualified JMon class name of the class you are annotating.
@MonitorType(description = "A simple JMon monitor, used to show
functionality of a new installation.")
@EventType — This annotation indicates the definition of an event type. In each event type definition class, insert this annotation immediately before the definition statement for the event type. You can specify a name and a description for the event. The name is the fully qualified EPL name for the event. If you do not specify a name, the name defaults to the fully qualified JMon class name of the class you are annotating. For example:
@EventType(description = "Event that signals a stock trade")
@Wildcard — This annotation indicates a wildcard event field. Insert it immediately before the field definition statement. You must have specified the @EventType annotation for the event type that defines this field. For example:
Following are two sample source files with annotations. These are the source files for the simple sample application provided with Apama. The lines with the annotations are in bold typeface for your convenience.
Here is the Simple.java file with comments removed:
import com.apama.jmon.*;
import com.apama.jmon.annotation.*;
@Application(name = "Simple",
author = "Moray Grieve",
version = "1.0",
company = "Apama",
description = "Deployment descriptor for the Simple JMon monitor",
classpath = "" )
@MonitorType(description = "A simple JMon monitor, used to show
functionality of a new installation.")
publicclassSimpleimplements Monitor, MatchListener {
publicSimple() {}
publicvoidonLoad() {
EventExpression eventExpr = new EventExpression(
"all Tick(*, >10.0):t");
eventExpr.addMatchListener(this);
}
publicvoidmatch(MatchEvent event) {
Tick tick = (Tick)event.getMatchingEvents().get("t");
tick.emit();
}
}
Generating deployment descriptor files from annotations
There are two utilities that you can use to generate the deployment descriptor file from annotations in your source files:
com.apama.jmon.annotation.DirectoryProcessor — This utility processes a directory and generates the deployment descriptor file, which you must add to your application’s JAR file.
com.apama.jmon.annotation.JarProcessor — This utility processes an application’s JAR file and adds the deployment descriptor file to that JAR file.
You can execute these utilities from the command line or from a Java build file.
The DirectoryProcessor utility takes three optional arguments:
-r indicates that you want to recursively process the .class files in each directory and subdirectory in the specified directory. The default is that the utility processes only the .class files that are in the specified directory.
-d specifies the directory that contains the .class files you want to process. The default is that the utility processes any .class files in the current working directory.
-o specifies the file in which to store the output. The default is that output goes to stdout. In the JMon application JAR file, the name of the deployment descriptor file must always be jmon-jar.xml.
After you generate the deployment descriptor file, you must place it in the META-INF directory of your development directory. For example, you can execute the DirectoryProcessor utility from the command line as follows:
cd src
javac -classpath
$APAMA_CORRELATOR_HOME/lib/ap-correlator-extension-api.jar
*.java
java -DAPAMA_LOG_LEVEL=WARN -classpath
$APAMA_CORRELATOR_HOME/lib/ap-correlator-extension-api.jar
com.apama.jmon.annotation.DirectoryProcessor -r -d./src -o
./src/META-INF/jmon-jar.xml
jar -cf../simple-jmon.jar META-INF/jmon-jar.xml *.class
The JarProcessor utility takes one required argument, which is the name of the JAR file to operate on. To execute the JarProcessor utility from a Java build file, you can define something like the following:
<!--Target to process the annotations in the JMon application classes
to produce jmon-jar.xml -- the deployment descriptor file.
-->
<target name="process-jar" depends="jar">
<echo message=
"Process annotations in jar file: ${process-jar-file}" />
<java jvm="java"
classname="com.apama.jmon.annotation.JarProcessor" dir="."
fork="yes">
<classpath>
<fileset dir="${lib-dir}">
<patternset refid="libs" />
</fileset>
</classpath>
<jvmarg value="-DAPAMA_LOG_LEVEL=WARN" />
<arg value="${process-jar-file}" />
</java>
</target>
<target name="process" depends="jar">
<antcall target="process-jar">
<param name="process-jar-file" value="${jar-file}" />
</antcall>
</target>
Package names and namespaces in JMon applications
There is no correlation between the correlator namespace defined for a named JMon event or monitor, and the Java package structure of the class file in which that event or monitor is implemented. Event expressions are based on the correlator namespace, not on the Java package of the implementation.
Consider the following example. An event type defined in a Java class a.b.c.MyEvent that is given the correlator name x.MyEvent. Also a monitor defined in a Java class a.b.c.MyListener that is given the correlator name y.MyListener. Now, although the two classes are in the same Java package and need not use import statements to see each other, their correlator names are in different namespaces. This means that an event expression in y.MyMonitor will need to use the fully qualified name x.MyEvent to refer the event.
Sample JMon applications
The Apama distribution includes a number of complete sample applications. These applications are in the samples/java_monitor folder, and are called simple, stockwatch, vwap, dos, context and complex.
See the README.txt file included with each sample for complete instructions for how to compile and run the sample application.