Developing Apama Applications > Writing Correlator Plug-ins > Writing Correlator Plug-ins in Java > Using Java plug-ins
Using Java plug-ins
After you create a correlator Java plug-in, it must be injected into a Java-enabled correlator before it is available for use in Apama applications. Applications that will use the plug-in also need to import the plug-in by name, as is done with correlator plug-ins written in C or C++.
Injecting
The jar file containing the correlator plug-in must be injected to a correlator that has been started with the --java option which enables support for Apama Java applications. When using the Apama engine_inject utility to inject the jar file, you also need to use the --java option.
Importing
Once a Java plug-in has been injected it is available for import using the plugin-name defined in the deployment descriptor file. The correlator will automatically introspect the class and make available any suitable, public methods that can be called directly from EPL. For example, the following code imports a plug-in named TestPlugin and calls its dosomething method:
monitor m {
import "TestPlugin" as test;
action onload
{
test.dosomething();
}
}
Note, if the plug-in jar has been incorrectly injected, the correlator will try to load the plug-in as a C/C++ plug-in and may give an error such as Error opening plug-in library libfoo.so: libfoo.so: cannot open shared object file: No such file or directory. If this happens and you were trying to load a plug-in written in Java, then check that the jar file was created and injected correctly before your EPL file.
Deleting
A correlator plug-in can be explicitly deleted by calling engine_delete with the application name defined in the deployment descriptor, as with Apama Java applications. Monitors using the plug-in depend on the plug-in type in the normal fashion. The plug-in will not be deleted until the application and all dependent monitors are deleted.
All Apama Java applications are loaded into their own classloaders. This means that they have no access to any classes loaded in different jar files. If your plug-in requires any other Java libraries they must either be specified on the correlator's global classpath or injected in the same application jar as the plug-in. Once the application has been deleted, the plug-in can be re-injected and it will be loaded into a new classloader.
Interacting with contexts
Correlator plug-ins can be passed context objects using the com.apama.epl.plugin.Context type. The Context object is defined as:
package com.apama.epl.plugin;
public class Context
{
public String toString();
public Context();
public String getName();
public int hashCode();
public boolean isPublic();
public boolean equals(Context other);
public static native Context getCurrent();
}
The getCurrent method returns the context that this method was called from.
Correlator plug-ins can use the com.apama.epl.plugin.Correlator class to enqueue events, enqueue events to contexts and to get the current context. The Correlator object is defined as:
package com.apama.epl.plugin;
public class Correlator
{
public static native void enqueue(String evt);
public static native void enqueueTo(String evt, Context c);
public static native void pluginMethodBlocking();
}
The Correlator methods are:
*enqueue(String) – Adds the event represented in String to the back of the input queue of all public contexts.
*enqueueTo(String, Context) – Adds the event represented in String to the back of the input queue of the specified context.
*pluginMethodBlocking() – Informs the correlator that the plug-in is potentially blocking for the rest of this call and the correlator is free to spin up additional threads on which to run other contexts. See the example at the end of this topic.
For more information on com.apama.epl.plugin.Context and com.apama.epl.plugin.Correlator, see the Apama Java API.
Exceptions
If a method throws an exception, that exception is passed up to the calling EPL and can be caught by the calling monitor. If an exception is not caught it will terminate the monitor instance. Details on catching exceptions in EPL can be found in Catching exceptions in Developing Apama Applications in EPL.
Persistence
No Java plug-ins are persistent and they are not permitted in a persistent monitor, but they are permitted in non-persistent monitors in a persistent correlator.
Load, unload, and shutdown hooks
If a plug-in needs to run anything when it is loaded, you can do this in a static initializer:
public class Plugin
{
static {
... // initialization code here
}
}
It is not natively possible for a plug-in to run anything when it is unloaded. If you need this functionality you can declare a method to be called when the plug-in is unloaded using annotations:
public class Plugin
{
@com.apama.epl.plugin.annotation.Callback(
type=com.apama.epl.plugin.annotation.Callback.CBType.SHUTDOWN)
public static void shutdown()
{
... // shutdown code here
}
}
The method must be a public static function which takes no arguments and returns void. Currently, Apama does not support callbacks other than SHUTDOWN.
Non-blocking plug-ins and methods
In a correlator some threads have the potential to block and others do not. If a thread might block, the correlator starts new threads if it has additional runnable contexts. By default the correlator assumes that a plug-in call may block and will start additional threads on which to run other contexts. In situations where the plug-in call can never block, the additional overhead of starting new threads when all CPUs are busy is unnecessary. If you know that a plug-in or an individual method is non-blocking, you can improve efficiency by annotating either entire plug-ins or individual methods as non-blocking.
Note, however,if a method declared as non-blocking does block, the correlator can block all threads waiting for them to finish, resulting in a deadlocked correlator. For methods that are normally non-blocking, but may block in predictable situations, see "Sometimes-blocking functions", below.
Annotations
You can apply the annotation com.apama.epl.plugin.annotation.NoBlock with no arguments to either a plug-in class, or to a method on a class:
@com.apama.epl.plugin.annotation.NoBlock()
public class Plugin
{
...
}
When applied to a class, the annotation indicates that no method on the plug-in can ever block.
public class Plugin
{
@com.apama.epl.plugin.annotation.NoBlock()
public static String getValue() { ... }
}
When applied to a method, the annotation indicates that this method will never block, but other methods may block.
Sometimes-blocking functions
If you have a function that usually will not block, but under some known conditions may block, then the method can be declared as NoBlock as long as it then uses a callback to indicate when it is starting the potentially-blocking behavior. The callback is a static method on com.apama.epl.plugin.Correlator called pluginMethodBlocking. This function takes no arguments, returns no value and is idempotent. When it is called, the correlator will then assume that the plug-in is potentially blocking for the rest of this call and is free to spin up additional threads on which to run other contexts.
public class Plugin
{
@com.apama.epl.plugin.annotation.NoBlock()
public static String getValue()
{
if (null != localValue) return localValue;
else {
com.apama.epl.plugin.Correlator.pluginMethodBlocking();
localValue = getRemoteValue();
return localValue;
}
}
}
Logging
Correlator plug-ins written in Java can log to the correlator's log file. This is done via the com.apama.util.Logger class. Each plug-in must create a static instance of the Logger using the static getLogger method. This instance provides debug(...), info(...), warn(...) and error(...) methods which log a string at that log level in the correlator log file. The level is configured either via the correlator command line and management commands or using a log4j configuration file.
For more information on using the Logger class, including how to override the default log level, see the Apama Javadoc reference material, available starting with doc\javadoc\index.html in your Apama installation directory.
The following is an example of logging in a correlator plug-in:
package test;
import com.apama.util.Logger;
public class Plugin
{
private static final Logger logger = Logger.getLogger(Plugin.class);
public static void foo()
{
logger.info("A string that's logged at INFO");
}
}
This will produce entries in the correlator log file like this:
2013-06-11 15:14:21.974 INFO [1167792448:processing] - <test.Plugin> A string that's logged at INFO
Copyright © 2013 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or Terracotta Inc., San Francisco, CA, USA, and/or Software AG (Canada) Inc., Cambridge, Ontario, Canada, and/or, Software AG (UK) Ltd., Derby, United Kingdom, and/or Software A.G. (Israel) Ltd., Or-Yehuda, Israel and/or their licensors.