Romain Francois, Professional R Enthusiast

To content | To menu | To search

Tuesday, September 8 2009

new R package : ant

The ant package has been released to CRAN yesterday. As discussed in previous posts in this blog (here and here), the ant R package provides an R-aware version of the ant build tool from the apache project.

The package contains an R script that can be used to invoke ant with enough plumbing so that it can use R code during the build process. Calling the script is further simplified with the ant function included in the package.

$ Rscript -e "ant::ant()"

The simplest way to take advantage of this package is to add it to the Depends list of yours, include a java source tree somewhere in your package tree (most likely somewhere in the inst tree) with a build.xml file, and include a configure and configure.win script at the root of the package that contains something like this:

#!/bin/sh

cd inst/java_src
"${R_HOME}/bin/Rscript" -e "ant::ant()"
cd ../..

This will be further illustrated with the demo package helloJavaWorld in future posts

Thursday, September 3 2009

update on the ant package

I have updated the ant package I described yesterday in this blog to add several things

  • Now the R code related to <r-set> and <r-run> tasks can either be given as the code attribute or as the text inside the task
  • The R code has access to special variables to manipulate the current project (project) and the current task (self) which can be used to set properties, get properties, ...
  • The package contains ant ant function so that ant can be invoked using a simple Rscript call, see below

The package now includes a demonstrative build.xml file in the examples directory

Here is the result

Wednesday, September 2 2009

R capable version of ant

ant is an amazing build tool. I have been using ant for some time to build the java code that lives inside the src directories of my R packages, see this post for example.

The drawbacks of this approach are :

  • that it assumes ant is available on the system that builds the package
  • You cannot use R code within the ant build script

The ant package for R is developed to solve these two issues. The package is source-controlled in r-forge as part of the orchestra project

Once installed, you find an ant.R script in the exec directory of the package. This script is pretty similar to the usual shell script that starts ant, but it sets it so that it can use R with the following additional tasks

  • <r-run> : to run arbitrary R code
  • <r-set> : to set a property of the current project with the result of an R expression

Here is an example build file that demonstrate how to use these tasks

Here is what happens when we call the R special version of ant with this build script

$ `Rscript -e "cat( system.file( 'exec', 'ant.R', package = 'ant') )"`
Buildfile: build.xml

test:
     [echo] 
     [echo]   	R home        : /usr/local/lib/R
     [echo]   	R version     : R version 2.10.0 Under development (unstable) (2009-08-05 r49067)
     [echo]   	rJava home    : /usr/local/lib/R/library/rJava
     [echo]   	rJava version : 0.7-1
     [echo]  

BUILD SUCCESSFUL
Total time: 1 second

Friday, August 28 2009

Combine R CMD build and junit

This is a post in the series Mixing R CMD build and ant. Previous posts have shown how to compile the java code that lives in the src directory of a package and how to document this code using javadoc.

This post tackles the problem of unit testing of the java functionality that is shipped as part of an R package. Java has several unit test platforms, we will use junit here, but similar things could be done with other systems such as testng, ...

The helloJavaWorld package now looks like this :

.
|-- DESCRIPTION
|-- NAMESPACE
|-- R
|   |-- helloJavaWorld.R
|   `-- onLoad.R
|-- inst
|   |-- doc
|   |   |-- helloJavaWorld.Rnw
|   |   |-- helloJavaWorld.pdf
|   |   `-- helloJavaWorld.tex
|   `-- java
|       |-- hellojavaworld-tests.jar
|       `-- hellojavaworld.jar
|-- man
|   `-- helloJavaWorld.Rd
`-- src
    |-- Makevars
    |-- build.xml
    |-- junit
    |   `-- HelloJavaWorld_Test.java
    |-- lib
    |   `-- junit-4.7.jar
    `-- src
        `-- HelloJavaWorld.java

9 directories, 15 files

We have added the src/lib directory that contains the junit library and the HelloJavaWorld_Test.java that contain a simple class with a unit test

And the ant build file has been changed in order to

  • build the junit test cases, see the build-testcases target
  • run the unit tests, see the test target
  • create nice html reports, see the report target

The package can be downloaded here

Coming next, handling of dependencies between java code that lives in different R packages

Friday, March 27 2009

Document java software with "R CMD build", ant, and javadoc

This is the sequel of this post where we look at ways to build javadoc documentation as part of an R package

Ant has the javadoc task which we will use to build html files from java sources, leading to this modified build script with the new javadoc target:

   1 <project name="Hello Java World" basedir="." default="build" >
   2 
   3   <property name="target.dir" value="../inst/java" />
   4   <property name="javadoc.dir" value="../inst/javadoc" />
   5   
   6   <target name="clean">
   7     <delete dir="bin" />
   8     <delete dir="${javadoc.dir}" />
   9   </target>
  10   
  11   <target name="compile">
  12     <mkdir dir="bin"/>
  13     <javac srcdir="src" destdir="bin" />
  14   </target>
  15   
  16   <target name="javadoc">
  17     <mkdir dir="${javadoc.dir}" />
  18     <javadoc access="public" destdir="${javadoc.dir}"
  19       author="true" version="true" use="true" 
  20       windowtitle="helloJavaWorld - Java API">
  21         
  22        <fileset dir="src" defaultexcludes="yes">
  23             <include name="**/*.java"/>
  24         </fileset>
  25           
  26     </javadoc>
  27   </target>
  28   
  29   <target name="build" depends="compile,javadoc">
  30     <jar jarfile="${target.dir}/hellojavaworld.jar">
  31       <fileset dir="bin" />
  32     </jar>
  33   </target>
  34   
  35 </project>
  36 

so that when we run "R CMD build", the directory inst/javadoc gets created and filled with documentation generated from the java sources

The next thing we need is a way to access this documentation from R documentation, so we will just add a link to it from the Rd file, I have added this into the helloJavaWorld.Rd file in the seealso section:

18 \seealso{\link[helloJavaWorld:../javadoc/index]{The Java API of the package}}

This is not a perfect solution but gives a starting point. Potential issues, things to improve :

  • It would be better to have a link in the 00Index.html file, but there currently is no way to do something like that
  • A way to jump back to the R documentation from the java documentation is needed

I have posted a copy of the built package here, and you can download the source of this version here

Next step, use the junitreport ant task to make a report of unit tests of the java code

Thursday, March 26 2009

Build java software with "R CMD build" and ant

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