Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Friday, 15 April 2011

Database Connection Pooling in Tomcat using Eclipse

While using Maven as build tool in our project, I found it very difficult to create a Dynamic Web Project which supports Maven dependencies and can execute in Eclipse! I have seen lot of people using Maven just as build tool and for local setup uses jar files in some /lib directory. I wanted to remove this dependencies on local /lib for jar files and resolve everything with Maven. My project should be a Dynamic web project with Maven dependencies enabled.
Here is a simple tutorial which you can go through to create Dynamic Web Project having Maven enabled in Eclipse. This project can be used as base project and can be easily converted to most kind of project like Struts based, Spring MVC based etc.

Required Tools

For this tutorial, I assume you have following setup in your machine.
1. JDK 1.5 or above (download)
2. Eclipse 3.2 or above (download)
3. Maven 2.0 or above (download)
4. M2Eclipse Plugin (download)

Step 1: Create Maven Project in Eclipse

Create a new project in Eclipse. Goto File > New > Project.. and select Maven Project from the list. Click Next.
eclipse-maven-new-project
Enter “MavenWeb” as Project name and click Next. On Configuration screen, select war in Packaging and also check the checkbox for src/main/webapp.
new-maven-project
Once done, click Finish. This will create a Maven project in Eclipse.

Step 2: Generate Eclipse Project with WTP

Let us convert the Maven project to Dynamic Web Project for Eclipse. For this we will use following maven command.
1
mvn eclipse:eclipse -Dwtpversion=1.5
Goto the folder where the new project is created and execute above command.
C:\Workspace\Test\MavenWeb>mvn eclipse:eclipse -Dwtpversion=1.5

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - MavenWeb:MavenWeb:war:0.0.1-SNAPSHOT
[INFO] task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse]
[INFO] Adding support for WTP version 1.5.
[INFO] Using Eclipse Workspace: C:\Workspace\Test
[INFO] no substring wtp server match.
[INFO] Using as WTP server : Apache Tomcat v5.5
[INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER
[INFO] Not writing settings - defaults suffice
[INFO] Wrote Eclipse project for "MavenWeb" to C:\Workspace\Test\MavenWeb.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Wed Jul 28 13:55:09 CEST 2010
[INFO] Final Memory: 7M/30M
[INFO] ------------------------------------------------------------------------
That’s it. We just created Dynamic Web Project from Maven project. Now refresh the project in Eclipse.

Step 3: Change Project Facet

The above step by default set the project facet to JDK 1.4. We need to modify this and set project facet to JDK 5. Right click on MavenWeb project and select Properties (shortcut: Alt+Enter). From the Properties dialog box, select Project Facets. Now click on “Modify Project…” button and change the project facet to Java 5.0
project-facet-maven-eclipse

Step 4: Setting Build Path

We need to specify the Maven jar dependencies in Java Build Path of our MavenWeb project. Open Properties.. dialog box (Alt+Enter) and select Java Build Path. Click “Add Library..” button and select “Maven Managed Dependencies” and click Finish.
maven-eclipse-build-path

Step 5: Hello World Servlet

Our dynamic web project with maven support is done now. Let us add a small Hello World servlet to this project and see how it works.
Open pom.xml from root folder and copy following content into it.
File: pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>MavenWeb</groupId>
    <artifactId>MavenWeb</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <description></description>
    <build>
                <plugins>
                        <plugin>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
                                        <source>1.5</source>
                                        <target>1.5</target>
                                </configuration>
                        </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.0</version>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
    </dependencies>
</project>
 
Also create a servlet file HelloWorldServlet.java. We will add this servlet in net.viralpatel.maven package.
File: /src/main/java/net/viralpatel/maven/HelloWorldServlet.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package net.viralpatel.maven;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class HelloWorldServlet extends HttpServlet {
 
    private static final long serialVersionUID = 1031422249396784970L;
 
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
 
        resp.setContentType("text/html");
 
        PrintWriter out = resp.getWriter();
        out.print("Hello World from Servlet");
        out.flush();
        out.close();
    }
}
Once the servlet is created, let us configure this in web.xml. Note that in our maven project no web.xml is present. We will create one at /src/main/webapp/WEB-INF/ location.
File: /src/main/webapp/WEB-INF/web.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>HelloWorldServlet</display-name>
    <welcome-file-list>
        <welcome-file>hello-world</welcome-file>
    </welcome-file-list>
 
    <servlet>
        <servlet-name>HelloWorldServlet</servlet-name>
        <servlet-class>
            net.viralpatel.maven.HelloWorldServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorldServlet</servlet-name>
        <url-pattern>/hello-world</url-pattern>
    </servlet-mapping>
</web-app>

That’s All Folks

Our dynamic web project with Maven support in Eclipse is completed. Run the web project in eclipse (Alt+Shirt+X, R)
hello-world-maven-eclipse-web-project
 

