Showing posts with label Apache. Show all posts
Showing posts with label Apache. Show all posts

Friday, 25 March 2016

Logging in Ant : Live Practical Example

Hi! Hows it going guys! Today is an auspicious Indian day - Holi : the festival of colors. On this good auspicious day am also presenting a fresh new 200th post.

Let's look into a simple concept - how to take logs in Apache Ant builds. By taking logs I mean how to capture the console output in a log file.

The foremost thing you need to be aware of is the <record> task with which we tell Ant when and where to capture the console into a log. Detailed explanation of the task can be read at Ant Official Manual.

Let's use a familiar example that we used in our earlier posts - Ant build.xml updates : Feb 28 and Ant - Build.xml Introduction.

Check out our new updated build.xml below :

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="generate-docs" basedir=".">

<property name="build.home" value="${basedir}" />
<property file="build.properties"/>

<tstamp>
<format property="timestamp" pattern="dd-MM-yyyy"/>
</tstamp>

<target name="clean">
<delete dir="${build.home}/src" />
<delete dir="${build.home}/bin" />
<delete dir="${build.home}/lib" />
<delete dir="${build.home}/test" />
<delete dir="${build.home}/dist" />
<delete dir="${build.home}/docs" />
<delete dir="${build.home}/logs" />
</target>

<target name="createdir" depends="clean">
<mkdir dir="${build.home}/src" />
<mkdir dir="${build.home}/bin" />
<mkdir dir="${build.home}/lib" />
<mkdir dir="${build.home}/test" />
<mkdir dir="${build.home}/dist" />
<mkdir dir="${build.home}/docs" />
<mkdir dir="${build.home}/logs" />
<record name="${build.home}/logs/build.log" action="start" append="no" loglevel="verbose" />
</target>

<path id="classpath">
<pathelement location="${build.home}/bin"></pathelement>
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

<target name="copydir" depends="createdir">
<copydir src="${workspace.src}"
dest="${build.home}/src"></copydir>
</target>

<target name="compile" depends="copydir, clean">
<javac classpathref="classpath" includeantruntime="false"
srcdir="${build.home}/src"
destdir="${build.home}/bin"
includes="**/*.java"></javac>
</target>

<target name="create-jar" depends="compile">
<jar basedir="${build.home}/bin" destfile="${build.home}/dist/${timestamp}-TestJar-${versionnum}.jar"
includes="**/*.class">
<manifest>
<attribute name="Main-class" value="com.ironcladzone.FileSize"/>
</manifest>
</jar>
</target>
<target name="generate-docs" depends="create-jar">
<javadoc sourcepath="${build.home}/${src.dir}" destdir="docs"/>
<record name="${build.home}/logs/build.log" action="stop" append="no" />
</target>


</project>

Notice the "createdir" task where we started the recorder and in the "generate-docs" we stopped it. The loglevel parameter is an optional one. In this example you see we have set the loglevel to verbose. It means it will have much detailed information in the logs than the default console output. However it can have any of the 5 possible values - error, warn, info, verbose, debug. Experiment with each level to see the difference.

Btw check the directory structure for reference.

Friday, 4 March 2016

Kill process or application using Apache Ant

Hello friends. In our last post we saw how to execute a shell script from Apache Ant. In today's post lets see if we could use Ant to kill some running processes.

For example lets open the TextWrangler app. Now lets try to close it using Ant build.

Consider a shell script kill-wrangler.sh as below :

kill -9 `ps -ef | grep TextWrangler | awk '{print $2}'`;

Now we'll execute the above bash script and kill the corresponding PID (process ID) for the TextWrangler app using the Ant build. Consider the following build.xml

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="kill-process" basedir=".">

<target name="kill-process">
<exec executable="/bin/bash">
<arg value="kill-wrangler.sh"/>
</exec>
</target>


</project>

In this we execute the above bash script kill-wrangler.sh and close the application. You could grep (search) the running processes for any other program/string. For instance you could kill some Java process or maybe stop some application. Okay guys, signing out for now. Will post some more cool stuff in the forthcoming days. Stay tuned...

Tuesday, 1 March 2016

