You can call custom Java functions directly in StreamBase expressions by
an alias defined
in the server configuration file, or by using the calljava() function. The
StreamBase expression language provides two forms of the calljava() function, to be used in StreamBase simple
and aggregate expressions.
This topic provides guidelines for creating StreamBase custom functions in Java. It describes:
Note
StreamBase Studio ships with new projects configured by default to build with Java 6. If you have a requirement to use Java 5, configure the Studio project that contains your custom code using the steps in Using Java 5 for Custom Extensions.
The StreamBase installation includes the source files for two custom Java function samples:
| Sample | Described in |
|---|---|
| custom-java-function | Custom Java Simple Function Sample |
| custom-java-aggregate | Custom Java Aggregate Function Sample |
Custom aggregate functions are built by extending the com.streambase.sb.operator.AggregateWindow class of the
StreamBase Java Client library. This class is described in Java API Documentation.
Simple custom Java functions can be called in expressions in the context of most StreamBase components, other than the Aggregate operator. Follow these steps to create a custom Java simple function:
-
Use the New StreamBase Java Function wizard to create the base code, as described in Using the StreamBase Java Function Wizard.
-
Implement a
public staticin a public Java class. -
Observe the guidelines in Method Parameter and Return Types.
For example, Hypotenuse.java in the sample application
declares the following class and method:
public class Hypotenuse {
public static double calculate(double a, double b) {
return Math.sqrt(a*a + b*b);
}
}
At compile time, the calljava() implementation looks
for only a single method matching the exact types of the function call in the
StreamBase expression. But there can be multiple matching methods, such
as these two functionally equivalent ones:
public static boolean isZero(int i) { return i == 0; }
public static Boolean isZero(Integer i) {
return i == null ? null : Boolean.valueOf(i.intValue() == 0);
}
If this case occurs, StreamBase throws an error.
Follow these steps to create a custom Java aggregate function:
-
Use the New StreamBase Java Function wizard to create the base code, as described in Using the StreamBase Java Function Wizard.
-
Define a Java class that extends the
com.streambase.sb.operator.AggregateWindowclass. -
Observe the guidelines in Method Parameter and Return Types.
-
Observe the guidelines in the annotations to the example below.
Consider the following annotated example:
package com.mycompany;
import com.streambase.sb.operator.AggregateWindow;
public class MyStdev extends AggregateWindow {
private double sum;
private double sumOfSquares;
private int count;
public void init() {
sum = sumOfSquares = 0.0;
count = 0;
}
public double calculate() {
return Math.sqrt((count * sumOfSquares - sum*sum) / count*(count-1));
}
public void accumulate(double value) {
sum += value;
sumOfSquares += value*value;
++count;
}
public void release() { /* nothing to release in this example */ }
}
The following annotations describe points of interest in the preceding example:
The method can have any number of parameters, including none. Each parameter must be a Java primitive or object type corresponding to a StreamBase data type as shown in the following table:
| StreamBase Data Type | Java Primitive | Java Object |
|---|---|---|
| blob | — | com.streambase.sb.ByteArrayView |
| bool | boolean | java.lang.Boolean |
| double | double | java.lang.Double |
| int | int | java.lang.Integer |
| long | long | java.lang.Long |
| list | — | java.util.List |
| string | byte[] | java.lang.String |
| timestamp | — | com.streambase.sb.Timestamp |
| tuple | — | com.streambase.sb.Tuple |
Notes
-
For simple functions, the return type cannot be void, and must be one of the Java primitive or Java Object types shown above.
-
You can use
java.lang.Stringanywhere a byte[] is acceptable as an argument or return value. In this case, the StreamBase string is transparently converted to or from ajava.lang.Stringusing the system default encoding. -
If a parameter's type is byte[] and its value is null, it is represented as a Java
null. Likewise, if a Java method with a byte[] return type returns a null, the calling StreamBase expression will see the return value as string(null). -
If the parameter or return type is list or tuple, you must either provide a custom function resolver, or must define the argument types in a
custom-functionelement in the server configuration file. See Custom Functions with Complex Data Types for details. -
If any value of a parameter with a primitive type is null at runtime, the method that implements the custom function is not invoked. However, Java Object parameter types can be used to pass in null parameter values.
For example, if a StreamBase custom function call would involve converting a StreamBase
int(null)orbool(null)value to a primitive Javaintorboolean, the method is not called, and null is assumed as the return value.public static boolean isZero(int i) { return i == 0; } calljava("TheClass", "isZero", 1) /* false * calljava("TheClass", "isZero", 0) /* true */ calljava("TheClass", "isZero", int(null)) /* null */