Introduction to Apache Maven: A build framework & build automation tool

For a quite while I had been using Ant build tool for building my Java projects. Since few days I have been switching to Apache Maven, an open source build framework that can be used to build almost all the projects in Java, .Net and other platforms. Maven was created by Sonatype’s Jason van Zyl in 2002.

What is Maven?

Maven, a Yiddish word meaning accumulator of knowledge, was originally started as an attempt to simplify the build processes in the Jakarta Turbine project. Maven is really a process of applying patterns to a build infrastructure in order to provide a coherent view of software projects.

Maven is a build tool

maven-build-tool-command-prompt
Maven 2.0 is based around the central concept of a build lifecycle. What this means is that the process for building and distributing a particular artifact (project) is clearly defined.
A Build Lifecycle is Made Up of Phases. Each of these build lifecycles is defined by a different list of build phases, wherein a build phase represents a stage in the lifecycle.

Maven is dependency management tool

maven-dependency-diagram
Dependency management is one of the features of Maven that is best known to users and is one of the areas where Maven excels. There is not much difficulty in managing dependencies for a single a project, but when you start getting into dealing with multi-module projects and applications that consist of tens or hundreds of modules this is where Maven can help you a great deal in maintaining a high degree of control and stability.

A Documentation tool

maven-documentation-screen
Maven helps you to generate documentation of your project and create a Project Site. Not only does it generates the site code, but it can deploy the website on a server. Maven has several reports that you can add to your web site to display the current state of the project. These reports take the form of plugins, just like those used to build the project.
Internationalization in Maven is very simple, as long as the reports you are using have that particular locale defined.

Objectives of Maven

  • Make the development process visible or transparent
  • Provide an easy way to see the health and status of a project
  • Decreasing training time for new developers
  • Bringing together the tools required in a uniform way
  • Preventing inconsistent setups
  • Providing a standard development infrastructure across projects
  • Focus energy on writing applications

Project Object Model (pom.xml)

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target; the source directory, which is src/main/java; the test source directory, which is src/main/test; and so on.
The POM was renamed from project.xml in Maven 1 to pom.xml in Maven 2. Instead of having a maven.xml file that contains the goals that can be executed, the goals or plugins are now configured in the pom.xml. When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.

POM Sample

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-core-api-container</artifactId>
<name>Cargo Core Container API</name>
<version>0.7-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies/>
<build/>
[...]

* project – root
* modelVersion – should be set to 4.0.0
* groupId – the id of the project’s group.
* artifactId – the id of the artifact (project)
* version – the version of the artifact under the specified group

Build Profiles in Maven

Profiles are specified using a subset of the elements available in the POM itself (plus one extra section), and are triggered in any of a variety of ways. They modify the POM at build time, and are meant to be used in complementary sets to give equivalent-but-different parameters for a set of target environments (providing, for example, the path of the appserver root in the development, testing, and production environments). As such, profiles can easily lead to differing build results from different members of your team. However, used properly, profiles can be used while still preserving project portability. This will also minimize the use of -f option of maven which allows user to create another POM with different parameters or configuration to build which makes it more maintainable since it is runnning with one POM only.

Different types of Profile

* Per Project – Defined in the POM itself (pom.xml).
* Per User – Defined in the Maven-settings (%USER_HOME%/.m2/settings.xml).
* Global – Defined in the global maven-settings (%M2_HOME%/conf/settings.xml).
* Profile descriptor – a descriptor located in project basedir (profiles.xml)

Repositories in Maven

repository-maven-local-remoteA repository in Maven is used to hold build artifacts and dependencies of varying types. There are strictly only two types of repositories: local and remote. The local repository refers to a copy on your own installation that is a cache of the remote downloads, and also contains the temporary build artifacts that you have not yet released. The local and remote repositories are structured the same way so that scripts can easily be run on either side, or they can be synced for offline used. In general use, the layout of the repositories is completely transparent to the Maven user, however.

Declaring a Remote Repository

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 (http://repo1.maven.org/maven2/).
To override this, you need to specify a repositories element as follows:
<project>
...
<repositories>
<repository>
<id>my-internal-site</id>
<url>http://myserver/repo</url>
</repository>
</repositories>
...
</project>

Plugins in Maven

Maven is really just a core framework for a collection of Maven Plugins. In other words, plugins are where much of the real action is performed, plugins are used to: create jar files, create war files, compile code, unit test code, create project documentation, and on and on. Almost any action that you can think of performing on a project is implemented as a Maven plugin.
Plugins are the central feature of Maven that allow for the reuse of common build logic across multiple projects. They do this by executing an “action” (i.e. creating a WAR file or compiling unit tests) in the context of a project’s description – the Project Object Model (POM). Plugin behavior can be customized through a set of unique parameters which are exposed by a description of each plugin goal (or Mojo).