List of Figures

Chapter 1. Introducing Ant

Figure 1.1. Conceptual view of a build file. The project encompasses a collection of targets. Inside each target are task declarations, which are statements of the actions Ant must take to build that target. Targets can state their dependencies on other targets, producing a graph of dependencies. When executing a target, all its dependents must execute first.

Chapter 2. A first Ant build

Figure 2.1. The XML Representation of a build file is a tree: the project at the root contains one target, which contains two tasks. This matches the Ant conceptual model: projects contain targets; targets contain tasks.

Figure 2.2. The directory layout for our project—keeping source separate from generated files. The shaded directories and files are created during the build.

Figure 2.3. Once you add dependencies, the graph of targets gets more complex. Here clean depends upon init; archive depends on compile, and, indirectly, init. All of a target’s dependencies will be executed ahead of the target itself.

Figure 2.4. Our build file hosted under Eclipse. Consult Appendix C for the steps needed to do this.

Chapter 4. Testing with JUnit

Figure 4.1. UML diagram of the core of our diary. Interfaces and classes in grey are those of the Java libraries. We’re going to assume they work and not test them ourselves.

Figure 4.2. JUnit UML diagram depicting the composite pattern utilized by TestCase and TestSuite. A TestSuite contains a collection of tests, which could be either more TestSuites or TestCases, or even classes simply implementing the test interface. The Assert class provides a set of static assertions you can make about your program.

Figure 4.3. JUnit’s Swing GUI has successfully run our test case. A green bar indicates that all is well. If there was a red bar, we would have a problem.

Figure 4.4. Adding test targets to the build process. Tests can be compiled only after the main source is compiled; the test run depends on the tests being compiled.

Figure 4.5. The test results presented by <junitreport>. The main page summarizes the test statistics and hyperlinks to test case details.

Figure 4.6. Test case results showing the assertion that failed, and the stack trace. The output log is under the System.out link. Keep an eye on the Time Stamp to make sure you’re not viewing old test results.

Chapter 5. Packaging projects

Figure 5.1. The packaging process: a JAR library consists of getting the source and data files into the JAR and the documentation into a directory, then creating the Zip and tar packages for distribution.

Figure 5.2. The generated API documentation

Figure 5.3. A UML view of the Java archives. WAR and EAR files are subclasses of the JAR file, which is itself a subclass of a Zip file class. WAR files can contain JAR libraries; EAR files can contain JAR and WAR files. JAR files contain a manifest, and usually at least some .class files.

Figure 5.4. The implementation hierarchy of Ant’s packaging classes and tasks. The <zip>, <jar>, <war> and <ear> task hierarchy resembles that of their respective file types.

Chapter 6. Executing programs

Figure 6.1. Ant can spawn native applications, while Java programs can run inside or outside Ant’s JVM.

Chapter 7. Distributing our application

Figure 7.1. Checking our mailbox. Our original message said “This is paypal security, please run this program to secure your account,” but the spam filters kept deleting it.

Figure 7.2. A model of how <antcall> creates a new project, with its own internal state

Chapter 8. Putting it all together

Figure 8.1. How to lay out classes in a large project. The files and directories in white are the source; those in grey are created in the build. Source and test source code trees are split up and compiled into different directories. Unit Test cases are in /test packages.

Chapter 9. Beyond Ant’s core tasks

Figure 9.1. Stop! It’s the code police! The tool also has caught the fact that we’ve forgotten to make a constant final. The case rule of constants (all capitals) did not match that of a variable.

Chapter 10. Working with big projects

Figure 10.1. A graph of the direct dependencies between our modules.

Figure 10.2. A master build can set the properties for the child projects, even if those projects try to override them. If the master build had accidentally used value instead of location, the directory location would have still been resolved in the client build files relative to their own directory, which would be a bug.

Chapter 11. Managing dependencies

Figure 11.1. Ivy reports the dependencies for one of the configurations

Figure 11.2. In this configuration, two obsolete modules are evicted.

Chapter 12. Developing for the Web

Figure 12.1. The basic workflow for constructing a web application

Chapter 13. Working with XML

Figure 13.1. The <xslt> task transforms XML into other file formats or into new XML files.

Figure 13.2. The generated HTML page. We can use this in developer documentation, or add it to the web site content.

Chapter 14. Enterprise Java

Figure 14.1. The new architecture of the diary application. The proxy class is created for us, and bridges from the web application to the session bean.

Figure 14.2. How Cactus runs tests on the server. The client program relays test requests to the server over HTTP; results come back the same way.

Chapter 15. Continuous integration

Figure 15.1. CruiseControl was the first continuous-integration server. The build loop polled for changes, ran the builds, and published reports; the web front end displayed the results. Everything was driven by the config.xml file.

Figure 15.2. Adding a user to Luntbuild. You can be notified by email, IM, or blog postings.

Figure 15.3. A server populated with a full set of users

Figure 15.4. A Luntbuild project is bound to a source code repository and can have different builders to build parts of the project on defined schedules.

