Monday, March 7, 2011

Create Maven Site

Your first step in order to play with Maven will be to download Maven and install the same. It’s very simple and you just need to follow instructions available here:


I’m using Maven 3.

Now we need to create a project, for which you need to execute below command:

mvn archetype:generate
-DgroupId=com.mycompany.app
-DartifactId=my-project
-DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false

Archetype allows you to create your project, and there is several archetypes available for creating web application, command line application and many more. I’ve barely scratched the surface.

Once you run above command, maven will create a project and you can see the set of instructions getting executed command window.



In your project directory (my-project) , you could see your POM file.

<project ….">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-project</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>my-project</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
The pom file is core of your project’s configuration. It is a single configuration file that contains the majority of information required to build a project in just the way you want.

Let’s add some more information about our project.

-          Adding License details.
Paste below code snippet in your POM file (just before <dependencies> element starts.

  <licenses>
        <license>
                        <name>Apache 2</name>
                        <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
                        <distribution>repo</distribution>
                        <comments>A business-friendly OSS license</comments>
        </license>
  </licenses>

-          Add organization details
You can also add details about your organization (paste below content after <licenses> details). We usually do this after adopting Maven at corporate level.

  <organization>
        <name>Mix and Match Organization</name>
        <url>http://www.mixandmatch.com</url>
  </organization>

-          Add team details
You could also add your team information, member’s name, timezone etc.

  <developers>
        <developer>
                        <id>Vicky</id>
                        <name>Vicky Sharma</name>
                        <email>solid.api@gmail.com</email>
                        <url> http://www.mixandmatchblogs.com/vicky </url>
                        <organization>Mix And Match</organization>
                        <organizationUrl> http://www.mixandmatch.com </organizationUrl>
                        <roles>
                                        <role>developer</role>
                        </roles>
                        <timezone>+5</timezone>
        </developer>
  </developers>



-          Add site plugin (after <dependencies> section)
Actually you do not need to add this plugin, but there is a bug with Maven 3 that needs this plugin to be added in your project’s POM.

<build>
        <plugins>
                        <plugin>            
                                        <groupId>org.apache.maven.plugins</groupId>            
                                        <artifactId>maven-site-plugin</artifactId>            
                                        <version>3.0-beta-3</version>        
                        </plugin>           
        </plugins>
</build>

-          Allow the project to create Javadoc for our artifacts:

To do this, add another plugin in <reporting> section (after <build>)

  <reporting>    
        <plugins>        
                        <plugin>            
                                        <groupId>org.apache.maven.plugins</groupId>            
                                        <artifactId>maven-javadoc-plugin</artifactId>            
                                        <version>2.7</version>            
                        </plugin>    
        </plugins>
  </reporting>


Ok.. Enough details added J

Now let’s run our site.

On command prompt type: mvn site:run
If you have just installed Maven, it may take a while on the first run. This is because Maven is downloading the most recent artifacts (plugin jars and other files) into your local repository. You may also need to execute the command a couple of times before it succeeds. This is because the remote server may time out before your downloads are complete.
Once our site starts running, command window appears like screen below:



Now type http://localhost:8080 in your browser and you will be able to see your newly created site.



Click on various links and Maven will display you appropriate details; for example when I clicked on ‘Dependencies’, I could see all the details about dependencies configured in our project.


You can check Project reports navigation to see Javadoc.

Maven internally uses jetty to run this web site.

This is not enough to actually learn how to create sites with Maven. You can refer Maven site or some of the links mentioned below for detailed information.

References:

Create Maven Plugin

Your first step in order to play with Maven will be to download Maven and install the same. It’s very simple and you just need to follow instructions available here:


I’m using Maven 3.

You also need to have good understanding of Maven lifecycle and plugins to really benefit from this post. You can refer below link to know more about Maven:
You can also check out Maven site for more details.
A plugin can have several MOJOs, where each MOJO refers to a goal. So when you type
$ mvn jar:jarGoal
That means you’re trying to execute ‘jarGoal’ from ‘jar’ plugin.
Based on my experience, I believe existing plugins offered by Maven will be more than enough for your project needs; however that does not stops you from writing your own plugin J and we’re here for the same.


Your first step will be to create a plug in project.

-          Create Plugin Project

To create a plugin project, you should use the Maven Archetype plugin. The following command-line will create a plugin with a groupId of org.sonatype.mavenbook.plugins and the artifactId of first-maven-plugin:

$ mvn archetype:create \
-DgroupId=org.sonatype.mavenbook.plugins \
-DartifactId=first-maven-plugin \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-mojo

The Archetype plugin is going to create a directory named my-first-plugin which contains the following POM.
<?xml version="1.0" encoding="UTF-8"?>
<project>
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.sonatype.mavenbook.plugins</groupId>
      <artifactId>first-maven-plugin</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>maven-plugin</packaging>
      <name>first-maven-plugin Maven Mojo</name>
      <url>http://maven.apache.org</url>
      <dependencies>
            <dependency>
                  <groupId>org.apache.maven</groupId>
                  <artifactId>maven-plugin-api</artifactId>
                  <version>2.0</version>
            </dependency>
            <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>3.8.1</version>
                  <scope>test</scope>
            </dependency>
      </dependencies>
</project>

-          Create MOJO(or goal)
Mojo class is nothing but description of your Goal. You could write this class in Java or any of the scripting language like Groovy, BeanShell, Ruby etc.
Each Mojo class is going to implement the org.apache.maven.plugin.Mojo interface, the Mojo implementation shown in our example implements the Mojo interface by extending the org.apache.maven.plugin.AbstractMojo class.

The Mojo interface is concerned with two things: logging the results of goal execution and executing a goal. When you are writing a custom plugin, you'll be extending AbstractMojo. AbstractMojo takes care of handling the setLog() and getLog() implementations and contains an abstract execute() method. When you extend AbstractMojo, all you need to do is implement the execute() method.

package org.sonatype.mavenbook.plugins;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

/**
 * Echos an object string to the output screen.
 *
 * @goal echo
 * @requiresProject false
 */
public class EchoMojo extends AbstractMojo {
                /**
                 * Any Object to print out.
                 *
                 * @parameter expression="${echo.message}" default-value="Hello World..."
                 */
                private Object message;

                public void execute() throws MojoExecutionException, MojoFailureException {
                                getLog().info(message.toString());
                }
}

Other thing to note is that, we have also provided our goal a name: ‘echo’ (with annotation on top @goal echo), and also mentioned that our Mojo (or goal) accepts a parameter echo.message whose default value is ‘Hello World’.
That means, while executing our plugin’s goal (i.e. echo), we could write:
$mvn org.sonatype.mavenbook.plugins:first-maven-plugin:1.0-SNAPSHOT:echo –Decho.message=Print me
And on console you could see a message : Print me
Specifying the groupId, artifactId, version, and goal on the command-line is cumbersome. What we want is to execute our goal with simple command like
$mvn first:echo
To achieve this, we need to tell Maven that ‘first’ actually means org.sonatype.mavenbook.plugins:first-maven-plugin:1.0-SNAPSHOT”, and this mapping need to be done in your ~/.m2/settings.xml file.

In your ~/.m2/settings.xml, add this line:
<pluginGroups>
<pluginGroup>org.sonatype.mavenbook.plugins</pluginGroup>
</pluginGroups>

That’s it! You’re done!
Now on command line, if you type:
$mvn first:echo
You can see ‘Hello World…’ on console.
This worked because our project adhered to a naming convention for Maven plugins. If your plugin project has an artifactId which follows the pattern maven-first-plugin or first-maven-plugin, maven will automatically assign a plugin goal prefix of first to your plugin. Well, you’re also free to customize any name to your plugin, so instead of first:echo, you could also execute your goal with second:echo or whatever you like. Check maven-plugin-plugin Plugin for more details.

References:

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.