29
Hands On With Maven Sid Anand (LinkedIn) July 19, 2012

Hands On with Maven

Embed Size (px)

DESCRIPTION

Hands On with Maven -- a gentle introduction to Maven

Citation preview

Page 1: Hands On with Maven

Hands On WithMavenSid Anand (LinkedIn)

July 19, 2012

Page 2: Hands On with Maven

Overview

Maven is a build system providing

A standard directory structure

A standard build lifecycle

The ability to override default behaviors via plug-ins

Dependency management

Page 3: Hands On with Maven

The Maven Directory Structure

Page 4: Hands On with Maven

The Maven Directory Structure• A standard directory structure means that the build tool and the user agree on

where different types of files can be found.

• These conventions make coming up to speed on new projects much easier

• Java Source Tree goes under /src/main/java

• Property files goes under /src/main/resources

• Web App files go under /src/main/webapp

• /src/main/webapp/WEB-INF

• /src/main/webapp/WEB-INF/web.xml

• /src/main/webapp/*.jsp

• /src/main/webapp/*.html

Page 5: Hands On with Maven

/src/main/java root of source tree (e.g. com/linkedin/...)

/src/main/resources Place configuration & property files here

/src/main/scripts Place scripts here

/src/main/webapp Place web resources here (e.g. .jsp, .html)

/src/test/java root of test source tree (e.g. com/linkedin/test/...)

/src/test/resources Place configuration & property files needed for tests

/target/Generated during build. Contains all build output

The Maven Directory Structure

Path Description

Page 6: Hands On with Maven

The Default Maven Life Cycle

Page 7: Hands On with Maven

The Default Maven Life Cycle• A default Maven Life Cycle means that you do not need to manually specify build-

steps and chain them together in each project:

• target = “package” dependsOn = “unit-test”

• target = “unit-test” dependsOn = “compile”

• target = “compile” dependsOn = “validate”

• If you have worked with other build-tools (e.g. Make, Scala Build Tool, Ant, etc...), you will find that you are copying build-specs and specifying this boiler-plate logic often

• Maven specifies a set of standard build steps and also automatically chains them together

• This is part of the Maven framework and is not the responsibility of the user to define

Page 8: Hands On with Maven

Validate Validate things like the pom.xml files

Compile Compile sources after resolving and downloading dependencies

Test Run Unit Tests

Package Create JAR or WAR

Integration-test Run integration tests against the package

Verify Does the package meet quality criteria?

Install Install in local repository

The Default Maven Life CycleBuild Phase Description

• Calling “mvn <build phase>” will call all steps before it in order• e.g. calling “mvn install” will call validate, then compile, then test, then .....

Page 9: Hands On with Maven

Understanding the POM.xml

Page 10: Hands On with Maven

Understanding the POM.xml

The pom.xml file is Maven’s build spec file (e.g. build.xml in Ant)

Page 11: Hands On with Maven

Understanding the POM.xml<project>

<modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <dependencyManagement>...</dependencyManagement> <modules>...</modules> <properties>...</properties>

<!-- Build Settings --> <build>...</build> <reporting>...</reporting>

<!-- More Project Information --> <name>...</name> <description>...</description> <url>...</url> <inceptionYear>...</inceptionYear> <licenses>...</licenses> <organization>...</organization> <developers>...</developers> <contributors>...</contributors>

<!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles></project>

Page 12: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <dependencyManagement>...</dependencyManagement> <modules>...</modules> <properties>...</properties>

<!-- Build Settings --> <build>...</build> <reporting>...</reporting>

<!-- More Project Information --> <name>...</name> <description>...</description> <url>...</url> <inceptionYear>...</inceptionYear> <licenses>...</licenses> <organization>...</organization> <developers>...</developers> <contributors>...</contributors>

<!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles></project>

The elements you will likely use

Page 13: Hands On with Maven

The Basics (POM)

Page 14: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <modules>...</modules> <properties>...</properties>

......</project>

The <groupId, artifactId, version> tuple forms a unique address for a project (and its artifact)

• It is aptly known as a Maven coordinate

packaging defaults to jar. Other options include pom and war

dependencies refers to a set of dependency elements, each of which define a jar that this projects depends on.

For example, if this project required Log4J, you would specify a dependency element containing a Maven coordinate as shown below:

<dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency></dependencies>

Page 15: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <modules>...</modules> <properties>...</properties>

......</project>

To figure out the co-ordinates for a jar when faced with a ClassNoDefFound exception:

<dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency></dependencies>

1. Try searching on Jarvana ( http://jarvana.com/jarvana/ ). This will give you the names of jars containing the Class in question

2. If you know the JAR name, search on Maven Central for all versions of the JAR. Pick the version you like.

Both Maven Central and Jarvana provide Maven coordinates.

Page 16: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <modules>...</modules> <properties>...</properties>

......</project>

The parent and modules elements are needed for parent-child projects.

To illustrate, imagine a typical search-indexing project called Foo.

In our Foo project, imagine that we have 3 build artifacts:

1. An indexer.jar for Indexing code

2. A search.war for Lucene-based servlet code

3. A ui.war for UI-specific code

One way to structure the code is to create 3 Maven modules (ui, indexer, and search) under a common parent (Foo)

Page 17: Hands On with Maven

Understanding the POM.xmlHence, we will have a directory structure as shown below:a Foo directory containing 3 sub-directories and 1 parent pom.xml:

• a search sub-directory• this follows the standard Maven Directory structure• it contains a pom.xml for the search module

• an indexer sub-directory • this follows the standard Maven Directory structure• it contains a pom.xml for the indexer module

• a ui subdirectory

• this follows the standard Maven Directory structure• it contains a pom.xml for the ui module

• a parent pom.xml file

search

indexer

ui

pom.xml

pom.xml

pom.xml

pom.xml

search

indexer

ui

Foo

Page 18: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-search</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

search

indexer

ui

pom.xml

pom.xml

pom.xml

pom.xml

search

indexer

ui

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo</artifactId> <version>1.0</version> <packaging>pom</packaging> <modules> <module>ui</module> <module>search</module> <module>indexer</module> </modules>......</project>

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-indexer</artifactId> <version>1.0</version> <packaging>jar</packaging> <parent>Foo</parent>

......</project><project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-ui</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

Page 19: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-search</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

search

indexer

ui

pom.xml

pom.xml

pom.xml

pom.xml

search

indexer

ui

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo</artifactId> <version>1.0</version> <packaging>pom</packaging> <modules> <module>ui</module> <module>search</module> <module>indexer</module> </modules>......</project>

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-indexer</artifactId> <version>1.0</version> <packaging>jar</packaging> <parent>Foo</parent>

......</project><project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-ui</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

<Parent> Tag in child

pom.xml

Page 20: Hands On with Maven

Understanding the POM.xml<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-search</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

search

indexer

ui

pom.xml

pom.xml

pom.xml

pom.xml

search

indexer

ui

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo</artifactId> <version>1.0</version> <packaging>pom</packaging> <modules> <module>ui</module> <module>search</module> <module>indexer</module> </modules>......</project>

<project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-indexer</artifactId> <version>1.0</version> <packaging>jar</packaging> <parent>Foo</parent>

......</project><project> <modelVersion>4.0.0</modelVersion>

<!-- The Basics --> <groupId>com.linkedin</groupId> <artifactId>Foo-ui</artifactId> <version>1.0</version> <packaging>war</packaging> <parent>Foo</parent>

......</project>

<Parent> Tag in child

pom.xml

3 <Module> Tags in the

parent pom.xml

pom <packaging>

type

Page 21: Hands On with Maven

Understanding the POM.xmlSome Useful Information

-- The child POMs inherit the settings in the parent POM.

-- Calling “mvn <command>” on the parent causes all child POMs to be executed

-- Calling “mvn <command>” on a child POM executes on that single child POM, but does correctly inherit settings from parent POM

search

indexer

ui

pom.xml

pom.xml

pom.xml

pom.xml

search

indexer

ui

Foo

Page 22: Hands On with Maven

More Project Information (POM)

Page 23: Hands On with Maven

Understanding the POM.xml

<!-- More Project Information --> <name>...</name> <description>...</description> <url>...</url> <inceptionYear>...</inceptionYear> <licenses>...</licenses> <organization>...</organization> <developers>...</developers> <contributors>...</contributors>

These fields are pretty self-explanatory. Good to include, especially for open-source projects.

Page 24: Hands On with Maven

Environment Settings (POM)

Page 25: Hands On with Maven

Understanding the POM.xml

<!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles></project>

The repositories tag refers to refers to repositories that Maven should refer to when looking for the jars listed in the dependencies section that we already covered.

If you do not specify a repositories tag, Maven will look in the default repository : http://search.maven.org/#browse (a.k.a. http://repo.maven.apache.org/maven2/ )

If you need to access jars from a private repository (e.g. LinkedIn’s Artifactory) and from the default public repository:

repositories> <repository> <id>public-central</id> <url> http://repo.maven.apache.org/maven2/ </url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>central-private</id> <url>

http://artifactory.corp.linkedin.com......./artifactory/release </url>

<snapshots> <enabled>false</enabled> </snapshots> </repository>

Page 26: Hands On with Maven

Understanding the POM.xml

<!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles></project>

The SCM tag refers to Source Control Management. Maven offers pretty advanced plug-ins for Git and SVN.

An example Git SCM tag is shown below. With this enabled, you can use powerful features in Maven such as release. “mvn release:perform” can release a WAR or JAR to Artifactory or to a public Maven repo.

Once complete, Maven will automatically up-rev the pom.xml version and commit/push the new pom.xml to the Git “origin” server using the Git connect strings in the SCM tag.

<scm> <connection> scm:git:[email protected]:ds-platform/listt.git </connection> <url> scm:git:[email protected]:ds-platform/listt.git </url> <developerConnection> scm:git:[email protected]:ds-platform/listt.git </developerConnection></scm>

Page 27: Hands On with Maven

Understanding the POM.xml

<!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles></project>

The distributionManagement tag is the reverse of the repositories tag -- it refers to the repository where the build artifact (i.e. JAR or WAR) will be stored.

From the previous “mvn release:perform” example, the information in the distributionManagement tag tells Maven where to post the jar.

<distributionManagement > <repository> <id>central-private</id> <url>

http://artifactory.corp.linkedin.com......./artifactory/release

</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </distributionManagement >

Page 28: Hands On with Maven

Some Useful Commands

Page 29: Hands On with Maven

Some Useful CommandsAll commands must be run in the same directory containing the pom.xml.

• mvn clean, compile --> cleans the project, then compiles it

• mvn clean package --> previous step + create WAR or JAR

• mvn clean install --> previous step + run integration tests and install the WAR or JAR in the local repository

• mvn release:prepare --> Does the following:• prompts the user for the version of the jar• alters the version in the POM.xml (i.e. 1.0-SNAPSHOT --> 1.0)• runs a clean-compile-test-package cycle• and generates a release.properties file

• mvn release:perform --> Does the following: • pushes the JAR/WAR to Artifactory or some public repo• If successful, bumps up the version in the pom.xml file (i.e. 1.0 --> 1.1-SNAPSHOT)

• You should never need to alter the version in the POM.xml file!