These notes were developed by Rod Byrne and adapted by Andrew Vardy.
A collection of Java files is used to create a receipt printing program.
% ls -l src
total 20
-rw------- 1 rod rod 568 Mar 17 18:41 ExemptTaxableProduct.java
-rw------- 1 rod rod 1962 Mar 17 18:50 FormattedReceiptPrinter.java
-rw------- 1 rod rod 670 Mar 17 18:41 Product.java
-rw------- 1 rod rod 607 Mar 17 18:41 TaxableProduct.java
-rw------- 1 rod rod 1229 Mar 17 18:41 TypedProduct.java
% wc src/*java
26 65 568 src/ExemptTaxableProduct.java
63 209 1962 src/FormattedReceiptPrinter.java
32 90 670 src/Product.java
23 88 607 src/TaxableProduct.java
48 171 1229 src/TypedProduct.java
192 623 5036 total
% grep main src/*java # find the main class
src/FormattedReceiptPrinter.java: public static void main( String[] args ) {
%
In addition to storing the java files in the src directory, the class files are stored in the classes directory. The project directory contains:
% ls -l
total 24
-rw------- 1 rod rod 1608 Mar 17 19:58 build.xml
drwx------ 2 rod rod 4096 Mar 19 15:04 classes
-rw------- 1 rod rod 36 Mar 17 18:56 manifest.txt
-rw------- 1 rod rod 3950 Mar 19 14:49 pcsv.jar
-rw------- 1 rod rod 3473 Mar 19 15:04 rp.jar
drwx------ 2 rod rod 4096 Mar 17 18:50 src
%
To start off in a known state, the contents of the classes directory and rp.jar are deleted with:
% rm -f classes/*
% rm -f rp.jar
% ls -l classes
total 0
%
The java files can be compiled with:
% javac -d classes src/*.java
% ls -l classes
total 20
-rw------- 1 rod rod 457 Mar 19 15:05 ExemptTaxableProduct.class
-rw------- 1 rod rod 2456 Mar 19 15:05 FormattedReceiptPrinter.class
-rw------- 1 rod rod 609 Mar 19 15:05 Product.class
-rw------- 1 rod rod 521 Mar 19 15:05 TaxableProduct.class
-rw------- 1 rod rod 770 Mar 19 15:05 TypedProduct.class
% ls -l src # class file here
total 20
-rw------- 1 rod rod 568 Mar 17 18:41 ExemptTaxableProduct.java
-rw------- 1 rod rod 1962 Mar 17 18:50 FormattedReceiptPrinter.java
-rw------- 1 rod rod 670 Mar 17 18:41 Product.java
-rw------- 1 rod rod 607 Mar 17 18:41 TaxableProduct.java
-rw------- 1 rod rod 1229 Mar 17 18:41 TypedProduct.java
%
The -d flag causes javac to save all the class files in the classes directory.
The program can be run with:
% java -cp classes FormattedReceiptPrinter
d-store
Thu Mar 19 15:05:27 NDT 2015
tooth p... 1 3.50 0.00
eggs 6 1.80 0.27
pop 20 10.00 0.00
total price: 15.30
total tax: 0.27
total: 15.57
%
The -cp specifies the class path. The class path is where java searches for any class files. The shell variable CLASSPATH can also be used.
% CLASSPATH=classes java FormattedReceiptPrinter
d-store
Thu Mar 19 15:05:28 NDT 2015
tooth p... 1 3.50 0.00
eggs 6 1.80 0.27
pop 20 10.00 0.00
total price: 15.30
total tax: 0.27
total: 15.57
% echo "'$CLASSPATH'" # note CLASSPATH only exists in the above cmd
''
% export CLASSPATH=classes
% java FormattedReceiptPrinter
d-store
Thu Mar 19 15:05:28 NDT 2015
tooth p... 1 3.50 0.00
eggs 6 1.80 0.27
pop 20 10.00 0.00
total price: 15.30
total tax: 0.27
total: 15.57
%
All the class files and manifest file can be bundled into a jar file with:
% cd classes
% jar cvfm ../rp.jar ../manifest.txt *.class
added manifest
adding: ExemptTaxableProduct.class(in = 457) (out= 313)(deflated 31%)
adding: FormattedReceiptPrinter.class(in = 2456) (out= 1385)(deflated 43%)
adding: Product.class(in = 609) (out= 363)(deflated 40%)
adding: TaxableProduct.class(in = 521) (out= 346)(deflated 33%)
adding: TypedProduct.class(in = 770) (out= 496)(deflated 35%)
%
The manifest.txt contains:
Main-Class: FormattedReceiptPrinter
All the *.class are now stored in rp.jar. The flags cvfm stand for: create, verbose, file, manifest. The jar file is listed with:
% jar tvf rp.jar
0 Thu Mar 19 15:05:28 NDT 2015 META-INF/
105 Thu Mar 19 15:05:28 NDT 2015 META-INF/MANIFEST.MF
457 Thu Mar 19 15:05:26 NDT 2015 ExemptTaxableProduct.class
2456 Thu Mar 19 15:05:26 NDT 2015 FormattedReceiptPrinter.class
609 Thu Mar 19 15:05:26 NDT 2015 Product.class
521 Thu Mar 19 15:05:26 NDT 2015 TaxableProduct.class
770 Thu Mar 19 15:05:26 NDT 2015 TypedProduct.class
%
The flags tvf stand for: table, verbose, file. The program can be executed with:
% java -jar rp.jar
d-store
Thu Mar 19 15:05:29 NDT 2015
tooth p... 1 3.50 0.00
eggs 6 1.80 0.27
pop 20 10.00 0.00
total price: 15.30
total tax: 0.27
total: 15.57
%
The ant tool automates the building of a software system. It was created to automate the building of systems that use the Java programming language. The ant tool uses a build file (build.xml) based on XML that describes which tasks to execute to build a target. Ant uses the following terms:
The greetings project has one target called sayit. The sayit target contains the echo task. The echo task outputs its contents to the screen. A description element can be used to document the project. The source of greetings.xml is:
<?xml version="1.0" ?>
<project name="greetings" default="sayit">
<description>
Do a greeting.
</description>
<target name="sayit">
<echo> Hi there. </echo>
</target>
</project>
The command to invoke ant on this file is:
% ant -f greetings.xml
Ant will then produce:
Buildfile: greetings.xml
sayit:
[echo] Hi there.
BUILD SUCCESSFUL
Total time: 0 seconds
Properties are set with the element:
<property name="name" value="value" />
where the name attribute defines the name and the value is found in the value attribute.
The value of the property is retrieved with:
${property-name}
Properties are use when a configuration value can appear more than once. Properties can be specified on the command line with:
-Dname=value
The properties can be specfied on the command line. Notice there is no property definitions in the build file.
<?xml version="1.0" ?>
<project name="greetings" default="sayit" >
<description>
Demonstrate properties.
</description>
<target name="init">
<!-- message can appear in the
message attribute -->
<echo message="init( ${projectname} )."/>
</target>
<target name="sayit" depends="init">
<echo>
Project ${projectname} is at
version ${version}
</echo>
</target>
</project>
The command to invoke ant with properties specified on the command line for this file is:
ant -f greetargs.xml -Dprojectname=p1 -Dversion=v1
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/scripts/greetargs.xml
init:
[echo] init( p1 ).
sayit:
[echo]
[echo] Project p1 is at
[echo] version v1
[echo]
BUILD SUCCESSFUL
Total time: 0 seconds
The file attribute to echo can be used to send the output of echo to a file.
<?xml version="1.0" ?>
<project name="file-greetings" default="sayit" >
<property name="result" value="result.txt" />
<description>
Demonstrate properties.
</description>
<target name="init">
<!-- message can appear in the
message attribute -->
<echo message="init( ${projectname} )."/>
</target>
<target name="sayit" depends="init">
<echo file="${result}">
Project ${projectname} is at
version ${version}
</echo>
</target>
</project>
ant -f file-greetargs.xml -Dprojectname=P1 -Dversion=v10
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/scripts/file-greetargs.xml
init:
[echo] init( P1 ).
sayit:
BUILD SUCCESSFUL
Total time: 0 seconds
cat result.txt
Project P1 is at
version v10
Creating and maintaining directory layouts are accomplished with the mkdir, delete, and copy tasks.
The example mkdir task is:
<mkdir dir="some/dir/list" />
This task will create all the directories (if necessary) to the last directory named on the path.
The delete task will delete a file if the file attribute is used, or delete a directory tree if the dir attribute is used.
<delete file="junk" />
<delete dir="classes" />
Files are copied with:
<copy file="stuff" tofile="stuff.bak"/>
A file can be copied to a directory with
<copy file="stuff" todir="backup"/>
More complex file sets can be constructed with the fileset element. Many tasks use the fileset element to select the files to operate on.
All the java files in a directory tree are selected with:
<fileset dir="base_dir">
<include name="**/*.java">
</fileset>
Files can also be excluded from a fileset, for example the following excludes any file with a .bak suffix.
<fileset dir="base_dir">
<include name="**/*">
<exclude name="**/*.bak">
</fileset>
The following ant script contains tasks to save a copy of all java files in a directory, and to remove the backup directory during cleanup.
<?xml version="1.0" ?>
<project name="files" default="backup">
<property name="src.dir" value="src" />
<property name="backup.dir" value="backup" />
<target name="remove">
<delete dir="${backup.dir}" />
<mkdir dir="${backup.dir}" />
</target>
<target name="backup" depends="remove">
<copy todir="${backup.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</copy>
</target>
</project>
The javac task invokes a java compiler to transform java source into class files. The javac task supports that same file selection elements as the fileset element. A ant script to compile a java package and store the class files in a separate directory is:
<?xml version="1.0"?>
<project name="javacc" default="compile">
<property name="src.dir" value="src"/>
<property name="dest.dir" value="classes"/>
<target name="init">
<mkdir dir="${dest.dir}"/>
</target>
<target name="compile" depends="init">
<javac
srcdir="${src.dir}"
destdir="${dest.dir}"
includes="**/*.java"/>
</target>
</project>
The source can be specified with include element inside the javac element.
<?xml version="1.0"?>
<project name="javacc" default="compile">
<property name="src.dir" value="src"/>
<property name="dest.dir" value="classes"/>
<target name="init">
<mkdir dir="${dest.dir}"/>
</target>
<target name="compile" depends="init">
<javac
srcdir="${src.dir}"
destdir="${dest.dir}" >
<include name="**/*.java"/>
</javac>
</target>
</project>
The jar (Java archive) tool is used to manage a collection of class files. It uses the zip archive format. An archive (jar file) is created, specified by the c flag, with:
% jar cvf file.jar input-files ...
A listing of the jar file's contents is done with:
% jar tvf file.jar
Extracting, specified by x, the contents is done by:
% jar xvf file.jar
The v flag means verbose, it causes jar to describe its progress. The f flag means that the next argument is the name of the jar file.
The classes that make up a Java program can be stored into a jar file and a manifest file can be used to specify the main class. The program contained in the jar file is executed with:
% java -jar file.jar
The manifest file must contain the name of the main class. For example, the main class is specified with:
Main-Class: FormattedReceiptPrinter
The class path used by the Main-Class: can be specified by the following line in the manifest file.
Class-Path: path1/t.jar path2/tt.jar
on a line by itself in the manifest file. A jar file containing a manifest is created with:
% jar cvmf manifest-file file.jar input-files
The m flag indicates that a manifest file follows. The f flag indicates the name of the jar file to create. Since the flags are specified as mf, the the manifest file precedes the jar file.
The manifest file, specifies that the main class is FormattedReceiptPrinter and the class path includes path1/t.jar and path2/tt.jar.
Creating jar files is supported by the jar task in the ant build tool. An example of creating a jar file for the vds program with a manifest is:
<?xml version="1.0"?>
<project name="jar" default="jar">
<!-- creates jar files that can be run with
java -jar rp.jar -->
<target name="jar" depends="compile">
<jar jarfile="rp.jar" basedir="classes"
includes="**/*.class">
<manifest>
<attribute name="Main-Class"
value="FormattedReceiptPrinter" />
</manifest>
</jar>
</target>
</project>
Note the above is only a partial build file.
The main class and class path can be specified by:
<manifest>
<attribute name="Main-Class"
value="FormattedReceiptPrinter" />
<attribute name="Class-Path"
value="path1/t.jar path2/tt.jar" />
</manifest>
Java programs can be executed with the java task. An example is:
<?xml version="1.0"?>
<project name="exercute" default="run">
<target name="run">
<java classname="Test" fork="true">
<arg value="one"/>
<classpath>
<pathelement location="./test.jar"/>
<pathelement path="classes"/>
</classpath>
</java>
</target>
</project>
The fork attribute specifies if a new JavaVM is created to run the program. When fork is "true" an new JavaVM is forked(created).
The ant build file for the receipt project is:
<?xml version="1.0"?>
<project name="receipt" default="help" basedir=".">
<target name="help">
<echo message="ant help -- print this message"/>
<echo message="ant compile -- compiles the source"/>
<echo message="ant run -- run the program"/>
<echo message="ant jar -- create an executable jar"/>
<echo message="ant runjar -- run the executable jar"/>
<echo message="ant clean -- removes classes"/>
</target>
<property name="dest.dir" value="./classes" />
<target name="init">
<mkdir dir="${dest.dir}"/>
</target>
<target name="compile" depends="init">
<javac
includeantruntime="false"
srcdir="src" destdir="${dest.dir}">
<include name="**/*.java"/>
</javac>
</target>
<target name="jar" depends="compile">
<jar jarfile="rp.jar" basedir="classes"
includes="**/*.class">
<manifest>
<attribute name="Main-Class"
value="FormattedReceiptPrinter" />
</manifest>
</jar>
</target>
<target name="run" depends="compile">
<java classname="FormattedReceiptPrinter" fork="true">
<classpath>
<pathelement path="${dest.dir}"/>
</classpath>
</java>
</target>
<target name="runjar" depends="jar">
<java jar="rp.jar" fork="true"/>
</target>
<target name="clean">
<delete includeemptydirs="true">
<fileset dir="classes" includes="**/*"/>
</delete>
</target>
</project>
The project can now be cleaned with:
% ant clean
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/receipt/build.xml
clean:
BUILD SUCCESSFUL
Total time: 0 seconds
%
The project is compiled and tested with:
% ant run
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/receipt/build.xml
init:
compile:
[javac] Compiling 5 source files to /home/rod/MUN/Winter2015/cs2718/notes/ant/receipt/classes
run:
[java] d-store
[java] Thu Mar 19 15:05:35 NDT 2015
[java]
[java] tooth p... 1 3.50 0.00
[java] eggs 6 1.80 0.27
[java] pop 20 10.00 0.00
[java]
[java] total price: 15.30
[java] total tax: 0.27
[java] total: 15.57
BUILD SUCCESSFUL
Total time: 1 second
%
The jar file is created with:
% ant jar
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/receipt/build.xml
init:
compile:
jar:
[jar] Building jar: /home/rod/MUN/Winter2015/cs2718/notes/ant/receipt/rp.jar
BUILD SUCCESSFUL
Total time: 0 seconds
%
A Java file is used to create a CSV printing program is
import au.com.bytecode.opencsv.CSVReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
/**
* Print csv
*
* @author rod
*
*/
public class PrintCSV {
public static void main(String args[] ){
try {
CSVReader reader = new CSVReader(new FileReader(args[0]));
List<String []> rows = reader.readAll();
for ( String[] r : rows ) {
for( String s : r ) {
System.out.printf("%-8s", s );
}
System.out.println();
}
} catch (FileNotFoundException e) {
System.err.println("File not found");
} catch (IOException e) {
System.err.println("Error reading csv");
}
}
}
In addition to storing the java files in the src directory, the class files are stored in the classes directory. The project directory contains:
% ls -l
total 28
-rw------- 1 rod rod 1399 Mar 19 14:26 build.xml
drwx------ 2 rod rod 4096 Mar 19 15:04 classes
-rw------- 1 rod rod 114 Mar 19 14:52 data.csv
drwx------ 2 rod rod 4096 Mar 19 14:12 lib
-rw------- 1 rod rod 49 Mar 19 14:42 manifest.txt
-rw------- 1 rod rod 1244 Mar 19 15:04 pcsv.jar
drwx------ 2 rod rod 4096 Mar 19 14:51 src
%
To start off in a known state, the contents of the classes directory and pcsv.jar are deleted with:
% rm -f classes/*
% rm -f pcsv.jar
%
The java files can be compiled with:
% javac -cp lib/opencsv.jar -d classes src/*.java
% ls -l classes
total 4
-rw------- 1 rod rod 1245 Mar 19 15:05 PrintCSV.class
% ls -l src # class file here
total 4
-rw------- 1 rod rod 819 Mar 19 14:51 PrintCSV.java
%
The -d flag causes javac to save all the class files in the classes directory. The class path is specifed with -cp lib/opencsv.jar.
The program can be run with:
% java -cp classes:lib/opencsv.jar PrintCSV data.csv
red green blue bright
255 0 0 255
0 255 0 255
0 0 255 255
255 0 255 255
255 255 255 255
%
The -cp specifies the class path. The class path is where java searches for any class files. In addition to directories, the class path can contain jar files. The shell variable CLASSPATH can also be used.
% CLASSPATH=classes:lib/opencsv.jar java PrintCSV data.csv
red green blue bright
255 0 0 255
0 255 0 255
0 0 255 255
255 0 255 255
255 255 255 255
%
All the class files and manifest file can be bundled into a jar file with:
% cd classes
% jar cvfm ../pcsv.jar ../manifest.txt *.class
added manifest
adding: PrintCSV.class(in = 1245) (out= 768)(deflated 38%)
%
The manifest.txt contains:
Main-Class: PrintCSV
Class-Path: lib/opencsv.jar
All the *.class are now stored in pcsv.jar. The jar file is listed with:
% jar tvf pcsv.jar
0 Thu Mar 19 15:05:38 NDT 2015 META-INF/
119 Thu Mar 19 15:05:38 NDT 2015 META-INF/MANIFEST.MF
1245 Thu Mar 19 15:05:38 NDT 2015 PrintCSV.class
%
% java -jar pcsv.jar data.csv
red green blue bright
255 0 0 255
0 255 0 255
0 0 255 255
255 0 255 255
255 255 255 255
%
The build file is:
<?xml version="1.0"?>
<project name="lin" default="compile" basedir=".">
<property name="src.dir" value="src"/>
<property name="dest.dir" value="classes"/>
<property name="lib.dir" value="lib"/>
<!-- location of libaray jars -->
<path id="lib-jars">
<fileset dir="${lib.dir}" />
</path>
<target name="init">
<mkdir dir="${dest.dir}"/>
</target>
<target name="compile" depends="init">
<javac includeantruntime="false"
srcdir="${src.dir}"
destdir="${dest.dir}">
<include name="**/*.java"/>
<classpath>
<path refid="lib-jars"/>
</classpath>
</javac>
</target>
<target name="jar" depends="compile">
<jar jarfile="pcsv.jar" basedir="classes"
includes="**/*.class">
<manifest>
<attribute name="Main-Class"
value="PrintCSV" />
<attribute name="Class-Path"
value="lib/opencsv.jar" />
</manifest>
</jar>
</target>
<target name="run" depends="compile">
<java classname="PrintCSV" fork="true">
<arg value="data.csv"/>
<classpath>
<pathelement path="${dest.dir}"/>
<path refid="lib-jars"/>
</classpath>
</java>
</target>
</project>
The project is compiled and tested with:
% ant run
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/csv/build.xml
init:
compile:
run:
[java] red green blue bright
[java] 255 0 0 255
[java] 0 255 0 255
[java] 0 0 255 255
[java] 255 0 255 255
[java] 255 255 255 255
BUILD SUCCESSFUL
Total time: 0 seconds
%
The jar file is created with:
% ant jar
Buildfile: /home/rod/MUN/Winter2015/cs2718/notes/ant/csv/build.xml
init:
compile:
jar:
[jar] Building jar: /home/rod/MUN/Winter2015/cs2718/notes/ant/csv/pcsv.jar
BUILD SUCCESSFUL
Total time: 0 seconds
%
Ant supports many task not mentioned here. Some other tasks are: