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