Figure 15.5. The VCS Adaptor to check out the project from SourceForge

Figure 15.6. Luntbuild configuration of our builder. To create a new builder, click the “new document” icon on the top-right corner.

Figure 15.7. The schedule contains the settings to run an incremental build of our project. It declares dependencies on other schedules, the builder to run, and the actions to take on success.

Figure 15.8. Mappings from usernames in the repository to Luntbuild users

Figure 15.9. The Luntbuild status page. The book is building; some of the other projects are failing. A clean build is under way.

Chapter 16. Deployment

Figure 16.1. The goal for our distribution: Ant telling SmartFrog to deploy our entire system, including setting up the application server and the database

Figure 16.2. The SmartFrog daemons build up a distributed graph of things to deploy. Cross-references are still valid across the network.

Figure 16.3. The lifecycle of a component. Things get deployed, then started, and finally terminated. Unless something fails, of course.

Figure 16.4. A running system. JBoss and MySQL are running on separate hosts. The happy component’s action fetches the happy.jsp page every time its parent pings it.

Figure 16.5. Package layout for deployment descriptors. Every descriptor is a resource in a Java package but is built into a separate JAR from the application. That lets us change this JAR and sign it without having to rebuild the application itself. Descriptors in the deploy. targets package are targeted at different machines, while those in the parent deploy package are the reusable templates.

Figure 16.6. The management console, showing the status of the deployed application. The elements under the happy component have not yet been deployed, as it delays for a minute before starting happy page checks.

Figure 16.7. The waterfall process is inflexible and widely discredited. But look how an iterative development cycle can revert to a waterfall at the final stage.

Figure 16.8. Integrating deployment into the development cycle. Deploy to production systems, then test.

Chapter 17. Writing Ant tasks

Figure 17.1. Common classes encountered inside Ant. Projects, Targets, and Tasks map 1:1 with the <project>, <target>, and task declarations. The other interfaces and classes are implementation details.

Figure 17.2. The Resource class has many derivatives, any of which can be added to resource collections. The Resource class is in the org.apache.tools.ant.types package; all the derivatives go under the org.apache.tools.ant.types.resources.

Figure 17.3. A UML outline of the resource classes. The methods and attributes have been stripped off as the diagram is complex enough already.

Chapter 18. Extending Ant further

Figure 18.1. The BuildListener and BuildLogger receive lifecycle events, events which are described by BuildEvent objects.

Appendix C. IDE Integration

Figure C.1. Eclipse debugging an Ant build. It has stopped at a breakpoint and is showing the current set of Ant properties.

Figure C.2. Eclipse projects “build” through builders. You can add a build file as a builder through the project’s properties dialog, where it can live alongside the projects’ other builders.

Figure C.3. You can add any program as a new builder, but only Ant has built-in support from the IDE.

Figure C.4. The first step to setting up the new builder is to set the path to the build file and its base directory. You also can add arguments to the command line, but not -lib or -logger related, as the IDE is in charge of those.

Figure C.5. You can add any number of targets to the IDE actions. “Auto Build” is the background compile of the application; the “After a Clean” and “Manual Build” builds are the targets to do a clean and incremental build of the application.

Figure C.6. Selecting targets to run in response to IDE actions. Avoid setting up long lists of targets for each action; it’s better to create new targets in the build file with the appropriate dependencies. This lets you use it from the command line and makes it available to other developers.

Figure C.7. To choose and configure the Ant runtime in Eclipse, go through the Preferences dialog to the Ant runtime, and select a new Ant Home, the base directory of the Ant installation.

Figure C.8. NetBeans running a build file that prompts for input. It brings up a dialog in this situation. We’ve set a breakpoint on the following task, so the debugger will halt the build.

Figure C.9. Adding an existing Ant project to NetBeans. It will create a subdirectory, nbproject, to hold extra project information, such as custom build files for the debugging actions.

Figure C.10. Binding targets to the stages in the build file. You don’t need a target for every action at this point, as you can edit these bindings later

Figure C.11. Configuring Ant in NetBeans. We’ve entered the location of our command line Ant distribution. The IDE-supplied Classpath option is left alone. Checking the “Save Files” option tells the IDE to save all files before running a build. Always select this option.

Figure C.12. IntelliJ IDEA running the SSH upload targets of chapter 7. The connection is failing, and an error is appearing in the messages window. Clicking on the error brings up the line of the build file. IDEA highlights all unknown properties—here it is marking as unknown all properties loaded from the server-specific properties file.

Figure C.13. Selecting the actions for which we want a deployment target to run; here the Tomcat and JUnit activities both trigger the action. You may find that you will need IDE-specific targets for such actions, targets that do not depend on the complete build taking place. This is because the IDE has already taken on much of the build.

Figure C.14. IntelliJ IDEA lets developers run a version of Ant in the file system, rather than the built-in version, with extra JARS on the classpath and with custom properties.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset