Friday 24 February 2012

Maven Tutorial

Apache Maven, is an innovative software project management tool, provides new concept of a project object model (POM) file to manage project’s build, dependency and documentation. The most powerful feature is able to download the project dependency libraries automatically.


Maven Repository


Maven is having local, central and remote repository

Maven local repository

Maven local repository is used to store all your projects’ dependency libraries (plugin jars and other files which downloaded by Maven), . In simple, when you use Maven to build your project, it will automatically download all dependency libraries into your Maven local repository.
Maven local repository is default to home directory :
  1. Unix/Mac OS X – ~/.m2 on
  2. Windows – C:\Documents and Settings\username\.m2 on Windows
Often times, you need to change the default location for maintainability purpose, after all, the .m2 is not a meaningful name.


1. Maven configuration file
Maven local repository is defined in the Maven’s configuration file, for example, {M2_HOME}\conf\setting.xml.

2. Edit it “setting.xml”

Find the following “localRepository” pattern, and define your new Maven local repository inside the “<localRepository>” element like this :
<settings>
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ~/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->
 
<localRepository>D:/maven_repo</localRepository>

3. Saved it

Done, your new Maven local repository is now changed to D:/maven_repo, all the future project’s dependency libraries or related files will be downloaded into this folder.

Maven central repository 

While building a Maven’s project, Maven will check your pom.xml file to download the entire project dependency libraries automatically.
If Maven can’t find the defined dependency libraries in your Maven local repository, it will try to download it from the default Maven central repository, which is http://repo1.maven.org/maven2/.
The maven center repository is revamp, if you visit above site via web browser, it will redirect tohttp://search.maven.org/ automatically.



Maven remote repository

According to Apache Maven :
Downloading in Maven is triggered by a project declaring a dependency that is not present in the local repository (or for a SNAPSHOT, when the remote repository contains one that is newer). By default, Maven will download from the central repository.
In Maven, when you need some libraries that are NOT EXITS the Maven center repository, the process will stopped and output error messages to your Maven console.
Example
The org.jvnet.localizer library is not available at Maven central repository, but Maven remote repository, which is http://download.java.net/maven/2/.
    <dependency>
      <groupId>org.jvnet.localizer</groupId>
      <artifactId>localizer</artifactId>
      <version>1.8</version>
    </dependency>
To tell Maven to go to Maven remote repository like java.net, you need to declared a “remote repository” in your Maven’s pom.xml file like this :
  <repositories>
    <repository>
      <id>java.net</id>
      <url>http://download.java.net/maven/2</url>
    </repository>
  </repositories>
Now, Maven’s dependency libraries look-up sequences is changed to :
  1. Search in Maven local repository, if not found, continue step 2, else exit.
  2. Search in Maven central repository, if not found, continue step 3, else exit.
  3. Search in java.net Maven remote repository – , if not found, prompt error message, else exit.
Maven’s dependency mechanism will download all the necessary dependency libraries automatically, and maintain the version upgrade as well.
Assume you want to use Log4J as your project logging mechanism (actually i more prefer SLF4J). Here is what you do…

 In traditional way

  1. Visit http://logging.apache.org/log4j/
  2. Download the Log4j jar library
  3. Manually include it into your project dependency
  4. All manage by yourself, you need to do everything


If there is Log4j version upgrade, you need to repeat above steps again.

In Maven way
  1. You need to know the log4j “Maven coordinates“, for example
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.14</version>
  1. It will download the log4j version 1.2.14 library automatically. If the “version” tag is ignore, it will upgrade the library automatically when there is a newer version.
    
    
  2. Include “Maven coordinates” into “pom.xml” file, under “<dependencies>” tag
    <dependencies>
        <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.14</version>
        </dependency>
    </dependencies>
  3. While Maven is compiling or building, the log4j will download automatically and put it into your Maven local repository.
  4. All manage by Maven… automatically.




When you use Maven to build your project, “pom.xml” will be parsed, and the Maven search the log4j library in this order :
  1. Search log4j in Maven local repository.
  2. Search log4j in Maven central repository.
  3. Search log4j in Maven remote repository (if define in pom.xml).




include library manually into maven local repository

There are still many Java libraries that are not support for Maven, or may be you want to create a custom library which is required to include it into your Maven local repository.
Fortunately, Maven comes with command to let you include your “non-maven-support” library into your Maven local repository easily.
For example, “kaptcha” is a third party library which is used to generate “captcha” image to stop spamming, but it did not support Maven.
Here’s a guide to show you how to install the “kaptcha” jar into your Maven’s local repository.

1. Install library – mvn install

Download the “kaptcha” jar file and put it into your “C:” drive, and issue following Maven’s command :
mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code 
-DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar
Result :
D:\>mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code 
-DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing c:\kaptcha-2.3.jar to 
D:\maven_repo\com\google\code\kaptcha\2.3\kaptcha-2.3.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Tue May 12 13:41:42 SGT 2009
[INFO] Final Memory: 3M/6M
[INFO] ------------------------------------------------------------------------
Now, the “kaptcha” jar library is included into your Maven local repository.

