API Consumer service allows the selection of subsets of Java APIs to be imported into Taverna Workbench and used as services within workflows.
In order to expose your Java API for you and others to use, you can use the API Consumer Tool to annotate selected classes and methods from the API and create the API definition XML file. You can then distribute the API (in a form of a JAR file) with the accompanying definition file. See the section on the API Consumer Tool on how to prepare your API for use in Taverna.
Importing API Consumer Services
Before you start, make sure you have the API Consumer XML definition file and the jar file of the library you wish to import. You will also need any jar files that the API Consumer library depends on.
Taverna will import classes and methods described in the XML definition file generated from the API Consumer Tool and and add them as services in the Service Panel. They will appear under a new node named after the imported library, as described in the XML definition file.
Using the API Consumer Classes and Methods as Services
Classes' constructors and methods that appear in the Service Panel can now be added to workflows as services.
In this example, our exposed API contains, among other things, a constructor for a class "AlgebraicRule" and a single method on that class called "delete". They appear as nodes in the Service Panel with little coffee bean icons next to them.
If we drag the "AlgebraicRule" service into the Workflow Diagram, you may see that it can construct the AlgebraicRule object for us on the output port called "object". The constructor service also takes an input parameter called "formula". Once this service creates the object instance for us on the "object" output port - we can invoke method "delete" on it as explained next.
If we drag the "delete" service into the Workflow Diagram, you may notice that it takes an object as input. The object you have to provide here is the AlgebraicRule object instance created by the object constructor service. If we connect these two services as shown in the figure below, the object created by the constructor service will be used to invoke the delete method on it.
As you can see, when you use the API Consumer services you have to build up the calls to the API as part of your workflow, as with the delete() method on the AlgebraicRule instance. We first have to call the constructor, and then call the method on the returned object.
As a convenience, all methods also return the very same object that was passed to them as input on the output port called "object". This is so that methods that needs to be run in a particular sequence can be chained to pass their object reference. This in effect prevents execution of the second method before the first method is returning its result and object reference.
Java objects can only be passed to other API Consumer services that can understand them (and only if they are serializable). If you want any useful inputs and outputs to interact with your workflow you need to return basic types such as String or byte array.
Static methods do not need the reference to the object they belong to in order to be invoked, hence they do not need the constructor call to create the object.
You also have to place the .jar file of your API Consumer and any other depending .jar files in a special
lib directory under Taverna home directory so Taverna can find it. This is very similar to how you specify dependencies for Beanshell service, so we will not go into details of different options here here - see the “Configure dependencies" section for Beanshell service for more.
Users who receive your workflow will need to install the same required jar files to run it.
If your API is using JNI, or one of its dependencies uses JNI, which is a native library with binding for Java, you need to take some special considerations, as explained in the section on JNI-based native libraries under Beanshell services. In particular, you need to select the System classloader sharing for all your services and modify the Taverna startup scripts.
A Word of Advice
Depending on the complexity of your API, building workflows in this way can turn out to be very a cumbersome way to do graphical Java programming in a workflow. In many cases, writing a Beanshell script using the same dependency mechanism can give you most of the benefits in a smaller amount of time. However, the API Consumer gives you one major advantage - the workflow designer do not need to know much about Java and they will see a browsable structure of your API in the Service Panel, just like the bundled services. The workflow designer does need to know how to use your API though, but if you have explicitly designed it to be easy to use from Taverna that barrier can be lowered significantly.
An API that is useful for many people could also be wrapped as a WSDL Web service, which would make it usable from any Taverna Workbench without requiring installation of your JAR and API Consumer XML definition files.