Call shell script from Apache Ant build on Mac OS X

Guys, you might come across some situations where you need to invoke shell and execute a bash script while building a project using Apache Ant. In today's example let's see how to run a shell script from within an Ant build.

For illustration, lets create a simple bash script to list the disk usage of our system. Let's name this file as "DiskUsage.sh"

#!/bin/bash

# Sample shell script to be invoked from an Ant build

echo "Disk usage is as follows : \n"
echo "=========================== \n"


df -h

Now let's create a simple build-test.xml using the exec command to invoke the shell as follows :

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="call-shell" basedir=".">

<target name="call-shell">
<exec executable="/bin/bash">
<arg value="DiskUsage.sh"/>
</exec>
</target>


</project>

Run the ant build from command line as ant -f build-test.xml. Note that the shell script and build.xml happen to be at the same location/hierarchy within the project. If your shell script lies elsewhere, you may perhaps want to refer to its path in the build.properties instead.

You could also invoke the "expect" scripting prompt in a similar fashion to execute an expect script that we discussed in our earlier post.

More information on the exec can be read at the official Ant manual.

Sunday, 28 February 2016

Ant - Build.xml Updates - 28 Feb

Guys, in my earlier posts we learnt how to write a simple basic build.xml and also learnt about the build.properties. Today we'll modify, update our build.xml to include some more functionality.

Let's add the following 2 features :
  • add a MANIFEST.MF file to the jar package which will contain the packaging information
  • create documentation using javadoc.
Check out the updated build.xml with the tasks for the same below :

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="generate-docs" basedir=".">

<property name="build.home" value="${basedir}" />
<property file="build.properties"/>

<tstamp>
<format property="timestamp" pattern="dd-MM-yyyy"/>
</tstamp>

<target name="clean">
<delete dir="${build.home}/src" />
<delete dir="${build.home}/bin" />
<delete dir="${build.home}/lib" />
<delete dir="${build.home}/test" />
<delete dir="${build.home}/dist" />
<delete dir="${build.home}/docs" />
<delete dir="${build.home}/logs" />
</target>

<target name="createdir" depends="clean">
<mkdir dir="${build.home}/src" />
<mkdir dir="${build.home}/bin" />
<mkdir dir="${build.home}/lib" />
<mkdir dir="${build.home}/test" />
<mkdir dir="${build.home}/dist" />
<mkdir dir="${build.home}/docs" />
<mkdir dir="${build.home}/logs" />
</target>

<path id="classpath">
<pathelement location="${build.home}/bin"></pathelement>
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

<target name="copydir" depends="createdir">
<copydir src="${workspace.src}"
dest="${build.home}/src"></copydir>
</target>

<target name="compile" depends="copydir, clean">
<javac classpathref="classpath" includeantruntime="false"
srcdir="${build.home}/src"
destdir="${build.home}/bin"
includes="**/*.java"></javac>
</target>

<target name="create-jar" depends="compile">
<jar basedir="${build.home}/bin" destfile="${build.home}/dist/${timestamp}-TestJar-${versionnum}.jar"
includes="**/*.class">
<manifest>
<attribute name="Main-class" value="com.ironcladzone.FileSize"/>
</manifest>
</jar>
</target>
<target name="generate-docs" depends="create-jar">
<javadoc sourcepath="${build.home}/${src.dir}" destdir="docs"/>
</target>

</project>

Notice the "create-jar" target where we have added the <manifest></manifest> tags in which we have mentioned the main class for instance. This will create a MANIFEST.MF file within the jar. I'll write a new post on the Manifest file soon.

Also for the javadoc, we have a new target named "create-documentation". If you check the folder structure, you'll find the index.html within the docs folder. Try looking into the index.html, you'll see the class and package details in a sample webpage decorated with the default javadoc css stylesheet.

Thursday, 25 February 2016

Ant - Delete only files from directories

For an Ant build, if you just want to delete files without deleting the directory, consider the following. For illustration, we'll take the folder structure as mentioned in our earlier post.

Let's say I want to only clear the class files generated in the bin/com/ironcladzone directory.

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="clean-class-files" basedir=".">

