Table of contents

Java Application API FAQ

What languages can I use to develop applications for IBM Streams?

Python, Java, Scala or SPL. Java and Scala use the Java Application API provided by this toolkit. SPL is the native language for IBM Streams, here's a getting start guide.

What version of IBM Streams do I need to be running to use the Java Application API?

The Java Application API uses IBM Streams 4.0.1.0 or later.

Can I use Java 8 lambda functions with the Java Application API?

Yes, IBM Streams 4.0.1 or later includes and supports Java 8.

How do I submit to a Streams instance that requires authentication?

Create the application bundle using the BUNDLE context and then submit using streamtool submitjob or Streams Console. Direct submission with authentication will be supported in the future.

I'm having issues reading and writing to files that I defined/initialized in my main() method. What gives?

Any Java object that your application references must be statically initialized. For example the following approach to initializing a file would be invalid:

public static BufferedWriter writer = null;
public static void main(String[] args){
writer = Files.newBufferedWriter("myFile.txt", charset);
...
myStream.sink(new FunctionV() {        
        @Override
        public void accept(String v) {
            writer.write(v);
        }
    });
...
}
That approach would fail because the writer variable is accessed statically by the application, so it would be seen as null. The following would be one way of properly initializing writer:

public static BufferedWriter writer = null;
static{
    BufferedWriter tmp = null;
    try{
        Charset charset = Charset.forName("US-ASCII");
        final Path outfile = (new File("outfile.txt")).toPath();
        tmp = Files.newBufferedWriter(outfile, charset);
    } catch(Exception e){
        e.printStackTrace();
    }
    writer = tmp;
}

public static void main(String argv[]){...}

I need to do some initialization in one of my stream transformations when running in standalone or distributed. How can I do this?

If you need to initialize state for one of your stream operations (such as opening a file or a database connection), implement a readResolve() method in the body of the transformation. When your application is loaded, the readResolve() method is invoked once before other methods.

In the RegexGrep sample that can be found in the documentation, the readResolve() method is used to initialize a Matcher object to look for regular expressions within a string:

    TStream filtered = lines.filter(new Predicate() {
	
	@Override
	public boolean test(String v1) {
		// Pass the line through if it matches the
		// regular expression pattern
		return matcher.reset(v1).matches();
	}

	// Recreate the matcher (which is not serializable)
	// when the object is deserialized using readResolve.
	transient Matcher matcher;

	/*
	 * Since the constructor is no invoked after serialization
	 * we use readResolve as a hook to execute initialization
	 * code, in this case creating the matcher from the
	 * pattern. 
	 * The alternative would be to create it on its first use,
	 * which would require an if statement in the test method.
	 */
	private Object readResolve() throws ObjectStreamException {
		matcher = pattern.matcher("");
		return this;
	}
});
You'll notice that the Matcher is marked as transient. This is because not all Java objects are serializable, and must therefore be excluded from the objects that are serialized when your application is submitted. Otherwize, you may encounter a NotSerializableException.

parallel() doesn't function properly when I run in an EMBEDDED context. Is this a bug?

Currently, parallel() is not supported when running embedded. While your application will compile and run, no parallelism will actually occur. Another way of putting it is that when running embedded, any call to parallel() will result in the equivalent of calling parallel(1).