About Me
DevOps@RajeshKumar.XYZ
Course Overview
- Introduction to Maven
- Key concepts of Maven
- Convention over configuration
- Day-to-day coding
- Integration
- Maven can be very complex
Course Overview
- Topics Covered
- Introduction to Maven
- Structure
- Dependencies
- Repositories
- Plugins
- IDE Integration
Outline
- High level overview
- Ant VS Maven VS IDE
- Installation Best Practices
- Hello World Application
- Summary
Maven High Level Overview
What is Maven
- At its simplest, Maven is a build tool
- It always produces one artifact (component)
- It helps us manage dependencies
- It can also be used as a project management tool
- It handles versioning and releases
- Describes what your project is doing or what it produces
- Can easily produce Javadocs as well as other site information
Who owns it
- Maven is managed by the Apache Software Foundation
- Maven sites are built with Maven
- Open Source
Why do you want to use it
- Repeatable builds
- We can recreate our build for any environment
- Transitive dependencies
- Downloading a dependency with also pull other items it needs
- Contains everything it needs for your environment
- Works with a local repo
- Works with your IDE, but also standalone
- The preferred choice for working with build tools like Jenkins or Cruise Control
Ant
- Ant was developed to be a replacement for a build tool called Make
- Designed to be cross platform
- Built on top of Java and XML
- Very procedural
Ant
- Ant really isn’t a build tool as much as it is a scripting tool
- You have to explicitly do everything in Ant
<target name="clean" description="clean up”>
<!-- Delete the ${build} and ${dist) directory trees -->
<delete dir="${build}"/>
</target>
We have to define everything that we want to do
- clean, clear, cleanup, etc…
A lot of tribal knowledge, nothing carries over
Maven
- Maven is a full fledged build tool
- A lot of implicit functionality
- Consistency across projects
- Also capable to achieve inheritance in projects
- Transitive dependencies (can be achieved using Ivy with Ant though)
- Built around versioning
Pros and Cons
- Maven can be a black box
- Steeper learning curve
- Convention over configuration
- Better IDE integration
- Let overheard through use of repos
- Different mindset, steepest learning curve is not making Maven act lik Ant
|
|
- You can trace through Ant files fairly easily
- Quicker to learn, but very copy-paste intensive
- Larger project size in SCM, artifacts stored with project
|
Ant build.xml
<project>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/closses"/>
</target>
<target name="jar">
<mkdir dir="build/jor"/>
<jar destfile="buiid/jor/HelloWorld.jar" bosedir="build/classes">
<manifest>
<attribute name="Man-Class" value="aato.HelloWorld”/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/Helloorld.jor" fork="true"/>
</target>
</project>
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>HelloWorld</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
Summary
- Ant is very declarative
- Maven follows a convention over configuration model
- Ant is maybe easier to learn, but it really is only beneficial as a scripting tool
- Maven is really centered around managing your entire project’s lifecycle
What we covered
- What is Maven
- How is Maven different from other tools
- Its not just a scripting tool
- Where to get it and how to install it
- A Hello World application
What is next
- Structure
- Dependencies
- Repositories
- Plugins
- Eclipse Integration
Outline
- Folder Structure
- POM File Basics
- Basic Commands and Goals
- Dependencies
- Local Repo
src/main/what?
- src/main/java
- target
- pom.xml
src/main/java
- Where we store our Java code
- The beginning of our package declaration
- com.yourcompanyname.division
- What about other languages
- What about testing
target
- Where everything gets compiled to
- Also where tests get ran from
- Contents in this directory get packaged into a jar, war, ear, etc…
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/xsd/maven-4.0.0.xsd">
<groupId>com.pluralsight</groupId>
<artifactId>HelloWorld</artifactId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0-SNAPSHOT</modelVersion>
<packaging>jar</packaging>
</project>
pom.xml
- Can be divided into 4 basic parts:
- Project Information
- groupId
- artifactId
- version
- packaging
- Dependencies
- Direct dependencies used in our application
- Build
- Plugins
- Directory Structure
- Repositories
- Where we download the artifacts from
Dependencies
- What we want to use in our application
- Dependencies are imported by their naming convention
- Often considered the most confusing part of Maven
- We have to know the groupId, artifactId, and the version of what we are looking for
- Added to a dependencies section to our pom file
Dependencies
- Just list the dependency that we want
- Transitive dependencies will be pulled in by Maven
- Need at a minimum 3 things:
- groupId
- artifactId
- version
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
pom.xml with our new dependency
<groupId>com.pluralsight</groupId>
<artifactId>HelloWorld</artifactId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
Goals
- clean
- Deletes the target directory and any generated resources
- compile
- Compiles all source code, generates any files, copies resources to our classes directory
- package
- Runs the compile command first, runs any tests, packages the app based off of its packaging type
- install
- Runs the package command and then installs it in your local repo
- deploy
- Runs the install command and then deploys it to a corporate repo
- Often confused with deploying to a web server
Local Repo
- Where Maven stores everything it downloads
- Installs in your home directory\.m2
- C:\Users\<yourusername>\.m2\repository
-
Stores artifacts using the information that you provided for artifactId, groupId, and version
- C:\Users\<yourusername>\.m2\repository\commons-lang\commons-lang\2.1\commons-lang-2.1.jar
- Avoids duplication by copying it in every project and storing it in your SCM
Local Repo
Defaults
- These are all the defaults that Maven has, but how do we override them?
- The build section!
- Let’s Demo the options for structure changes.
Summary
- Source code goes in src/main/java
- Everything is compiled to our target directory
- The pom has 4 major parts
- Introduction of goals
- Basic example of a dependency
- Where things are stored in your local repo
- How we can override the default behavior
Outline
- Versions
- Types
- Transitive Dependencies
- Scopes
Dependency
- Just list the dependency that we want
- Transitive dependencies will be pulled in by Maven
- Need at a minimum 3 things:
- groupId
- artifactId
- version
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
Versions
- Development starts off as a SNAPSHOT
- myapp-1.0-SNAPSHOT.jar
- Changes always downloaded
- Saves you from rereleasing versions for development
- Never deploy to production with a SNAPSHOT
- A release doesn’t have a specific naming convention
- myapp-1.0.jar
- myapp-1.0.1.jar
- Industry common terms, but don’t affect maven
- myapp-1.0-M1.jar (milestone release)
- myapp-1.0-RC1.jar (release candidate)
- myapp-1.0-RELEASE.jar (release)
- myapp-1.0-Final.jar (release)
Types
- Current core packaging types are:
- pom, jar, maven-plugin, ejb, war, ear, rar, par
- The default packaging type is jar
- The type of pom is referred to as a dependency pom
- Downloads dependencies from that pom
Transitive Dependencies
- The main reason people begin using maven
- If we add a dependency:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.6.Final</version>
</scope>compile</scope>
</dependency>
If we add a dependency it downloads it’s transitive dependencies:
Transitive Dependencies
Scopes
- There are 6 scopes available for dependencies:
- compile – default scope, artifacts available everywhere
- provided – like compile, means that the artifact is going to be provided where it is deployed
- servlet-api.jar
- xml-apis
- Available in all phases, but not included in final artifact
- runtime – not needed for compilation, but needed for execution
- Not available for compilation, but included in all other phases
- Not included in final artifact
- test – only available for the test compilation and execution phase
- system – similar to provided, you specify a path to the jar on your file system
- Very brittle and defeats the purpose of maven, don’t use!
- import – advanced topic, deals with dependencyManagement sections
Demo
- Let’s look at what the pom.xml will look like when we:
- Add a dependency
- Reference transitive dependencies
- Use scopes
Summary
- Version numbers are up to your corporate strategy
- SNAPSHOT has a unique meaning
- Supported types and what they mean to your application
- Transitive dependencies and how they are downloaded
- Scopes allow us to compile or test our code, but not include artifacts that shouldn’t be in the packaged code
Outline
- Dependency Repo
- Plugin Repo
- Releases/Snapshots
Local Repo
- Where Maven stores everything it downloads
- Installs in your home directory\.m2
- C:\Users\<yourusername>\.m2\repository
- Stores artifacts using the information that you provided for artifactId, groupId, and version
- C:\Users\<yourusername>\.m2\repository\commons-lang\commons-lang\2.1\commons-lang-2.1.jar
- Avoids duplication by copying it in every project and storing it in your SCM
Local Repo
Repositories
- Simply just a http accessible location that you download files from
- Super pom.xml
- Default with the Maven installation
- Default location
- Multiple repositories allowed
- Corporate Repository
- Nexus (this is what the default repo is built on)
- Artifactory
Dependency Repository
- Where we download all of our dependencies from
- Can contain just releases and/or snapshots
- Not uncommon to have them in separate repositories
- How do we specify our own repository
Dependency Repository
<repositories>
<repository>
<id>spring-snapshot</id>
<name>Spring Maven SNAPSHOT Repository</naine>
<url>http://repo.springsource.org/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
Plugin Repository
- Identical to Dependency Repositories, just deals with Plugins
- Will only look for Plugins, by design usually a separate repository
<pluginRepositories>
<pluginRepository>
<id>acme corp</id>
<name>Acme Internal Corporate Repository</name>
<url>http://acmecorp.com/plugins</url>
<snapshots>
<enabled>true</enab1ed>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
Releases / Snapshots
- Snapshots and releases can come from the same repo
- Why would projects not upload everything to the central repo
- Snapshots
- Milestones
- Release Candidate
- Release policies
Summary
- Dependency repositories and Plugin repositories can be separate or the same repository
- Projects will often not upload their SNAPSHOT code up to the central repo even though their release project is hosted there
- Plugins are usually in the same repo as dependencies
- Companies should use a corporate repository internally to help lighten the load on the central repo
Outline
- Goals
- Phases
- Compiler plugin
- Jar plugin
- Sources plugin
- Javadoc plugin
Goals
- The default goals are plugins configured in the maven install
- clean, compile, test, package, install, deploy
- Super pom has these goals defined in it, which are added to your effective pom:
- Goals are tied to a phase
Phases
- validate
- Validate the project is correct and all necessary information is available
- compile
- Compile the source code of the project
- test
- Test the compiled source code
- package
- Packages the code in its defined package, such as a JAR
Phases
- integration-test
- Deploy and run integration tests
- verify
- Run checks against package to verify integrity
- install
- Install the package in our local repo
- deploy
- Copy final package to a remote repository
Compiler Plugin
- Used to compile code and test code
- http://maven.apache.org/plugins/maven-compiler-plugin/index.html
- Invokes Javac, but with the classpath set from the dependencies
- Defaults to Java 1.5 regardless of what JDK is installed
- Configuration section allows customization
- clean, compile, test, package, install, deploy
- Fork
- Memory
- Source/target
Compiler Plugin
Jar Plugin
- Used to package code into a jar
- http://maven.apache.org/plugins/maven-jar-plugin/index.html
- Tied to the package phase
- Configuration section allows customization
- Includes/Excludes
- Manifest
Jar Plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>mavenc-jar-plugin-plugin</artifactId>
<version >2.4</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
</configuration>
</plugin>
</plugins>
</build>
Source Plugin
- Used to attach source code to a jar
- http://maven.apache.org/plugins/maven-source-plugin/index.html
- Tied to the package phase
- Often overridden to a later phase
Source Plugin
<plugin>
<groupId >org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id)
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Javadoc Plugin
- Used to attach Javadocs to a jar
- http://maven.apache.org/plugins/maven-javadoc-plugin/index.html
- Tied to the package phase
- Often overridden to a later phase
- Usually just use the defaults, but many customization options for Javadoc format
Javadoc Plugin
<plugin>
<groupId >org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id)
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Summary
- Goals are really just configured plugins in your application
- Plugins are tied to one of the defined phases, but can usually be overridden.
- The compile plugin is already defined for you, but is often changed to use a specific version of Java.
- The jar plugin is one of the default plugins and can be configured to produce artifacts to specific needs.
- Source and Javadocs can easily be generated to be installed in your corporate repository for use by other developers.
Eclipse/Spring STS Integration
Outline
- Installing Eclipse/Spring STS
- Importing Maven Projects
- Pom viewer
- Dependency Overview
- Adding a dependency
- Dependency Heirarchy
- Effective Pom
Installation
- Eclipse/Spring STS doesn’t use the registry
- Java and Maven installed the same regardless of using an IDE
- Some IDEs do include a bundled version of Maven
- http://www.springsource.org/downloads/sts-ggts
Importing Maven Projects
- Modern IDEs have Maven integration built into them
- Maven integration will allow us to execute default maven goals within our IDE
- IDE configuration and Classpath will be set from Maven
- Right Click in the Package Explorer > Import > Maven > Existing Maven Projects
Converting Existing Projects
- If you have a pom.xml file, you can convert the project to a Maven project
- Right click on the project containing the pom.xml file > Configure > Convert to Maven Project
- Once converted the project will set the classpath and automatically build the project
Pom Viewer
- Default view when you open the pom file
- Pom overview shows the high level elements of your project
- Changes made here are directly changing the source
Dependencies
- Shows which dependencies we have installed and allows us to manipulate dependencies too
- Dependency Management (advanced topic) is also displayed
- The add screen has searching capability
Dependency Heirarchy
- Displays the complete dependency tree, including transitive dependencies as well overridden dependencies
- Scope of the resource is also displayed
Effective Pom
- The complete pom with everything inherited from the project pom, if we have a parent pom, and the default super pom
- More of a debugging tool to see what the pom is doing
Summary
- Eclipse/STS installation is really unzipping
- Existing projects can be imported easily and converting projects can be easily as well
- Adding dependencies inside the IDE can be easier using the searching tools
- Solving dependency resolution errors is more convenient in the IDE
- Configuring your IDE is also more convenient with Maven
Questions?