For information on the Java API, see the "laeJavaApi" Zip file which you will find in the following location: <Data360Analyze installation directory>/docs/lae
Classpath modifications
You may want to modify the classpath on the Java node for inheritance and interface purposes, or to reference external classes and jars that are not included with your installation. If external classes are required for the Java node to run, you can add these to the Classpaths property.
For example, if you had written some utility Java code packaged into a .jar file called "myUtilityClasses.jar", which you wanted to reference in your Java node, the .jar file needs to be placed in a location where the server can access it.
If the .jar file was in the following location: /usr/home/myUtilityClasses.jar then you would need to add /usr/home/myUtilityClasses.jar
to the Classpaths property. Note that if the path that you are referencing contains spaces, you do not need to enclose these in quotes in the Classpaths property.
Adding extra code blocks
In some circumstances, it may be impractical to write all of the Java code required into the one code block provided in the Java node, for example if a large amount of code is required and it may make more sense to have an object model, as opposed to one node class. Or, if you are creating a Java library node that you want to have some common base code, however each instance of this node may need to add or modify a small section of code.
Therefore, multiple Java code blocks are sometimes required. This section describes how this can be achieved using the Java node.
The same run time property name format used by the Java node is also required for additional code blocks. For each additional code block that you implement, two new property file properties are required:
-
ls.brain.node.java.classes.<something>.code
(Java code to compile)
-
ls.brain.node.java.classes.<something>.class
(name of the class to compile)
The class defining the node to run must be referenced in the NodeClass property.
For example, you have a node called AbstractMetadataPassThrough which provides the code required to open all of the input streams, setup the output metadata on the corresponding input metadata, and clean up after itself. For this to work, the node must have the same number of inputs as outputs. This node, however, cannot be run, and serves only as a library node which is to be inherited by other nodes.
The JavaCode defines the abstract base class, which defines the setup
and cleanup
methods required. The node introduces an additional code block, with the property name ImplCode. This property provides the skeleton for defining the required processAll
and propertyBase
methods when inherited by a node instance. (See Composition and inheritance).
The ImplCode property contains the following line:
public class {{^ImplClass^}} extends {{^JavaClass^}}
This states that value of the ImplClass property is to be taken as the name of the class defined within the code block. Further, this class is to extend the JavaClass class defined in the JavaCode property. If you use an instance of this library node, you can configure the ImplClass property.
The NodeClass property contains the following text:
{{^JavaPackage^}}.{{^ImplClass^}}
As the JavaClass property refers to an abstract class, this cannot be run as the node. Therefore, the node class which is to be run is declared in the ImplCode property, and is referenced by the ImplClass property.
You have a second node called MultiFilter. The MultiFilter node inherits from the AbstractMetadataPassThrough node.
The code within the processAll
method shown below, shows that the node continues reading records from each input until the inputs have no more records to read. On each record, a method processRecord
is called on a class {{^ProcessRecordClass^}}
.
@Override
public void processAll() throws NodeFailedException
{
boolean allDone = false;
int recNum=1;
while (!allDone) {
allDone = true;
for (int i=0; i<numInputs();i++) {
Record record = read(i);
if (record != RecordInput.EOF) {
allDone = false;
try {
{{^ProcessRecordClass^}}.processRecord(i, record, recNum, input(i), output(i));
}
catch (IOException ioe) {
logger().error(ioe, "Error Processing record on input: "+i);
throw fail();
}
}
}
}
recNum++;
}
The MultiFilter node also introduces an additional Java code block called ProcessRecordCode, which has the class name ProcessRecord, as specified in the ProcessRecordClass property. The node is a utility class and does not implement the Node
interface. Therefore, unlike the AbstractMetadataPassThrough node, the NodeClass property does not need to be modified, as the actual Node to be run is still defined in the ImplCode property.
The code in the ProcessRecordCode property defines the class structure and then references other properties.