Describes the installation and usage of the Jalopy Ant task. Its authors describe Ant as a “Java-based build tool. In theory, it is kind of like Make, but without Make’s wrinkles.
Why another build tool when there is already make, gnumake, nmake, jam, and others? Because all those tools have limitations that Ant’s original author couldn’t live with when developing software across multiple platforms. Make-like tools are inherently shell-based—they evaluate a set of dependencies, then execute commands not unlike what you would issue in a shell. This means that you can easily extend these tools by using or writing any program for the OS that you are working on. However, this also means that you limit yourself to the OS, or at least the OS type such as Unix, that you are working on. Makefiles are inherently evil as well. Anybody who has worked on them for any time has run into the dreaded tab problem. "Is my command not executing because I have a space in front of my tab???" asked the original author of Ant way too many times. Tools like Jam took care of this to a great degree, but still have yet another format to use and remember.
Ant is different. Instead of a model where it is extended with shell-based commands, Ant is extended using Java classes. Instead of writing shell commands, the configuration files are XML-based, calling out a target tree where various tasks get executed. Each task is run by an object that implements a particular Task interface. Granted, this removes some of the expressive power that is inherent by being able to construct a shell command such as 'find . -name foo -exec rm {}', but it gives you the ability to be cross platform—to work anywhere and everywhere. And hey, if you really need to execute a shell command, Ant has an <exec> task that allows different commands to be executed based on the OS that it is executing on.”
Explains the steps involved in getting the Ant task up and running.
The plug-in requires Ant 1.5 or later. See Section 1.1, “System requirements” for the basic requirements to run Jalopy.
The plug-in comes as an executable Jar Archive (JAR) that contains a graphical setup wizard to let you easily install the software. Wizard installation is highly recommended and explained in detail in Section 1.3, “Wizard Installation”.
If you would rather install the plug-in manually, you have to decompress and copy the appropriate files into the different application and/or settings folders. To decompress the contents of the installer JAR, you can often use the build-in support of your file manager (e.g. Nautilus) or any other software that can handle the ZIP compression format (e.g. 7Zip, WinZip or Stuffit Expander). If you don’t have access to one of the convenience tools, you might resort to the jar command-line application that ships with your Java distribution.
When you’re upgrading from a prior version and want to keep your settings, first
copy or rename the current Jalopy settings directory to match the version number
of the new release. For instance, if your current settings directory is
C:\Users\John Doo\.jalopy\1.9
and you’re about to install Jalopy 1.9.4, either copy the directory
contents or rename it to
C:\Users\John Doo\.jalopy\1.9.4
.
The Jalopy Ant task requires two JAR files, the Ant library
jalopy-ant-1.9.4.jar
and the core engine
jalopy-1.9.4.jar
. These must be added to the class path.
You can do this in a number of ways:
Add the two JAR files to the SCM repository and explicitly load the tasks using a class path you set up in the build file. This is often the best approach as there’s no need for any work by the individual developers.
Copy the two JAR files from the temporary directory into a private directory and add the directory contents to the path via Ant’s
-lib
option. You can include this directory in the ANT_ARGS environment variable for automatic inclusion.Copy the two JAR files from the temporary directory into the
$HOME/.ant/lib
folder below your home directory. The library will be available on all projects which may lead to library version conflicts.Copy the two JAR files from the temporary directory into the
$ANT_HOME/lib
directory of your Ant installation. The library will be available to all users of a machine on all projects which may lead to library version conflicts.
Please note that you should make sure that no other Jalopy binaries are in the class path.
Again you might need to check the global $ANT_HOME/lib
directory of
your Ant installation, the user specific $HOME/.ant/lib
folder and
any directories you include with the -lib option when running Ant, and remove any older
jalopy-*.jar
entries.
Although Jalopy ships with sensible default settings (mimicking the Sun Java coding convention), you most likely want to configure the formatter to match your needs (adding copyright headers, tune Javadoc handling and the like). For such, Jalopy comes with a graphical configuration tool that lets you interactively customize the settings. See Chapter 2, Configuration for an in-depth discussion of the available options.
To display the configuration tool, you should use the matching wrapper script
for your platform. The wrapper scripts are called
jalopy.xxx
. Open a shell and invoke the script with the
--configure
option:
% jalopy --configure
Or you can execute the JAR directly with
% java -jar jalopy-1.9.4.jar --configure
When you’re done configuring the settings, you should export the code convention as described in Section 2.1.1.11, “Export code convention”. The exported settings file is typically used as part of the Jalopy task configuration in the build script.
Before you can use the Jalopy Ant task in your build scripts, you have to define the task. This can be done in several ways, depending on the Ant and Jalopy versions you use.
The most conservative way to define the task that works with all versions, is to utilize
the
<taskdef>
element in your build script and specify the class name of the Jalopy task. In order to
achieve a self-contained build, you should not place the Jalopy libraries
into your Ant /lib
folder, but use the classpath
attribute to point to the binaries:
Example 4.1. Task definition with specific class path
<taskdef name="jalopy"
classname="com.triemax.JalopyTask"
classpath="${deps}/jalopy-ant-1.9.4.jar" />
Please note that it’s sufficient to reference the Jalopy Ant task library, if the core engine file sits in the same directory (which should be the norm).
If the Jalopy libraries have been added to the Ant class path (by placing them in the
Ant/lib
folder), you can simply bind the task as follows:
Example 4.2. Task definition with global search path
<taskdef name="jalopy" classname="com.triemax.JalopyTask" />
After the task has been defined, you can use it in the same manner like any other task:
Example 4.3. Task usage without namespace
<target name="format"> <jalopy ...> ... </jalopy> </target>
Since Jalopy 1.9.3, you can utilize the library feature available with Ant 1.6 or later. When the library has been added to the Ant class path, you can either bind the task globally for the whole script:
Example 4.4. Task definition via project namespace declaration
<project name="foo" xmlns:triemax="antlib:com.triemax" ...> ... </project>
Or limited to a specific target:
Example 4.5. Task definition via target namespace declaration
<target name="jalopy" xmlns:triemax="antlib:com.triemax" /> ... <target/>
Declaring the namespace will automatically load the task and you can access it using the prefixed name defined in the declaration:
Example 4.6. Task usage with namespace
<target name="format"> <triemax:jalopy ...> ... </triemax:jalopy> </target>
But it is usually more sensible to leave the Ant class path alone and instead explicitly handle the class path in the build script to achieve a self-contained build process:
Example 4.7. Task definition with typedef
<target name="format"> <typedef resource="com/triemax/antlib.xml" classpath="${deps}" /> <jalopy ...> ... </jalopy> </target>
Nested <fileset> elements can and should be used to specify the source files and/or directories:
Example 4.8. Target specification using fileset
<target name="format"> <jalopy ...> <fileset dir="${dir.src.java}"> <include name="**/*.java" /> </fileset> </jalopy> </target>
You can also set user environment variables for a run by using nested <variable> elements.
The task itself can take several parameters to control the runtime behavior of Jalopy. The parameters are optional. When omitted, your current profile settings will be used. But it is recommended that at least a settings file is specified. The valid parameters are listed in the table below.
Table 4.1. Jalopy Ant task parameters
Attribute | Type | Description | Since | Required |
---|---|---|---|---|
backup | Boolean | Sets whether backup copies of all processed source files should be kept. When omitted, the corresponding code convention setting will be used (see Section 2.2.2.2, “Backup”) | 1.0 | No |
classpath | Path | The class path for type resolution. Please refer to Appendix A, “Type Resolution” for the list of features which require type resolution. If you don’t use any of these features, it’s not required to set anything here. Otherwise the referenced path must contain all types that are needed by your project. Specifying the Java runtime classes is optional; if they are omitted, the runtime classes used by Ant will be automatically added | 1.9.3 | No |
classpathref | String | The class path for type resolution, given as a reference. Please refer to Appendix A, “Type Resolution” for the list of features which require type resolution. If you don’t use any of these features, it’s not required to set anything here. Otherwise the referenced path must contain all types that are needed by your project. Specifying the Java runtime classes is optional; if they are omitted, the runtime classes used by Ant will be automatically added | 1.0 | No |
convention | String | Sets the location to the code convention settings file to use. Given either relative to the project’s base directory or as an absolute local path or internet address (refer to Section 2.1.1.11, “Export code convention” for information how to export your settings). When omitted, and no profile is specified, the settings of the currently active profile will be used | 1.0 | No |
destdir | String | Sets the destination directory to create/copy all formatting output into. If the given directory does not exist, it will be created. When omitted, all input files will simply be overridden | 1.0 | No |
encoding | String | Sets the encoding that controls how Jalopy interprets text files containing characters beyond the ASCII character set. Defaults to the platform default encoding | 1.0 | No |
failonerror | Boolean | Sets whether a run should be held if errors occurred. Defaults to “true” | 1.0 | No |
file | String | Specifies a single source file to format. | 1.0 | Yes, if no fileset is specified |
fileformat | String | Sets the file format of the output files. The file format controls what end of line character is used. Either one of “UNIX”, “DOS”, “DEFAULT” or “AUTO” can be used (case insensitive). Defaults to “AUTO” | 1.0 | No |
force | Boolean | Sets whether the formatting of files should be forced, even if a file is up-to-date. Defaults to “false” | 1.0 | No |
fork | Boolean | Sets whether the processing should be performed in a separate VM. Defaults to “false” | 1.0 | No |
history | String | Sets the history policy to use. Either one of “ADLER32”, “CRC32” or “NONE” can be used (case insensitive). When omitted, the corresponding code convention setting will used (see Section 2.2.2.1, “History”) | 1.0.3 | No |
inputEncoding | String | Sets the character encoding that controls how Jalopy interprets input text files containing characters beyond the ASCII character set. Defaults to the platform default encoding. Please note that this setting always overrides encoding | 1.6 | No |
javadoc | String | Indicates whether Javadoc related messages should be printed. Defaults to “true” | 1.0 | No |
loglevel | String | Specifies the logging level for message output. Either one of “ERROR”, “WARN”, “INFO” or “DEBUG” can be used (case insensitive). When omitted, the current code convention settings will be used (see Section 2.6.1, “Categories”) | 1.0 | No |
log | String | Specifies the log file to use for logging output. The format of the logging output is determined by the extension of the given file. Valid extensions are “.log” for a custom plain text format, “.xml” for a plain XML format and “.html” for an hierarchical HTML report. When omitted, the current code convention setting will be used (see Section 2.6.2, “Logging”) | 1.0.3 | No |
outputEncoding | String | Sets the character encoding Jalopy uses to write files. Defaults to the platform default encoding. Please note that this setting always overrides encoding | 1.6 | No |
profile | String | Sets the Jalopy profile that should be activated during the run (refer to Section 2.1.1.1, “Main window” for more information about profiles). The currently active profile will be restored after formatting. Please note that the profile must exist! | 1.5 | No |
repository | Boolean | Indicates whether the type repository should be used for type resolution. When disabled, an alternative implementation with different characteristics is used. Only meaningful when a class path has been defined via classpath or classpathref. You may want to disable the repository if you commonly format a single file or only a small set of files in order to avoid the maintenance overhead of the type repository. Please be aware that the import expansion feature requires the type repository. Defaults to “true” | 1.6 | No |
test | Boolean | Sets whether formatting output should actually be written to disk. If set to “true” no output will be written to disk. The default is “false” | 1.0 | No |
threads | Integer | Specifies the number of processing threads to use. Integer between
1 - 8 . When omitted, the current code
convention setting will be used
| 1.0 | No |
Some parameters may be specified as nested elements.
<classpath>
The class path might be alternatively specified using the nested <classpath> element. It is recommended to use the same class path as with your compile target, to ensure that all project types are accessible.
Since 1.9.3
Example 4.9. Class path declaration using nested classpath element
<jalopy ...> <classpath> <pathelement name="${classpath}" /> </classpath> ... </jalopy>
<variable>
Used to specify a user environment variable that shall be available during a run. If a variable with the given name already exists, its value will be overridden during the run and restored afterwards.
Since 1.0
Table 4.2. Nested variable parameter
Attribute | Type | Description | Required |
---|---|---|---|
name | String | Specifies the name of the variable. | Yes |
value | String | Specifies the value that should be assigned to the variable. | Yes |
Example 4.10. Variable declaration
<jalopy ...> <variable name="author" value="John Doo" /> ... </jalopy>
The following example demonstrates how you can make use of the Jalopy Ant task.
Note that the format
target depends on the compile
target. This way we can make sure that the provided class path covers the complete type
information.
Example 4.11. Example Ant build file
<?xml version="1.0" ?> <project name="myProject" default="format" basedir="."> <property name="dir.compile" value="${basedir}/build/classes" /> <property name="dir.lib" value="${basedir}/lib" /> <property name="dir.src.java" value="${basedir}/src/main/java" /> <!-- ==================================================================== --> <!-- Defines the project class path --> <!-- ==================================================================== --> <path id="project.classpath" > <!-- our compilation directory --> <pathelement location="${dir.compile}" /> <!-- needed 3rd party libraries --> <fileset dir="${dir.lib}" > <include name="**/*.jar" /> </fileset> </path> <!-- ==================================================================== --> <!-- Compiles the project sources --> <!-- ==================================================================== --> <target name="compile"> <javac destdir="${dir.compile}" classpathref="project.classpath"> <src path="${dir.src.java}" /> </javac> </target> <!-- ==================================================================== --> <!-- Formats the project source --> <!-- ==================================================================== --> <target name="format" depends="compile"> <!-- Load the task using explicit class path. Please note that it’s sufficient to reference the Jalopy Ant library JAR if the core engine JAR sits in the same directory (which should be the norm) --> <typedef resource="com/triemax/antlib.xml" classpath="${basedir}/../deps/jalopy-ant-1.9.4.jar" /> <!-- Invokes Jalopy as follows: - load the code convention from the given url - the import optimization feature will work (if enabled in the code convention), because a class path reference is given - all formatted files will have unix file format (\n) - override the convention to use alder32 checksums of files as history policy - override the convention to use loglevel 'info' - the task will use 4 worker threads - the user environment variable 'author' is set and the value 'John Doo' assigned Since Jalopy 1.3 an include pattern is no longer necessary if you want to format all supported source files of a directory structure --> <jalopy convention="http://shared-server/cisco-omg.xml" classpathref="project.classpath" fileformat="unix" history="adler32" loglevel="info" threads="4"> <variable name="author" value="John Doo" /> <fileset dir="${dir.src.java}"> <include name="**/*.java" /> </fileset> </jalopy> </target> </project>