2. Modify pom.xml file

After installed, you can add the custom library details into your “pom.xml” file like this
<dependency>
      <groupId>com.google.code</groupId>
      <artifactId>kaptcha</artifactId>
      <version>2.3</version>
</dependency>

3. Done

Build it, now the “kaptcha” jar is able to retrieve from your Maven local repository.
Please refer Maven install file documentation for more info.


Including  jar from Project lib/ any folder


        <dependency>
            <groupId>org.opensourzesupport.web</groupId>
            <artifactId>jarFileName</artifactId>
            <version>version</version>
            <scope>system</scope>
            <systemPath>${basedir}/lib/LOCAL.jar</systemPath>
        </dependency>


Enable proxy setting in Maven

There are high chance your company is set up a firewall and force the developers to connect internet via using HTTP proxy. If you are using HTTP proxy, Maven may not able to download the dependency libraries outside. To bypass it, you have to enable the proxy setting in Maven configuration file “settings.xml“.

1. Maven configuration file

Find your Maven configuration file – e.g, {M2_HOME}/conf/settings.xml

2. Edit it “settings.xml”





Find the following pattern
<proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
</proxies




Comment out the proxy setting and fill in your proxy information.
<proxies>
 
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.yourcompany.com</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
 
</proxies>

4. Saved it, Done.

Apache Maven is able to connect to Internet via proxy server now.




Sample MAVEN POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.opensourzesupport.web</groupId>
    <artifactId>MavenDemo</artifactId>
    <version>1.0.0</version> 
    <packaging>war</packaging>
    <name>MavenDemo</name>
    <url>http://maven.apache.org</url>
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <netbeans.hint.deploy.server>JBoss4</netbeans.hint.deploy.server>
    </properties>
    <repositories>
       
        <repository>
            <id>java.net</id>
            <url>http://download.java.net/maven/2</url>
        </repository>
        <repository>
            <id>jboss-public-repository-group</id>
            <name>JBoss Public Repository Group</name>
            <url>http://repository.jboss.org/nexus/content/groups/public/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </repository>
        <repository>
            <id>repository.jboss.org-public</id>
            <name>JBoss.org Maven repository</name>
            <url>https://repository.jboss.org/nexus/content/groups/public</url>
        </repository> 
        <repository>
            <id>prime-repo</id>
            <name>PrimeFaces Maven Repository</name>
            <url>http://repository.primefaces.org</url>
            <layout>default</layout>
        </repository>
        <repository>
            <id>com.springsource.repository.bundles.release</id>
            <name>EBR Spring Release Repository</name>
            <url>http://repository.springsource.com/maven/bundles/release</url>
        </repository>
        <repository>
            <id>com.springsource.repository.bundles.external</id>
            <name>EBR External Release Repository</name>
            <url>http://repository.springsource.com/maven/bundles/external</url>
        </repository>
       
    </repositories>
   
    <dependencies>
<!--          ant -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-script-ant</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
        </dependency>

<!--    Including our own jar files from system -->
        <dependency>
            <groupId>org.opensourzesupport.web</groupId>
            <artifactId>MYLocalDependencyjarFile</artifactId>
            <version>2.9.0.RC1</version>
            <scope>system</scope>
            <systemPath>${basedir}/lib/LOCAL.jar</systemPath>
        </dependency>
       
        <dependency>
            <groupId>com.sun.jmx</groupId>
            <artifactId>jmxri</artifactId>
            <version>1.2.1</version>
        </dependency>

<!--          Primefaces  -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>3.0.RC1</version> 
        </dependency> 
        <dependency> 
            <groupId>org.primefaces.themes</groupId> 
            <artifactId>black-tie</artifactId> 
            <version>1.0.2</version> 
        </dependency> 
        <dependency> 
            <groupId>org.primefaces.themes</groupId> 
            <artifactId>cupertino</artifactId> 
            <version>1.0.2</version> 
        </dependency> 
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>classes12</artifactId>
            <version>10.2.0.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.aopalliance</groupId>
            <artifactId>com.springsource.org.aopalliance</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-configuration</groupId>
            <artifactId>commons-configuration</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
           
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.icu</groupId>
            <artifactId>icu4j</artifactId>
            <version>3.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.jasypt</groupId>
            <artifactId>jasypt</artifactId>
            <version>1.7</version>
        </dependency> 
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.0.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.0.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.aop</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.asm</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.beans</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>org.springframework.binding</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>       
       
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>org.springframework.faces</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>org.springframework.webflow</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.context</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.context.support</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
       
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.core</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.expression</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
       
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.jdbc</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.transaction</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web.servlet</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>
<!--       SPRING  LDAP-->
        <dependency>
            <groupId>org.springframework.ldap</groupId>
            <artifactId>spring-ldap</artifactId>
            <version>1.3.1.RELEASE</version>
            <classifier>all</classifier>
        </dependency>     
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-acl</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jdmk</groupId>
            <artifactId>jmxtools</artifactId>
            <version>1.2.1</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>MySampleMavenProject</finalName>       
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

No comments:

Post a Comment