Building And Deploying the REST application with Maven

This exercise is to build and deploy the REST application here using MAVEN.
http://cuppajavamattiz.com/2012/11/09/a-simple-restful-service/

Download maven and add it to your PATH environment variable.Create a folder where you want your maven app to be configured. Go to this folder on your command prompt and run the following command:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mattiz.testapp -DartifactId=MavenRest
This will create a maven project structure for a web application within a folder called MavenRest which will also contain a pom.xml
Create a folder src/main/java and copy your java source files to this folder.
The project will have a structure similar to this:

A default pom.xml is created within the MavenRest folder.
Overwrite it with this source:

<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>com.mattiz.testapp</groupId>
  <artifactId>MavenRest</artifactId>
  <packaging>war</packaging>
  <version>0</version>
  <name>MavenRest Maven Webapp</name>
  <url>http://maven.apache.org</url>
	<properties>
		<org.springframework-version>3.0.2.RELEASE</org.springframework-version>
		<com.springsource-version>3.0.2.RELEASE</com.springsource-version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>com.springsource.org.codehaus.jackson.mapper</artifactId>
			<version>1.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>com.springsource.org.codehaus.jackson</artifactId>
			<version>1.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>com.springsource.org.apache.commons.beanutils</artifactId>
			<version>1.8.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>com.springsource.org.apache.commons.logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.aop</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.asm</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.beans</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.core</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.expression</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.web.servlet</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>org.springframework.web</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<repositories>
		<!--For any snapshot build (Spring 2.5-SNAPSHOT, Spring Web Flow 2.0-SNAPSHOT, etc.) the Maven
		artifacts for that build will be uploaded to the Spring Snapshot repository.-->
		<repository>
            <id>SpringSource Enterprise Bundle Repository - External Bundle Snapshots</id>
            <url>http://repository.springsource.com/maven/bundles/snapshot</url>
        </repository>

        <!-- Required, as Spring JavaConfig has dependencies on released versions of SpringSource products -->
        <repository>
            <id>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</id>
            <url>http://repository.springsource.com/maven/bundles/release</url>
        </repository>

        <!-- Required, as Spring JavaConfig has dependencies on External OSGi bundles -->
        <repository>
            <id>SpringSource Enterprise Bundle Repository - External Bundle Releases</id>
            <url>http://repository.springsource.com/maven/bundles/external</url>
        </repository>
		<repository>
            <id>org.springframework.maven.snapshot</id>
            <name>Spring Maven Snapshot Repository</name>
            <url>http://maven.springframework.org/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
	</repositories>
	<build>
		<finalName>MavenRest</finalName>
		<!--Property file creation Starts-->
		<resources>
			<resource>
		        <directory>src/main/resources</directory>
		        <filtering>true</filtering>
		     </resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>tomcat-maven-plugin</artifactId>
				<configuration>
					<server>TomcatServer</server>
					<path>/${project.build.finalName}</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Points to note
The packaging is declared as war so that maven knows that a WAR file has to be created. The dependencies are mostly declared without any scope so these will be included in the war WEB-INF/lib folder. The jar javax.servlet.jar is declared as “provided” which means it will not be included in the war and will be provided at runtime by the tomcat container. The dependencies for this project are available at the following site:
http://ebr.springsource.com/repository/app/bundle

The repository where these dependencies and the maven plugins are available at the URLs mentioned under repositories. Also the plugins required are declared in the pom. we use two plugins:

  • maven-compiler-plugin
  • tomcat-maven-plugin

The clean, compile, package plugins that we use are available by default with maven. You will need to declare the repositories for the plugins you have explicitly declared in pom.xml.
Copy
applicationContext.xml
cxf-servlet.xml
rest-services-config.xml
web.xml
Place them in /MavenRest/src/main/webapp/WEB-INF/
You need to overwrite the existing web.xml from the older application.
Your app is now ready to build.
Run the following on a command prompt
mvn clean package
You will see that a war file is created under target folder.
You can convert your maven folder structure to a maven Eclipse project. Run this on the command prompt in the folder which contains the pom.
mvn eclipse:eclipse
Import the project created using import existing projects into Eclipse.
Set M2_REPO eclipse variable in Eclipse to your maven repository location to resolve build errors.

You can auto deploy the war created in target folder to a tomcat of your choice using tomcat-maven-plugin declared in the pom.
See this declaration:

			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>tomcat-maven-plugin</artifactId>
				<configuration>
					<server>TomcatServer</server>
					<path>/${project.build.finalName}</path>
				</configuration>
			</plugin>

It tells Maven to deploy the war in the currently running instance of tomcat at the 8080 port. The context path is defined by ${project.build.finalName} which in our case it MavenRest.
You need to make some changes in Maven’s settings.xml too.
Add this to conf/settings.xml under servers.

	<server>
      		<id>TomcatServer</id>
      		<username>admin</username>
      		<password>admin</password>
    	</server>

This is assuming your tomcat manager has the username and password admin/admin
Make this change in the tomcat-users.xml to enable this username and password.

        <role rolename="manager"/>
        <role rolename="admin"/>
        <user username="admin" password="admin" roles="admin,manager"/>

When you run
mvn tomcat:deploy
Maven will deploy the war created by pom.xml to the tomcat’s webapp folder currently running on the 8080 port. You need to have tomcat running on this port in the first place.
Run tomcat:redeploy to redeploy the war after changes.
Check application with the URL
http://localhost:8080/MavenRest/restservices/mattiz
using a REST client.

Short note on Maven
Maven is just a framework of plugins that uses Ant underneath. It stores jar files in a remote repository for easy sharing. Maven is easier to use; there is no need to write large build.xml files since most common tasks are available as plugins.
You have a settings.xml and one or several pom.xml.
settings.xml
The settings.xml is optional and is used to specify the repository location, security and deployment settings. If it is absent default values are used. It may also contain repository authentication informatio and username and passoword for the server on which the generated package is deployed.
Maven Repository
Maven will automatically download artifacts from the online maven repository if the dependencies are not locally available in the repository. The jars are placed in a local maven repository(relative path=.m2/repo).
pom.xml
It contains the following information:

  • the type of packaging,
  • information about the project dependencies(artifacts or dependencies of those artifacts),
  • artifact name
  • artifact version,
  • artifact scope(default scope means the generated package will include this artifact while “provided” means they will be provided by the deployment container),
  • maven plugins that are to be used during the build process(certain plugins such as mvn:clean, mvn:compile, mvn:package are included by default within the maven distribution),
  • dependencies on third party maven repositories

When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information such as project dependencies, then executes the goal. The goal may be a custom goal or one that is available in a maven plugin or inbuilt into maven.
Maven commands
mvn-test
mvn compile
mvn package
mvn install
are common maven commands.
Advantages
Maven has plugins for all “common” tasks so that all you have to do is add some information to configuration files. These are built over Ant tasks.
Refer this post for the maven download of the REST app http://cuppajavamattiz.com/2012/11/09/a-simple-restful-service/

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: