Wednesday, February 9, 2011

Drawing ANT build file

Sometimes best way to learn about any new Open source Framework, APIs, Tools etc is to look in their source code. Documentation does help, but most of the time, specially for Open source software they fall short of their purpose.

I usually start by looking at build script, following different targets..corresponding source code and so on. For some of the Frameworks...let's say Log4J, you'll see plenty of targets in build file..It does not stop there, those targets refer other targets that reside in some other build file and it goes on.

Tracking all the build dependency by looking at the build file becomes very difficult, especially for the projects having more than 50-60 targets.

I’m going to show you how you can prepare a diagram for your build file.

I will be using Vizant and GraphViz for this purpose.
1)      Download Vizant jar file from sourceforge
2)      Install GraphViz. You can get .msi file from GraphViz web site. Check this URL for downloading installer. http://www.graphviz.org/Download_windows.php

Once you’re done installing the GraphViz, let’s use a sample build file to see, how it works.

build.xml  

<project name="HelloWorld" basedir="." default="main">
    <property name="src.dir" value="src"/>
    <property name="build.dir" value="build"/>
    <property name="classes.dir" value="${build.dir}\classes"/>
    <property name="jar.dir" value="${build.dir}\jar"/>
    <property name="main-class" value="oata.HelloWorld"/>

    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>
   
    <target name="compile">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
    </target>
   
    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar basedir="${classes.dir}"
             includes="**\*.class"
             destfile="${jar.dir}\${ant.project.name}.jar">
        <manifest>
            <attribute name="Main-Class"
                value="${main-class}"/>
        </manifest>
        </jar>
    </target>
   
    <target name="run" depends="jar">
        <java jar="${jar.dir}\${ant.project.name}.jar" fork="true"/>
    </target>
   
    <target name="clean-build" depends="clean,jar"/>
   
    <target name="main" depends="clean,run"/>
</project>

3) I will now be adding a new target for preparing an image for this build file.

First I will define a new task:
    <taskdef name="vizant" classname="net.sourceforge.vizant.Vizant" classpath="lib/vizant.jar"/>
    
You can keep vizant.jar in whatever location you want on your local system, I kept it in /lib folder.

Next step, is to add a target that you can invoke for creating a pictorial representation of your build file.

    <target name="draw">
        <vizant antfile="build.xml" outfile="build.dot"/>
        <exec executable="dot" ><arg line="-Tpng build.dot -o build.png"/></exec>
    </target>

    
4) Once you add these lines to your build file, type

D:\Project-RND\RAndD>ant draw

You will see usual output on command window.

Buildfile: D:\Project-RND\RAndD\build.xml
draw:
BUILD SUCCESSFUL
Total time: 0 seconds

5) Now check your project folder, you will be seeing two new files: build.dot and build.png

I'm attaching build.png for your reference, and you can now see target dependency tree.


For more information, check this URL: http://vizant.sourceforge.net/#parameters

Happy reading. Leave a comment, if you've any question.


Monday, February 7, 2011

Building ANT

I have used ANT for so many projects in past; It's pretty simple..isn't? Today I thought of building ANT itself, was just curious to know how I can do this.

1) Ant site has svn information to get the latest source code from trunk. I used below URL:

http://svn.apache.org/repos/asf/ant/core/trunk

Once you have source code, your eclipse would look like as shown below.



2) Next step is to build the source code.

Go to the folder where you've checked out ANT and run this command:

build -Ddist.dir=<directory_to_contain_Ant_distribution> dist

For me, It was:


build -Ddist.dir=D:\Project-RND\MyAnt

Once the processing gets over, your folder structure will look like 


In /bin and /lib you will see familiar files like ant.bat, ant.cmd, ant.jar etc.


The /lib however does not contain all the jar files, you usually see when you download ANT binaries. So now lets get those jars.

3) Log on to newly built ANT folder and run below commands

ant -f fetch.xml -Ddest=[option]
where option is one of the following, as described above:
  • system - store in Ant's lib directory (Recommended)
  • user - store in the user's home directory
  • optional - store in Ant's source code lib/optional directory, used if building Ant source code
When I ran the same with dest as ‘system’, I got plenty of new jars created in lib folder, and now your /bin and /lib contains most of the ANT jars to go ahead and start building your project from your newly compiled ANT installation.



ANT document also mention, If you wish to install the build into the current ANT_HOME directory, you can use:
build install    (Windows)
sh build.sh install    (Unix)
Actually this step assumes that before building ANT, you have already an ANT installation in your system and ANT_HOME environment variable points to that location. Now if you want to update that location with this latest build, you just need to type build install on command prompt and current ANT_HOME directory will get updated with newly compiled Ant libraries and binaries. That’s why it mention at the bottom:

Both the install and install-lite targets will overwrite the current Ant version in ANT_HOME. Try running this command (a word of caution, take a back up of your ANT_HOME before running this command)


This is not exhaustive tutorial to build ANT, for that you can check ANT web site.  


Note: I'm using Java 6 on Windows XP for building ANT.


Thanks for reading and get back to me for any queries.

Saturday, February 5, 2011

From Factory to AbstractFactory


Following last statements in my previous blog, lets consider there is a need to run our application this time with SQL Server Database.

Essential problems we could see is that:
-          The Connection, Statements and Resulset objects now belongs to SQL Server database, so we have family of similar objects; one set belongs to Oracle and other set belongs to SQL Server DB; and lets also assume that application need to run with even MySQl DB, so we have third set of similar object.

Off course in this case we have to create family of similar objects.

Factory method pattern is not going to work here, it is not designed to handle family of similar products.

So now what?

Hmm… AbstractFactory?

Intent of this pattern says:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

In below diagram (from GOF Book), lets replace classes to make things more clear.




WidgetFactory -> MyDatabaseObjects (An abstraction that our application uses to create DB objects)
-          CreateScrollBar -> CreateConnection //Returns a Connection object
-          CreateWindow -> CreateStatements //Returns a Statement object
-           
-          MotifWidgetFactory -> SQLServerDatabaseObjects //Returns SQL server db objects
-          PMWidgetFactory -> MySQLDatabaseObjects //Returns MySQL db objects

-          ScrollBar -> Connection (java.sql.Connection)
-          Window -> Statement (java.sql.Statement)

-          PMWindow -> MySQL concrete Statement class
-          MotifWindow -> SQLServer concrete Statement class

-          PMScrollbar -> MySQL concrete Connection class
-          MotifScrollBar -> SQLServer concrete Connection class

So, now you could imagine what happens when we change the driver classes in our application. When you change the database to SQL Server, application uses SQLServer related Factory; similary when you need to use MySQL, application uses MySql related factory.. and when you do this, nowhere in your source code you’re going to specify concrete classes for any of the database objects. (See Intent above)

Hope this makes thing more clear. Write back, If I could be of any help on this topic

Confusion about Factory method pattern

Hmm... I was going through Factory method pattern from GOF book, later looked in "The Design pattern" book by James W. Cooper. I consider GOF book as reference. My one of the confusion I believe is going to be clear now.
If you compare the two books, it’s my thought that NamerFactory class in Cooper book is basically one of the abstraction identified by GOF (Application) and 'Namer' relates to "Document" in GOF.

I think in Cooper book, there should be one more class ConcreteNamerFactory or MyNamerfactory that should inherit from NamerFactory to make the example more complete.

So we should have overall 6 classes:

Cooper                                   GOF
-------                                     -----
Namer                                    Document
FirstFirst                                MyDocument
LastFirst                                 MyDocument
NamerFactory                        Application
ConcreteNamerFactory         MyApplication


Above diagram is from GOF Book.

Below should be the steps to create an instance of Namer:

1) NamerFactory factory = getFactory(String whichFactory);//This method localize the code for searching apprpriate factory and in simple language, will have some if-else logic to choose appropriate factory based on provided parameter (whichFactory). Call to this method and selection of appropriate factory is out of scope for 'Factory method' design pattern. I mentioned this to give a complete picture.

Above line of code could also be written as:
NamerFactory factory = new ConcreteNamerFactory();

2) Namer namer = factory.getNamer(); // This piece of code does what GOF book says:
  • Creator relies on its subclasses to define the factory method so that it returns an instance of the appropriate ConcreteProduct.
Here 'creator' refers to an instance of 'NamerFactory' that is an abstraction in our application. However NamerFactory  is delegating the responsibility of creating an instance of a concrete product i.e. 'Namer' to one of its sub classes i.e. 'ConcreteNamerFactory'.

Within getNamer() method of 'ConcreteNamerFactory' you can write all the code for instantiating your concrete product.

Following DDD patterns, factory pattern also gives you flexibility to externalize any knowledge your product needs for its creation. A nice example I remember, Printer cannot build itself, actually they are built in assembly line by providing all construction material. 'Factory' also does job of assembly line and build your Printer object; this relax printer (i.e. your product) from knowing how to build myself (i.e. instead of placing complex creation logic in Object's constructor, better place it outside).

To summarize:
  • -          Factory method pattern is helpful when you’ve to create a single Product(or Namer)
  • -          This will allow you to delegate the responsibility for creating one Product to a subclasse.
  • -          If you’ve multiple Product(or Namer) to create, still you’re fine using this patter i.e. assuming you’ve different kind of Namers (FIrstNamer, LastNamer, MiddleNamer, NoNamer etc..), you can write as many method in NamerFactory class and get those Objects created..
-          However, If apart from different kind of Namers, you also have different Namer families..then you need to look for my next Blog.
To conclude and to simplify things further , let’s considering an application that uses JDBC with Oracle database. However we also expect that in order to run our application with SQL Server DB, we need to only change the driver..rest JDBC will take care. This works because we use Connection, Statements, ResultSet abstraction in our application for which concrete classes reside inside Oracle provided client libraries and we simply don’t worry about them. Somewhere in the whole flow, a factory method resides that generate these objects for us. By the time, we are using Oracle consistently, we are happy because our factory methods instantiate appropriate Connection, Statements and ResultSet objects.

So factory pattern no doubt is an essential part of our application  development.