<property name="build.home" value="${basedir}" />
<property file="build.properties"/>

<target name="clean-class-files">
<delete>
<fileset dir="${bin.dir}">
<include name="**/*"/>
</fileset>
</delete>
</target>


</project>

Note : by using **/*, it will recursively delete all the files from the bin/ subdirectories. Using the <fileset> tag, we mention the directory tree, on which the delete operation needs to be performed.

List only target names from build.xml in Apache Ant

In Apache Ant, for listing only the target names defined in the build.xml, all we have to do is type the following from command line :

Eg :

ant -p build.xml

Output :

Buildfile: /Users/ironcladzone/Documents/workspace/AntBuildTest/build/build.xml

Main targets:

Other targets:

 clean
 compile
 copydir
 create-jar
 createdir

Default target: create-jar

Wednesday, 24 February 2016

Build properties in Ant - An Introduction

Guys, in our previous post we saw a basic build.xml file with some basic target definitions. Note that we mentioned a property or two in it. But have you ever wondered, what happens if you have multiple properties to define? Yea that's when we use a build.properties file.

Let's create a build.properties file and we define all the properties inside it. The advantage of using a properties file is that whenever you want to modify/update the value of any property you only have to do it once in this build.properties. You don't have to look into the build.xml to see when and where you want to modify things. This makes life a lot easier, which otherwise would have been cumbersome.

Ok so I create a new build.properties with the following updated folder structure :


You must have observed that in our older post we included some hardcoded directory paths directly in the build.xml. That's a quite crude way to define the paths and is not advisable. Hardcoded paths should be avoided as much as possible. So what we do is create some properties and define their values equal to the directory paths. Something like this :

versionnum=1.3
workspace.src=/Users/ironcladzone/Documents/workspace/AntBuildTest/src
src.dir=/Users/ironcladzone/Documents/workspace/AntBuildTest/build/src
bin.dir=/Users/ironcladzone/Documents/workspace/AntBuildTest/build/bin

Note that we have also included an additional property named "versionnum" to assign a certain version number to the jar package that we created.

Now we only need to provide a reference to these properties in our build.xml file. Take a look at the new updated build.xml below :

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="create-jar" basedir=".">

<property name="build.home" value="${basedir}" />
<property file="build.properties"/>

<target name="clean">
<delete dir="${build.home}/src" />
<delete dir="${build.home}/bin" />
<delete dir="${build.home}/lib" />
<delete dir="${build.home}/test" />
<delete dir="${build.home}/dist" />
</target>

<target name="createdir" depends="clean">
<mkdir dir="${build.home}/src" />
<mkdir dir="${build.home}/bin" />
<mkdir dir="${build.home}/lib" />
<mkdir dir="${build.home}/test" />
<mkdir dir="${build.home}/dist" />
</target>

<path id="classpath">
<pathelement location="${build.home}/bin"></pathelement>
</path>

<target name="copydir" depends="createdir">
<copydir src="${workspace.src}"
dest="${src.dir}"></copydir>
</target>

<target name="compile" depends="copydir, clean">
<javac classpathref="classpath" includeantruntime="false"
srcdir="${src.dir}"
destdir="${bin.dir}"
includes="**/*.java"></javac>
</target>

<target name="create-jar" depends="compile">
<jar basedir="${build.home}/bin" destfile="${build.home}/dist/TestJar-${versionnum}.jar"
includes="**/*.class"></jar>
</target>

</project>

Don't you think the new build.xml looks much cleaner now? It does! Right? Okay so with today's post I've introduced you to the concept of properties. In the next post, we'll try to refine the script and introduce some new features into it. Keep visiting folks.

BONUS TIP : Note that properties are immutable. So once a build starts, the value assigned to the properties remain constant. However, if am not wrong, we can update the properties at build time using the propertyFile task. Note that this is different than the <property file> tag. Notice there is no space there in the propertyFile task.

Ok guys, signing out for the day. Let's meet up again tomorrow. Till then, ciao!

Saturday, 20 February 2016

Ant - Build.xml example on Mac OS X

