The helloJavaWorld is a simple R package that shows how to distribute java software with an R package and communicate with it by means of the rJava package. helloJavaWorld has a vignette showing the different steps involved in making such a package.
Basically, helloJavaWorld uses the inst directory of an R package structure to ship the jar file in which the java software is packaged.
This post goes a bit further and shows how we can distribute the source of the java software and make R compile it when we run R CMD build
. For that we are naturally going to use the src part of the R package, leading to this structure:
. |-- DESCRIPTION |-- NAMESPACE |-- R | |-- helloJavaWorld.R | `-- onLoad.R |-- inst | |-- doc | | |-- helloJavaWorld.Rnw | | |-- helloJavaWorld.pdf | | `-- helloJavaWorld.tex | `-- java | `-- hellojavaworld.jar |-- man | `-- helloJavaWorld.Rd `-- src |-- Makevars |-- build.xml `-- src `-- HelloJavaWorld.java 7 directories, 12 files
Only the src directory differs from the version of helloJavaWorld that is on cran. Let's have a look at the files that are in src:
helloJavaWorld.java is the same as the code we can read in helloJavaWorld's vignette
1 public class HelloJavaWorld { 2 3 public String sayHello() { 4 String result = new String("Hello Java World!"); 5 return result; 6 } 7 8 public static void main(String[] args) { 9 } 10 11 }
build.xml is a simple ant script. Ant is typically used to build java software. This build script is very simple. It defines the following targets:
- clean: removes the bin directory we use to store compiled class files
- compile: compiles all java classes found in src into bin
- build: package the java classes into the hellojavaworld.jar file, that we store in the inst/java directory to comply with the initial package structure
1 <project name="Hello Java World" basedir="." default="build" > 2 3 <property name="target.dir" value="../inst/java" /> 4 5 <target name="clean"> 6 <delete dir="bin" /> 7 </target> 8 9 <target name="compile"> 10 <mkdir dir="bin"/> 11 <javac srcdir="src" destdir="bin" /> 12 </target> 13 14 <target name="build" depends="compile"> 15 <jar jarfile="${target.dir}/hellojavaworld.jar"> 16 <fileset dir="bin" /> 17 </jar> 18 </target> 19 20 21 </project>
Next, is the Makevars file. When an R package is built, R looks into the src directory for a Makevars file, which would typically be used to indicate how to compile the source code that is in the package. We simply use the Makevars file to launch the building and cleaning with ant, so we have a simple Makevars file:
1 .PHONY: all 2 3 clean: 4 ant clean 5 6 all: clean 7 ant build 8
See Writing R extensions for details on the Makevars file
And now we can R CMD build the package:
$ R CMD build helloJavaWorld * checking for file 'helloJavaWorld/DESCRIPTION' ... OK * preparing 'helloJavaWorld': * checking DESCRIPTION meta-information ... OK * cleaning src ant clean Buildfile: build.xml clean: BUILD SUCCESSFUL Total time: 0 seconds * installing the package to re-build vignettes * Installing *source* package ‘helloJavaWorld’ ... ** libs ant clean Buildfile: build.xml clean: BUILD SUCCESSFUL Total time: 0 seconds ant build Buildfile: build.xml compile: [mkdir] Created dir: /home/romain/svn/helloJavaWorld/src/bin [javac] Compiling 1 source file to /home/romain/svn/helloJavaWorld/src/bin build: [jar] Building jar: /home/romain/svn/helloJavaWorld/inst/java/hellojavaworld.jar BUILD SUCCESSFUL Total time: 1 second ** R ** inst ** preparing package for lazy loading ** help *** installing help indices >>> Building/Updating help pages for package 'helloJavaWorld' Formats: text html latex example helloJavaWorld text html latex example ** building package indices ... * DONE (helloJavaWorld) * creating vignettes ... OK * cleaning src ant clean Buildfile: build.xml clean: [delete] Deleting directory /home/romain/svn/helloJavaWorld/src/bin BUILD SUCCESSFUL Total time: 0 seconds * removing junk files * checking for LF line-endings in source and make files * checking for empty or unneeded directories * building 'helloJavaWorld_0.0-7.tar.gz'
Download this version of helloJavaWorld: helloJavaWorld_0.0-7.tar.gz
This approach relies on ant being available, which we can specify in the SystemRequirements in the DESCRIPTION file
SystemRequirements: Java (>= 5.0), ant
Next time, we will see how to trick the documentation system so that it builds javadoc files