Pragmatic Automation http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi Pragmatic Automation. Hosted by Mike Clark. en-us Gleaning Project Feedback http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/GleaningProjectFeedback.rdoc You know you want to extract useful information from your project in an automated way, but which tools should you use and how much configuration will they take? <p> <a href="http://jbrugge.com/blog">John Brugge</a> has taken a number of popular open-source tools and knitted them together for you. He&#8217;s calling it <a href="http://jbrugge.com/glean">Glean</a>, and his goal is to help your project get quick and easy feedback by simply dropping Glean into your build system. It&#8217;s analogous to Maven plugins, but aimed at projects using Ant, and less ambitious. </p> <p> Currently Glean includes scripts to drive the following tools: </p> <ul> <li>CPD (copy/paste detector) </li> <li>Emma (code coverage) </li> <li>JavaNCSS (source code metrics) </li> <li>PMD (static analysis) </li> <li>StatSVN (Subversion repository activity analysis) </li> <li>UMLGraph (generates UML class diagrams from code) </li> <li>&#8230; and about a dozen more </li> </ul> <p> The download includes basic documentation on how to set up Glean to run against a source tree, as well as sample configurations for a handful of open-source projects. </p> <p> John packaged up Glean to scratch an itch for his clients, and he&#8217;s offering it back to the community as a token of appreciation for all the open-source tools. <a href="http://jbrugge.com/glean">Glean</a> is distributed under an MIT license. </p> <p> Enjoy! </p> SwitchTower as an Automated Deployment Archetype http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/SwitchTowerDeploymentArchetype.rdoc I&#8217;ve been remiss to have delayed mentioning <a href="http://manuals.rubyonrails.com/read/book/17">SwitchTower</a> until now. It&#8217;s an open-source utility that makes one-step deployment to one or more machines both possible and painless. <p> Say, for example, you need to roll out a new release of your killer app to two web servers, four application servers, and a database server. You could manually log in to each of those machines and type a list of commands, or just let SwitchTower do it for you: </p> <pre> rake deploy </pre> <p> That single incantation causes SwitchTower to execute the commands listed in your deployment recipe in parallel (and atomically) on multiple machines. (It uses <tt>ssh</tt> to communicate with the remote machines.) It&#8217;s really that easy. </p> <p> But then you notice that the application you just deployed has a bug. After giving your manager fifty push-ups, you&#8217;re thankful you can press the &quot;undo&quot; button: </p> <pre> rake rollback </pre> <p> That command rolls back the application to the last deployed version <em>on all deployed machines</em>. Yes, it&#8217;s really that easy. </p> <p> I&#8217;ve been starting to use SwitchTower on all my <a href="http://clarkware.com/rails.html">Rails projects</a>, and demo&#8217;ing it in our <a href="http://pragmaticstudio.com">Pragmatic Rails Studio</a>. As a result, SwitchTower has truly spoiled me. It&#8217;s an automator&#8217;s dream, and I can&#8217;t imagine going back to manual deployment gyrations. </p> <p> That brings us to the point of this elevator pitch: Can you deploy and roll back software releases this easily and consistently on your project? If not, I&#8217;d recommend you give the SwitchTower <a href="http://manuals.rubyonrails.com/read/book/17">manual</a> a read, especially if you <em>aren&#8217;t</em> building Rails applications. That&#8217;s right, even if you&#8217;ve never heard of Ruby or Rails you owe it to yourself to check out SwitchTower because its concepts aren&#8217;t specific to Ruby or Rails. And in fact it seems possible to use SwitchTower as the deployment vehicle for apps of any size and color by customizing a core set of tasks. I&#8217;d love to hear of efforts to adapt SwitchTower to J2EE projects, for example. </p> <p> Every software project can benefit from a deployment process that takes less time and money without sacrificing quality. SwitchTower is an archetype of automated deployment. Check it out before rolling your own solution. </p> CruiseControl 2.3.1 Released http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/CruiseControl231.rdoc <a href="http://cruisecontrol.sourceforge.net">CruiseControl</a> 2.3.1 was released today with an enviable display of <a href="http://sourceforge.net/mailarchive/message.php?msg_id=13309089">nips and tucks</a>. <p> Get it <a href="http://cruisecontrol.sourceforge.net/download.html">here</a>. </p> CruiseControl 2.3 Released http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/CruiseControl23.rdoc The dedicated team of folks who write code to keep your code continuously integrated have obviously been busy this summer. <a href="http://cruisecontrol.sourceforge.net">CruiseControl</a> 2.3 was released yesterday with a goodly amount of new features and plugins (<a href="http://sourceforge.net/mailarchive/message.php?msg_id=12776276">release notes</a>). <p> Get it <a href="http://cruisecontrol.sourceforge.net/download.html">here</a>. </p> Tiger: An Automation Platform http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/Tiger.rdoc In the last 24 hours, I&#8217;ve upgraded my private and public worlds. Thankfully, both upgrades went off without a hitch. This PowerBook is now happily running <a href="http://www.apple.com/macosx/overview/">Tiger</a> and my <a href="http://clarkware.com">company web site</a> is now being hosted by <a href="http://www.textdrive.com/">TextDrive</a>. The end result is that I now have more options for automation across the board. <p> On the global front, TextDrive has all the <a href="http://textdrive.com/specs/">tools</a> I need to get things done on the web. It&#8217;s nothing short of a geek&#8217;s paradise, and the support has been superb. </p> <p> Locally, Tiger has all the fixings for an automation feast: <a href="http://www.apple.com/macosx/features/automator/">Automator</a>, <a href="http://www.apple.com/macosx/features/dashboard/">Dashboard</a>, and even the latest version of Ruby. Automator and Dashboard have been primarily focused at the consumer market, but both have a lot of potential for project automation. Imagine a Dashboard widget that shows, at a glance, the health of your build or production application. As well, Automator is at your service to help simplify repetitive or time-consuming project chores. Imagine a consistent, repeatable workflow that takes your source code and, through a series of visually-assembled actions, transforms it into a packaged release. </p> <p> Here are just a few resources to whet your appetite: </p> <ul> <li><a href="http://developer.apple.com/macosx/automator.html">Working with Automator</a>: An overview of Automator and primer for writing Automator actions (Apple Developer Connection) </li> <li><a href="http://www.macworld.com/2005/04/features/tigerautomator/index.php">Delegating the grunt work</a>: An introduction to Automator (MacWorld) </li> <li><a href="http://www.automatorworld.com/">Automator World</a>: A clearinghouse for Automator workflows, actions, news, etc. </li> <li><a href="http://www.apple.com/downloads/macosx/automator/">Automator Actions</a>: Apple&#8217;s site of Automator actions, ready for the taking </li> <li><a href="http://developer.apple.com/documentation/AppleApplications/Conceptual/AutomatorConcepts/index.html#//apple_ref/doc/uid/TP40001450">Automator Programming Guide</a> </li> <li><a href="http://developer.apple.com/macosx/dashboard.html">Developing Dashboard Widgets</a>: A jump-start to writing your first Dashboard widget (Apple Developer Connnection) </li> <li><a href="http://www.macworld.com/2005/04/features/tigerdashboard/index.php">Discovering the Dashboard</a> : An introduction to Dashboard (MacWorld) </li> <li><a href="http://developer.apple.com/documentation/AppleApplications/Conceptual/Dashboard_Tutorial/index.html">Dashboard Programming Guide</a> </li> </ul> <p> I&#8217;m looking forward to building a few Automator actions and Dashboard widgets myself. Moreover, I&#8217;m excited to see the killer applications that emerge from what promises to be a groundswell of activity around these tools. So please dig in, and share what you find! </p> Getting Started with Rake http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/GettingStartedWithRake.rdoc <a href="http://onestepback.org/index.cgi">Jim Weirich</a> has started writing what promises to be an excellent series of Rake tutorials (<a href="http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialIntroduction.rdoc">Getting Started</a> and <a href="http://onestepback.org/index.cgi/Tech/Rake/Tutorial/RakeTutorialRules.red">Handling Common Actions</a>). <p> <a href="http://rake.rubyforge.org/">Rake</a> is a Ruby build program that rhymes with <tt>make</tt>, but for all intents and purposes that&#8217;s where the similarity ends. Rake&#8217;s built-in tasks read like a mini build language and because Rakefiles are defined in standard Ruby syntax, you have all the power of a genuine object-oriented language with which to do automation galore. </p> <p> Yum. </p> Subversion: It's What's For Dinner http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/SVNBook.rdoc Project automation relies on version control for consistently and repeatability. If you&#8217;re not using version control, or your version control system is getting in your way, then the answer has never been clearer: <a href="http://subversion.tigris.org/">Subversion</a>. It&#8217;s free, it works great, and it stays out of your way. <p> Mike Mason, master chef of tasty Subversion dishes, has put together a collection of his best recipes to help you get up and running with Subversion quickly, and correctly. His book, <a href="http://www.pragmaticprogrammer.com/titles/svn/index.html">Pragmatic Version Control Using Subversion</a>, just went on sale. Get it while it&#8217;s hot! </p> CruiseControl 2.2.1 Released http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/CruiseControl221.rdoc <a href="http://cruisecontrol.sourceforge.net">CruiseControl 2.2.1</a> is now available, thanks to Jeffrey Fredrick and all the other hard-working folks named in the <a href="http://sourceforge.net/project/shownotes.php?release_id=301582">release notes</a>. <p> New features since 2.2 that caught my eye include: </p> <ul> <li>A configuration GUI was added to the <tt>contrib</tt> directory for standalone use or deployed with Java Web Start (<a href="http://cruisecontrol.sf.net/configuration/cruisecontrol-gui.jnlp">JNLP file</a>). </li> <li>CM Synergy is now supported&#8212;a notable new feature for two projects I recently visited. </li> <li>Default attributes can be specified for plugins to help whittle down the size of your <tt>config.xml</tt> file. </li> </ul> <p> And that&#8217;s just the tip o&#8217; the iceberg from my vantage point. In addition, many fixes were contributed from the community. </p> Off the Treadmill, Onto the Rails http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/RailsAutomation.rdoc If you haven&#8217;t heard of <a href="http://www.rubyonrails.org/">Ruby on Rails</a>, it might be time to look up from your keyboard. Rails is an open-source web framework in <a href="http://www.ruby-lang.org/en/">Ruby</a>, and it&#8217;s gaining mindshare at a staggering pace. But people aren&#8217;t just talking about Rails; they&#8217;re doing it, using Rails to build useful web applications. Indeed, the number of Rails applications that have been released in the last several weeks&#8212;applications powered by just a couple hundred lines of code&#8212;speaks well for the productivity boost of Rails development. <p> I caught up with <a href="http://www.loudthinking.com/">David Heinemeier Hansson</a>, the creator and tireless evangelist of Rails, to answer a few quick questions about the automation aspects of Rails. </p> <p> <b>Mike</b>: Everybody who tries Rails raves about how it makes them super productive. What types of automation does Rails employ to help developers create great apps so quickly? </p> <p> <b>David</b>: The basic philosophy is to encourage good behavior through invitations. So, for example, when you use the generator to create a new model or controller, it also creates unit test stubs that are all hooked up. You just enter a new test case and off you go. The same goes to fixtures, where a YAML file is already created and hooked up, just waiting for you to input the data. </p> <p> Additionally, we have the entire test process wired up through <a href="http://rake.rubyforge.org/">Rake</a> (Make for Ruby). So by default, if you just enter <tt>rake</tt> in a new Rails project, it&#8217;ll run all the unit and functional tests. Oh, and it&#8217;ll give you a statistical report about your code base, too. Like code-to-test ratio and stuff like that. </p> <p> <b>Mike</b>: Sounds like you&#8217;ve tried to automate everything that will be the same on most projects. </p> <p> <b>David</b>: We basically try to make it so that the only thing you need to create is application-specific functionality. All the infrastructure is already configured and ready to run. That means it&#8217;s much, much easier to get off to a good start with testing, revision control (we backup your DB schema for you), and the like. </p> <p> So even though we call it a Rails skeleton, when you create a new empty application, it&#8217;s actually more a fully fleshed, but undressed body you&#8217;re dealing with (yeah, Rails is that sexy :)). </p> <p> <b>Mike</b>: I like the fact that the automation built into Rails&#8212;code generation, templates, one-step test process, etc.&#8212;<em>invites</em> good behavior and productivity. It makes it easy for people to do the right thing. Speaking of testing, what are you using for continuous integration with Rails and Rails projects? </p> <p> <b>David</b>: <a href="http://damagecontrol.codehaus.org/">DamageControl</a>, which is a project out of ThoughtWorks by Aslak and Tirsen. It&#8217;s a bit fragile at the moment, but still very useful. It has already saved me a couple of times. I&#8217;m certainly a big believer in continuous integration. We have it set up for <a href="http://www.basecamphq.com/">Basecamp</a> and two recently announced Rails projects: <a href="http://tadalist.com/">Ta-da List</a> and <a href="http://www.writeboard.com/">Writeboard</a>. </p> <p> <b>Mike</b>: Rails projects are popping up all over. I just started converting a small J2EE project to Rails, and let me just say that Rails is highly addictive stuff. You mention DamageControl, a web application that&#8217;s already written in Ruby. Any chance it will be converted to a Rails application? </p> <p> <b>David</b>: Yes, I believe Aslak from the DamageControl team is working on this already. DamageControl was using its own controller framework-like setup, but seeing as <a href="http://ap.rubyonrails.org/">Action Pack</a> is readily available and will allow the project to run on Apache as well as <a href="http://www.webrick.org/">WEBrick</a>, it seemed like a great fit. </p> <p> I&#8217;m really excited to see DamageControl come to Rails. I&#8217;m sure it&#8217;ll mean an influx of good ideas and code from the existing Rails community. We&#8217;re quite eager to see it happen. </p> <p> <em>Thanks for taking time out to share your thoughts, David. Keep up the great work on Rails!</em> </p> A Sneak Peek at Automator http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/AutomatorSneakPeek.rdoc I enjoy writing programs that glue recurring tasks together into an automation workflow. And as a programmer, I have lots of automation tools within reach. But those tools often only get me half way to my goal. Once I&#8217;ve written a program that automates a task, I&#8217;d like to share the task with non-programmers and allow them to use it to build their own automation workflows. Indeed, automation is for all of us. <p> The goal of ubiquitous automation is one of the reasons I&#8217;m excited about <a href="http://www.apple.com/macosx/tiger/automator.html">Automator</a>: a feature in the soon-to-be-released Mac OS X Tiger. To my mind, it enables automation for the masses. Simply by dragging preloaded <em>Actions</em> onto a <em>Workflow</em>, anyone on your project can automate the tasks of checking out code from version control, building the project, and creating an installation package. That&#8217;s a few project chores you can check off the list, but imagine what other chores you might be able to automate when you start creating and sharing your own custom Actions. </p> <p> <a href="http://developer.apple.com/macosx/tiger/automator.html">Working with Automator</a>, the latest article in <a href="http://blog.x180.net/">James'</a> Tiger Developer Overview Series, gives you a quick overview of Automator, and then shows you how you can build your own Actions and share them with other users. </p> <p> Automator not only puts another automation tool within your reach, but it also conveniently puts the automation tools you build within the reach of others. When you start playing with Automator, please do <a href="http://localhost/cgi-bin/pragauto.cgi/SuggestContent.rdoc">write in</a> with your stories. I plan to share any Actions I craft right here, so stay tuned. </p> CruiseControl 2.2 Released http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/CruiseControl22.rdoc <a href="http://cruisecontrol.sourceforge.net">CruiseControl</a> 2.2 is now available. This release adds a boatload of new features and squashes known bugs. <p> I continue to be impressed by all the hard work and pride in workmanship that goes into this project and the expert support provided by the CruiseControl community. Just take a look at all of the individuals listed in the <a href="http://sourceforge.net/mailarchive/message.php?msg_id=9919275">release notes</a> who contributed to this release. There are countless others who help folks on the mailing list every day. Thank you all for making CruiseControl a great continuous integration tool! </p> Tracking Projects by the Dashboard Lights http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/DashboardLights.rdoc Tom Copeland wrote an insightful <a href="http://www.onjava.com/pub/a/onjava/2003/09/10/dashboard.html">article</a> a while back describing how his team uses automation&#8212;powered by Ruby and Java&#8212;to keep a large, geographically distributed Java project on track. He <a href="http://www.onjava.com/pub/a/onjava/2003/09/10/dashboard.html">writes</a>: <dl> <dt></dt><dd><em>&#8230;the UltraLog project is written in Java, by developers from over a dozen companies distributed around the United States. We needed something to help avoid integration problems; we needed a status page. So we put together the <a href="https://ultraforge.ultralog.net/">"Dashboard."</a></em> </dd> </dl> <p> He goes on to describe how they use Ruby to parse the output of several Java-based open source tools and aggregate project metrics into a consolidated view. Nowadays, depending on the situation, I&#8217;d probably use the <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> framework to publish this information on a custom tab of the <a href="http://cruisecontrol.sourceforge.net/reporting/jsp/index.html">build status page</a>. But it&#8217;s neat to see how Tom&#8217;s team used a scripting language to knit all of this information together. </p> Programming Ruby 2 Available For Pre-Order http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/ProgrammingRuby2.rdoc Dave <a href="http://pragprog.com/pragdave/Random/PickAxeTwoPreorder.rdoc">says</a> the book <a href="http://www.pragmaticprogrammer.com/titles/ruby/index.html">Programming Ruby 2</a> (aka the PickAxe book) is now available for <a href="http://pragmaticprogrammer.com/shopsite_sc/store/html/page5.html">pre-order</a>. <p> Why mention a Ruby book? Well, <a href="http://www.pragmaticprogrammer.com/sk/auto/">Pragmatic Project Automation</a> includes a Ruby script and some recent posts on this site have included Ruby code. And it turns out that Ruby is an excellent language for automating tasks, among other things. Indeed, I find myself reaching for Ruby more and more when I&#8217;m building automation tools. The language is concise and elegant, it gives you easy access to the power of your operating system, and it stays out of your way. So you&#8217;ll be seeing more Ruby code posted here. </p> <p> For those reasons, and my unabashed opinion that the book is outstanding, I highly recommend pre-ordering a copy. In addition to learning a fun new language, learning Ruby has made me a better programmer in general. So even if your project has no intentions of using Ruby, you&#8217;ll be honing new skills while discovering ways to improve on old skills. </p> Quartz Quick Start http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Tools/QuartzQuickStart.rdoc When I need to turn commanded automation into scheduled automation, I generally reach for <tt>cron</tt>. I&#8217;ve gotten used to its syntax and other peculiarities over the years, so <tt>cron</tt> is a tool I&#8217;m comfortable wielding. But recently I&#8217;ve been writing an automated monitoring program for a client requiring a scheduler that can live inside of their Java application and run on heterogeneous platforms. Java ports of <tt>cron</tt> are available, but I needed something with a bit more horsepower and flexibility. <p> <a href="http://www.opensymphony.com/quartz/">Quartz</a> is an open source job scheduling system written in Java that can be embedded within a Java/J2EE application or run as a stand-alone application. And yet those qualifications alone didn&#8217;t convince me to add the Quartz JAR file to my project. (I&#8217;m fairly picky about what libraries I&#8217;ll introduce into a project.) What did convince me to use Quartz is it makes the simple things easy and the complex things possible. </p> <p> For now, I just need to do simple things: schedule recurring jobs. And before I can do the complex things, I learn by doing the simple things first. So I thought I&#8217;d share how I got started using Quartz as a way of introducing it to you. As a result, you&#8217;ll have another automation tool within reach. </p> <h3>Download and Install</h3> <p> Start by <a href="http://www.opensymphony.com/quartz/download.html">downloading Quartz</a>. </p> <p> Installation is a simple matter of adding <tt>quartz.jar</tt> and <tt>commons-logging.jar</tt> to your classpath (ok, so it&#8217;s <em>two</em> JAR files). You&#8217;ll find various other JAR files in the Quartz distribution, but thankfully those two JAR files are all you need to get started. </p> <h3>Create A Job</h3> <p> Next, you need to write some Java code to create a job and put it on a schedule. </p> <p> Say, for example, you&#8217;re developing a build scheduler that runs Ant build files at regular intervals. (The world certainly doesn&#8217;t need another Java build scheduler with great continuous integration tools such as <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> already there for the taking, but it&#8217;s an example that&#8217;s hopefully near and dear to your heart.) </p> <p> Somewhere in guts of your build scheduler you create a job: </p> <pre> JobDetail jobDetail = new JobDetail(&quot;buildJob&quot;, &quot;buildGroup&quot;, BuildJob.class); </pre> <p> The <tt>JobDetail</tt> instance represents a schedulable job. The first two parameters uniquely identify the job by its name and group. The third parameter refers to a Java class that implements the <tt>Job</tt> interface. We&#8217;ll actually write the <tt>BuildJob</tt> class a bit later. But first, notice that the <tt>JobDetail</tt> refers to a class, which means you can&#8217;t call any instance methods to set the state of a <tt>Job</tt> instance. And because the scheduler will create a new instance of <tt>BuildJob</tt> each time the job is executed, the job&#8217;s instance variables are cleared between executions. </p> <p> That appears to be a problem because you want your build scheduler to run a specified Ant build file and target. Therefore, when an instance of your <tt>BuildJob</tt> class is created it will need to be supplied two variables: the build file and target. Quartz has a mechanism for shuttling data to jobs when they&#8217;re run. All you need to do is put the data in the <tt>JobDataMap</tt> associated with the <tt>JobDetail</tt> instance: </p> <pre> jobDetail.getJobDataMap().put(&quot;buildfile&quot;, &quot;build.xml&quot;); jobDetail.getJobDataMap().put(&quot;target&quot;, &quot;test&quot;); </pre> <p> The <tt>JobDataMap</tt> behaves like a Java <tt>Map</tt> with a key-value pair. We&#8217;ll see the data in the <tt>JobDataMap</tt> appear on the other side when we write the <tt>BuildJob</tt> class. </p> <h3>Tune A Trigger</h3> <p> Next, define when the job should run. Let&#8217;s say you want the Ant build file to run every 60 seconds indefinitely. To do that, create a trigger with the schedule properties: </p> <pre> Date startTime = new Date(); // immediately Date endTime = null; // forever long repeatInterval = 60000L; // 60 seconds int repeatCount = SimpleTrigger.REPEAT_INDEFINITELY; SimpleTrigger trigger = new SimpleTrigger(&quot;buildTrigger&quot;, Scheduler.DEFAULT_GROUP, startTime, endTime, repeatCount, repeatInterval); </pre> <p> The <tt>SimpleTrigger</tt> is good for simple interval-based schedules. It runs the job at a specific moment in time and optionally repeats running it on an interval. Alternatively, you can use the <tt>CronTrigger</tt> to run a job on a calendar-like schedule. (Now you know another reason I like Quartz.) For example, to run the Ant build at 2:30 am, Monday through Friday, use: </p> <pre> CronTrigger trigger = new CronTrigger(&quot;buildTrigger&quot;, Scheduler.DEFAULT_GROUP, &quot;0 30 2 ? * MON-FRI&quot;); </pre> <p> If you&#8217;re not familiar with <tt>cron</tt> syntax, that funny string supplied as the last parameter is a cron expression with the following form: </p> <pre> Seconds Minutes Hours DayOfMonth Month DayOfWeek </pre> <p> Cron expressions give you a lot of scheduling flexibility. For a full range of examples, refer to the <a href="http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html">CronTrigger JavaDoc</a>. </p> <h3>Schedule The Job</h3> <p> Until now we have not associated the job with its trigger. Indeed, jobs and triggers are decoupled. One benefit of this design is a job can be assigned to many triggers. Now we&#8217;re ready to schedule the job. </p> <p> First, create a scheduler: </p> <pre> SchedulerFactory factory = new StdSchedulerFactory(); Scheduler scheduler = factory.getScheduler(); </pre> <p> Then schedule the job by associating the job and its trigger: </p> <pre> scheduler.scheduleJob(jobDetail, trigger); </pre> <p> The schedule is set, but jobs won&#8217;t actually fire until the scheduler has been started: </p> <pre> scheduler.start(); </pre> <p> (Jobs can also be scheduled while the scheduler is running.) </p> <p> At some later time, make sure to gracefully shut down the scheduler: </p> <pre> boolean waitForJobsToComplete = true; scheduler.shutdown(waitForJobsToComplete); </pre> <h3>Write A Job Class</h3> <p> Before running the scheduler, we need to write a class that implements the <tt>Job</tt> interface. This brings us back to the <tt>BuildJob</tt> class. </p> <p> You put the Java code that gets executed when the job runs in the method called <tt>execute()</tt>. Here&#8217;s an example implementation of the <tt>BuildJob</tt> class: </p> <pre> public class BuildJob implements org.quartz.Job { public BuildJob() { } public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap map = context.getJobDetail().getJobDataMap(); String buildFile = map.getString(&quot;buildfile&quot;); String target = map.getString(&quot;target&quot;); try { AntRunner runner = new AntRunner(); runner.run(buildFile, target); } catch(Exception e) { throw new JobExecutionException(e); } } } </pre> <p> Notice that a <tt>JobExecutionContext</tt> instance is passed to the <tt>execute()</tt> method when the job is run. From the <tt>JobExecutionContext</tt> instance you&#8217;re able to get the <tt>JobDataMap</tt> instance containing the data defined when the job was scheduled&#8212;the Ant build file and the target. </p> <p> The <tt>BuildJob</tt> simply delegates to the <tt>AntRunner</tt> class&#8212;a custom class I wrote that runs the Ant build file and target. By making <tt>Job</tt> classes as thin as possible&#8212;simply delegating the real work to a class not dependent on Quartz&#8212;the job execution code is easier to test and potentially reuse elsewhere in the system. </p> <p> Notice also that the only checked exception the <tt>execute()</tt> method is allowed to throw is a <tt>JobExecutionException</tt>. Thus, any unhandled exceptions (checked or unchecked) raised during job execution should be caught and rethrown as a <tt>JobExceptionException</tt>. </p> <h3>Advanced Scheduling</h3> <p> We&#8217;ve barely tapped into the potential of Quartz. Thankfully, although it lets you do complex things, you can get started quickly and then wade into advanced features if you need them. If you want to dig deeper, the <a href="http://www.opensymphony.com/quartz/tutorial.html">tutorial</a> goes into more detail without overwhelming you with options. </p> <p> Have fun! </p>