Fantom provides JavaFFI for interacting with Java libraries. As an example, I will use the weka data mining library and show how to use the library to load in some data, construct and test a classifier.
- NOTE
As of version 1.0.73, Fantom still relies on Java 8 as its run-time. JavaFFI will not be able to find the standard Java libraries if used with a newer version of Java.
Download weka and locate the file 'weka.jar' - this is the library. Fantom uses a set of standard locations to search, when looking for a java class. The ideal place for the libraries is under the home folder for your Fantom installation: 'lib/java/ext/'.
The following script shows how to include some classes from the Java and Weka libraries, then create and use instances of classes from the Weka API.
// Example of using weka from Fantom using [java]weka.classifiers.trees::J48 using [java]weka.core::Instances using [java]java.io::FileReader class Main { public static Void main (Str[] args) { echo ("File to use: " + args[0]) // read in the data data := Instances(FileReader(args[0])) // set the class label as the last attribute data.setClassIndex (data.numAttributes() - 1) // construct the decision tree tree := J48() { buildClassifier (data) } // display the tree and related information echo (tree) // classify and display class of each instance data.numInstances.times |Int i| { classn := tree.classifyInstance (data.instance(i)) echo ("${data.instance(i)} is classed as ${classn}") } } }
Simply run the script like a normal Fantom script. In this example I have used a data file from the Weka distribution. The Fantom runtime locates and uses the Weka library as needed:
> fan run-j48.fan weather.nominal.arff File to use: weather.nominal.arff J48 pruned tree ------------------ outlook = sunny | humidity = high: no (3.0) | humidity = normal: yes (2.0) outlook = overcast: yes (4.0) outlook = rainy | windy = TRUE: no (2.0) | windy = FALSE: yes (3.0) Number of Leaves : 5 Size of the tree : 8 sunny,hot,high,FALSE,no is classed as 1.0 sunny,hot,high,TRUE,no is classed as 1.0 overcast,hot,high,FALSE,yes is classed as 0.0 rainy,mild,high,FALSE,yes is classed as 0.0 rainy,cool,normal,FALSE,yes is classed as 0.0 rainy,cool,normal,TRUE,no is classed as 1.0 overcast,cool,normal,TRUE,yes is classed as 0.0 sunny,mild,high,FALSE,no is classed as 1.0 sunny,cool,normal,FALSE,yes is classed as 0.0 rainy,mild,normal,FALSE,yes is classed as 0.0 sunny,mild,normal,TRUE,yes is classed as 0.0 overcast,mild,high,TRUE,yes is classed as 0.0 overcast,hot,normal,FALSE,yes is classed as 0.0 rainy,mild,high,TRUE,no is classed as 1.0
Note: I have many jar files on my CLASSPATH, and these cause Fantom to run very slow, as it seems to try reading all the libraries looking for the ones it needs. Before running the above script, clear out the classpath using (on Linux):
> export CLASSPATH=.
The JavaFFI still has some limitations, which are documented on the documentation page. The main one of these for me is the lack of support for multi-dimensional arrays. One workaround is to create a wrapper in Java which Fantom can use, and the wrapper will create and pass along the required Java datatype. With the wrapper in place, the procedure for working with your wrapped library is as above.