AntBuilder ant scripts in JRuby


Project Home Page at rubyforge.org

http://rubyforge.org/projects/jruby-extras/

Quick start for Windows XP



Common optional extras:


Getting Started with your own JRuby ant scripts

See the examples:


examples/basic/check_install.rb

examples/jruby/build.rb



To subclass or not to subclass AntBuilder


If you do not want to subclass AntBuilder then you have to say:

require 'builder/antbuilder'

ant = Builder::AntBuilder.new  
...
ant.copy(:todir => @jruby_classes_dir) {
  ant.fileset(:dir => @src_dir, :includes => "**/*.properties")
}

(You don't have to use the name 'ant'; its just an example)


If you *do* subclass AntBuilder then you can don't have to use the 'ant' prefix all over the place.


class Build < Builder::AntBuilder

  def compile_tasks # Builds the Ant tasks that we need later on in the build
    ...
    copy(:todir => @jruby_classes_dir) {
      fileset(:dir => @src_dir, :includes => "**/*.properties")
    }
  end

  ...

end

Ant properties and Ant property Files

After every ant command is executed, AntBuilder retrieves the ant properties that have changed since the last command and copies them to ruby instance variables. (Remember that ant properties can only be assigned once).


Properties such as "build.dir" are converted to @build_dir. Any characters in the ant property that are not legal in a ruby instance variable are converted to underscores.


In ant xml build files you will often see:



You can try this in AntBulder with



If the file contains

build.dir=build

classes.dir=${build.dir}/classes


Then the ruby instance variables defined will be the equivalent of:

@build_dir="build"

@classes_dir="build/classes"


(Of course you could always define build_dir and classes_dir rather than build.dir and classes.dir in the default.build.properties file)


You cannot use the ant properties in the ant commands in the ${property} form. ${property} works in ant xml files and replaced by the ant xml file preprocessor.

But you can use the #{@property} form instead in JRuby code. There are a couple of exceptions – firstly the ant.property task will process ant properties of the form ${property} in the properties file as shown above (classes.dir=${build.dir}/classes).


Another case where 'native' ant properties can be used is shown here:


available(:property=>"jdk1.4+", :classname=>"java.lang.CharSequence")
patternset(:id => "java.src.pattern") {
  exclude(:unless=>"jdk1.4+", :name=>"**/AstPersistenceDelegates.java")
}



The above code will also create a ruby instance variable called @jdk1_4_

Ant dependencies


def compile # Compile the source files for the project
  depends :compile_tasks, :check_for_optional_packages 
  javac(
    :destdir => @jruby_classes_dir, 
    :debug => "true", 
    :source=> @javac_version, 
    :classpathref => "build.classpath" 
  ) {
    src(:path => @src_dir)
    patternset(:refid => "java.src.pattern")
  }
end


Taskdefs

The ant taskdef task can be used but the classpath attribute is ignored. If you actually want to use the declared task, you have to make sure that the class is on the classpath.


taskdef(:name =>"jruby_serialize", :classname=>"org.jruby.util.ant.JRubySerialize") {
  classpath(:path => @jruby_classes_dir) # ignored
}
...
jruby_serialize(:destdir => @jruby_classes_dir, :verbose=>"true") {
  fileset(:dir => @src_dir) {
    patternset(:refid=>"ruby.src.pattern")
  }
}

run_targets_from_command_line

If you subclass AntBuilder then you can end the class definition with run_targets_from_command_line and it will run tasks from the command line like ant does.

class Build < Builder::AntBuilder

  def compile_all
    ...
  end

  def clean 
    ...
  end

  ...
  run_targets_from_command_line

end

Then from the command line you could say:

jruby build.rb clean compile_all

Current Limitations and Gotchas

The AntBuilder project uses the excellent leafcutter api and is influenced by its features:




Common AntBuilder Errors




How Does It Work?

AntBuilder is just a tiny bit of JRuby glue, that sticks together apache-ant, leafcutter and Builder::XMLBase. It relies heavily on Builder::XMLBase to generate the correct syntax for the leafcutter ant api.

Very briefly: When you say "echo(:text => 'starting-build')" there is no such method as echo defined in the class, and this event gets trapped in Builder::XMLBase. The missing method and its parameters are then converted to a string "echo text=starting-build" by XMLBase and the AntBuilder subclass. This string is compatible with the leafcutter api syntax for executing ant code. The string is passed over to leafcutter for execution.


Background

First came Groovy's markup concept: See http://groovy.codehaus.org/GroovyMarkup which was an inspired idea. This inspired Ruby's Builder(and ::XmlMarkup) (http://builder.rubyforge.org/). See http://www.onestepback.org/index.cgi/Tech/Ruby/BuilderObjects.rdoc) for the story and the subsequent namespace issue solution which stung Groovy in the tail big time recently. Basically the Builder concept can be applied to any semi hierarchical structure, such as Swing gui construction and ant scripts. Groovy uses this concept to very good effect with its AntBuilder, SwingBuilder, and SWTBuilder. See http://www.javaworld.com/javaworld/jw-10-2004/jw-1004-groovy.html for an excellent example of the Groovy AntBuilder concept in practice.


Other Alternatives to AntBuilder in the Java world

import org.leafcutter.core.TaskRunner;

public class MyBuild {

public static void main(String[] args) {

TaskRunner.run("copy file=hello.txt tofile=world.txt overwrite=true”);

}

}


Other Alternatives to AntBuilder in the Ruby world

Use Rake


Using the Ruby Eclipse plugin with JRuby (Experimental)


Get eclipse 3.1 (or 3.2M3+)

Get the JRuby HEAD (The interpreter from version 0.8.2 will NOT work in RDT)

Install RDT nightly build from http://rubyeclipse.sourceforge.net/nightlyBuild/updateSite/

Restart Eclipse

Windows-Preferences-Ruby-Installed-Interpreters and add the JRuby jruby.bat as an interpreter.






























Eclipse 3.1 (Windows XP) AntBuilder Developer Setup

Get eclipse 3.1 or 3.2M3+

Get the JRuby HEAD (The interpreter from version 0.8.2 will NOT work in RDT)

Install RDT nightly build from http://rubyeclipse.sourceforge.net/nightlyBuild/updateSite/

Restart Eclipse

Windows-Preferences-Ruby-Installed-Interpreters and add the JRuby jruby.bat as an interpreter.

Install cygwin (including ssh from category “Net” - ssltools)

Open eclipse

Menu-Window-Preferences-Team-CVS-Ext Connection Method

CVS_RSH:=C:\cygwin\bin\ssh.exe

Parameters: -l anonymous rubyforge.org

CVS Server:cvs

Then open the CVS perspective and set up a new repository:: :extssh:anonymous@rubyforge.org:/var/cvs/antbuilder

Expand HEAD and right click AntBuilder and check out as project.

Run the examples

If classes are missing, modify the jruby.bat classpath