In today's post guys, we'll cover the topic of building a very simple Java based project using Apache Ant. We'll learn how to write a basic build.xml file for building it.  Let's first look into the code for build.xml and then we'll breakdown the code with the explanation.

build.xml :

<?xml version="1.0" encoding="UTF-8"?>

<project name="AntBuildTest" default="create-jar" basedir=".">

<property name="build.home" value="${basedir}" />

<target name="clean">
<delete dir="${build.home}/src" />
<delete dir="${build.home}/bin" />
<delete dir="${build.home}/lib" />
<delete dir="${build.home}/test" />
<delete dir="${build.home}/dist" />
</target>

<target name="createdir" depends="clean">
<mkdir dir="${build.home}/src" />
<mkdir dir="${build.home}/bin" />
<mkdir dir="${build.home}/lib" />
<mkdir dir="${build.home}/test" />
<mkdir dir="${build.home}/dist" />
</target>

<path id="classpath">
<pathelement location="${build.home}/bin"></pathelement>
</path>

<target name="copydir" depends="createdir">
<copydir src="/Users/ironcladzone/Documents/workspace/AntBuildTest/src"
dest="/Users/ironcladzone/Documents/workspace/AntBuildTest/build/src"> </copydir>
</target>

<target name="compile" depends="copydir">
<javac classpathref="classpath" includeantruntime="false"
srcdir="/Users/ironcladzone/Documents/workspace/AntBuildTest/build/src"
destdir="/Users/ironcladzone/Documents/workspace/AntBuildTest/build/bin"
includes="**/*.java"></javac>
</target>

<target name="create-jar" depends="compile">
<jar basedir="${build.home}/bin" destfile="${build.home}/dist/TestJar.jar"
includes="**/*.class"></jar>
</target>


</project>

Now let's look into the folder structure in the Eclipse Package Explorer :


Now, let's get down to the explanation guys :

1. First of all, AntBuildTest is my project workspace which has the source code in it.

2. Next I created a build directory under which I created the above build.xml file.

3. Now in the builds.xml I have defined various steps/tasks also known as targets viz : clean, createdir, copydir, compile, create-jar. Note that a build.xml will still successfully build even if it doesn't have a single target defined.

4. For every build.xml file, we first have to define the <project></project> tag, in which we mention the project name, basedir and default target to be executed.

5. Basedir is the location of the current root directory in which build.xml exists i.e the absolute path

6. The default target that we define, will be the task/target which will be executed. Now the target can have dependencies on other targets.

7. Note that target can have one or many dependencies on multiple targets.

8. The 'clean' target is the target to delete all sub-directories that we create in the 'createdir' target. So every time we perform a clean build, the directories created in the last build will be deleted.

9. In the 'createdir' target, we make directories namely : src, bin, lib, test, dist.

10. We now want to copy the source code from our local workspace to the 'src 'directory that we create in the 'createdir' target,. So in the 'copydir' target we define the step to copy the source code.

11. Now once we have the source code, we need to compile it right. So we define the 'compile' target wherein we define 'srcdir' i.e the location where we have our java files. Also we mention the 'destdir' as the bin folder i.e this is where we want our .class files to be saved.

12. During compilation, we need to specifically tell the xml where the .class files would be. So we need to define the classpath. 

13. We define the classpath i.e the bin directory which will have the .class files.

<pathelement location="${build.home}/bin"></pathelement>

14. After compilation, we define the 'create-jar' target, in which we create the jar package - TestJar.jar. Make sure not to miss the .jar file extension. Note that we have mentioned the include parameter for including the **/*.class files that need to be included in it.

15. We have also defined the 'destfile' parameter i.e the location where we want the jar file to be saved i.e the 'dist' directory for distribution.

16. Oh and I missed the 'lib' directory, which will basically hold the external jar files required for our project.

17. Well, I hope I covered the simple basic fundamental points surrounding an Ant build.  Let me know if I missed any point guys. If I did, I'll try to cover them in detail in an another upcoming post covering an advanced scenario. Till then, ciao!
Related Posts Plugin for WordPress, Blogger...
eXTReMe Tracker