Saturday, April 2, 2016

Maven Fundamentals

1.0 High Level Overview

·         Open Source product
·         Managed by the Apache Software Foundation
·         Build tool
o   Always produces one artifact or component
o   Helps manage dependencies
·         Project management tool
o   Handles versioning and releases of your code
o   Meta info: Describes what the project is doing or what it produces
o   Easily produce JavaDocs
o   Produce other site information
·         Maven sites are built with Maven. All the Layout is made with Maven’s site generation features.

2.0 Why use Maven

·         Repeatable builds
·         Recreate a build for any environment
·         Transitive dependencies
o   Downloading dependencies also pulls other items needed
·         Contains everything you need build your code
·         Works with a local repo
o   Local repo keeps the dependencies in a local repo
o   If local repo already contains the dependency required for a particular project, Maven just references the dependency binary stored in the repo.
o   If local repo does not contain the dependency required for a project, Maven downloads the dependency from public or privately hosted maven repo to the local repo.
·         Works with IDS and also as a standalone
·         Preferred choice with build tools like Jenkins

3.0 Ant Vs Maven

3.0.1 Ant

·         Ant was developed to replace a build tool called make, which was not a cross platform tool. Make was brittle and limited to unix.
·         Ant is built on top of Java and uses XML
·         Ant is very procedural
o   It is hard to inherit anything
o   You have to go out of your way to use different pieces and have it stretched out to be able to use composition inside the ant scripts.
·         Ant isn’t a build tool
·         You have to explicitly do everything in Ant
·         Everything needs to be defined. It is very declarative.
·         No standard out there.
·         Nothing can get carried over from one project to another.
·         Each organization, team and individual can define keywords like clean, init etc. and each one could have a different meaning. Nothing is implicit.
·         No possibility of reuse. You’d have to copy over the entire ant script from one project to another if you want to reuse.

3.0.1.1 Ant build.xml

3.0.2 Maven

·         Maven is a proper build tool
·         mvn clean – is always maven clean
·         Inheritance in projects is implicitly available
·         Transitive dependencies
·         Consistent across projects
·         Functionality and keywords are strongly defined and standardization is implicit.
·         In built versioning features – snapshot vs release
·         Maven follows a convention over configuration model
·         Maven is centered around managing your entire project’s lifecycle

3.0.2.1 Pros and Cons

3.0.2.2 Maven pom.xml



4.0 Installation Best Practices


4.0.1 Environment variables

System variables
JAVA_HOME – c:\Program Files\Java\jdk1.8.0_73
MAVEN_HOME – c:\work\tools\build\apache-maven-3.3.3
Add JAVA_HOME and MAVEN_HOME to the Path - %JAVA_HOME%/bin; %MAVEN_HOME%/bin;



5.0 Demo: Hello World


1.       Create a new project named HelloWorld in the IDE of your choice.

2.       Create a file named pom.xml and add the following xml.
<project>
       <!-- Associate group Id with your site or organization name. -->
       <groupId>com.iaditya</groupId>
       <!--  name of our application -->
       <artifactId>HelloWorld</artifactId>
       <version>1.0-SNAPSHOT</version>
       <!-- Version of the XML schema structure used in the project. -->
       <modelVersion>4.0.0</modelVersion>
       <packaging>jar</packaging>
</project>
3.       Create source folder structure in the HelloWorld project - src/main/java
4.       Create a HelloWorld.java file in src/main/java and add the following code.
public HelloWorld {
              public static void main (String args[]) {
                     System.out.println("Hello World");
              }
}

5.       In command prompt or shell, change directory to the project folder and execute the following commands.

mvn clean
mvn compile

This will generate a target directory with classes directory where HelloWorld.class will be stored.

mvn package

This will generate a HelloWorld-1.0-SNAPSHOT.jar file in the target directory.

6.0 Folder structure


1.       Maven looks for src/main/java by default.
a.       All Java code of our package is stored here.
b.      This is the beginning of our package declaration. Example: com.iaditya.helloworld package structure exists in src/main/java/com/iaditya/helloworld.
c.       Other languages: src/main/groovy


2.       Unit test cases are stored in src/test/java.

3.       Maven compiles all code to a target directory by referencing defaults and anything we have overridden in the pom.xml file.
a.       All unit tests get run from the target folder.
b.      Contents from this directory get packaged into jar, war or ear file.

7.0 POM file basics

7.0.1 Parts of a POM file

POM files can be classified into 4 basic parts.
1.       Project Information
a.       groupId – Often it is the package in our code.
b.      artifactId – Name of our application.
c.       version – Current version. Snapshot vs Release.
d.      packaging – How do we want to package our application? ear, war, jar or other package types.
2.       Dependencies –
a.       Actual artifacts we want to use in our application.
3.       Build
a.       Plugins – The plugins we want to use to build our code?
b.      Directory structure
                                                               i.      To override the src/main/java directory
                                                             ii.      Target name
                                                            iii.      Location of target
                                                           iv.      Location of specific resources, generated sources and xml etc.
4.       Repositories
a.       Download artifacts from repositories
b.      Optionally download from maven central
c.       Download from private maven repo hosted in your organization

7.0.2 Dependencies Intro

Often considered the most confusing part of Maven.
1.       Dependencies are imported by their naming convention.
2.       We have to know the following three of any dependency you are looking to use in your code.
a.       groupId
b.      artifactId
c.       version
3.       Added to the dependencies section in the pom.xml.
a.       List the dependency that we want to use
b.      Transitive dependencies will be pulled by Maven
<project>
       <!-- Associate group Id with your site or organization name. -->
       <groupId>com.iaditya</groupId>
       <!--  name of our application -->
       <artifactId>HelloWorld</artifactId>
       <version>1.0-SNAPSHOT</version>
       <!-- Version of the XML schema structure used in the project. -->
       <modelVersion>4.0.0</modelVersion>
       <packaging>jar</packaging>

       <dependencies>
              <dependency>
              <!-- Package -->
                     <groupId>commons-lang</groupId>
              <!-- Name of our application -->
                     <artifactId>commons-lang</artifactId>
                     <version>2.1</version>
              </dependency>
       </dependencies>
</project>

7.0.3 Goals

1.       clean – deletes the target directory and any generated sources
2.       compile 
a.       Compiles the source code
b.      Generates any files
c.       Copies resources to our classes directory
3.       package
a.       Runs compile first
b.      Runs unit tests
c.       Packages the app based on the packaging type defined in pom.xml
4.       install
a.       Runs the package command and installs it in your local repo
5.       deploy
a.       Runs the install command and deploys it to a private repository.
b.      Does not deploy to an app server.

7.0.4 Running maven goals

Maven goals can be run individually.
mvn clean
mvn compile
mvn package
mvn install
mvn deploy

And they can be daisy-chained.
mvn clean package

7.0.5 Local repo


1.       Maven stores everything it downloads to a local repository folder on the hard drive. Usually, it is installed in the home directory\.m2 folder.

2.       Avoids duplication. Otherwise, we would end up copying the dependency into every project and storing it in the SCM.

3.       Stores artifacts using the information provided in the pom.xml for the dependencies. Folders named artifactId, groupId and version are created.
c:\users\<username>\.m2\repository\comons-lang\commons-lang\2.1\commons-lang-2.1.jar

7.0.6 Overriding defaults in the build section

Defaults that are implicitly followed by Maven can be overridden in the build section of the pom.xml. In the following example, we are overriding the target package name. By default, the target package name in our HelloWorld example will be HelloWorld-1.0-SNAPSHOT.jar.
       <project>
              <!-- Associate group Id with your site or organization name. -->
              <groupId>com.iaditya</groupId>
              <!--  name of our application -->
              <artifactId>HelloWorld</artifactId>
              <version>1.0-SNAPSHOT</version>
              <!-- Version of the XML schema structure used in the project. -->
              <modelVersion>4.0.0</modelVersion>
              <packaging>jar</packaging>
      
              <dependencies>
                     <dependency>
                     <!-- Package -->
                           <groupId>commons-lang</groupId>
                     <!-- Name of our application -->
                           <artifactId>commons-lang</artifactId>
                           <version>2.1</version>
                     </dependency>
              </dependencies>
             
              <build>
              <!-- Override the target package name. -->
                     <finalName>iAditya</finalName>
              </build>
       </project>

8.0 Maven Dependencies


1.       Dependencies are other resources that we want to use inside of our application.

2.       Maven will pull transitive dependencies based on the dependencies we list.

3.       Minimum required info to pull dependencies:
a.       groupId
b.      artifactId
c.       version

8.0.1 Versions


1.       Development starts off as a SNAPSHOT

2.       SNAPSHOT allows us to push new code to a repository and have our IDE or command line automatically check for changes every time.

3.       If we specify a SNAPSHOT version in our pom.xml, Maven will pull down new code every time it runs and uses the new code.

4.       SNAPSHOT keyword has to be all capital. It does not work as a SNAPSHOT otherwise.

5.       This SNAPSHOT functionality saves you from re-releasing versions for development.

6.       Never deploy to production with a SNAPSHOT because we cannot reproduce or re-create that code. The next time we compile the code, the functionality could be different in the code.

7.       A release does not have to have a specific naming convention. Example: HelloWorld-1.0.jar, HelloWorld-1.0.1.jar

8.       Milestone releases like HelloWorld-1.0-M1.jar or HelloWorld-1.0-RC1.jar do not effect Maven. Such milestone or release candidate versions are published for evaluation purposes and should not be considered as release versions.

9.       RELEASE versions are sometimes named with a keyword RELEASE, although it is not necessary.

8.0.2 Types


1.       Types refer to the type of resource that we want to include inside of our application.

2.       The default and the most common type is a jar.

3.       The current core packaging types are pom, jar, maven-plugin, ejb, war, ear, rar and par.

4.       The type of pom is referred to a dependency pom.
a.       All dependencies inside the pom are downloaded into our application.
b.      Commonly referred to as a dependency pom.
c.       Example: If you have web services in your organization and you want to group all of these dependencies that we use for a anytime we want to create a web service, like Jersey libraries and other different XML dependencies, all those dependencies can be put into one pom and reference that pom in your project and Maven will download that into our application.
5.       Types refer to packaging inside our application. If we are building an artifact for other people to consume, we need to specify our packaging in the pom.
              <groupId>com.iaditya</groupId>
              <artifactId>HelloWorld</artifactId>
              <version>1.0-SNAPSHOT</version>
              <packaging>jar</packaging>

8.0.3 Transitive dependencies


1.       The main reason people begin using maven.

2.       If we add a dependency like hibernate, it will go ahead and pull down any and all transitive dependencies that hibernate needs.

3.       If there is a conflict, Maven will resolve those by choosing the newer version.

8.0.4 Scopes


Six scopes available for dependencies:
1.       compile
a.       Default scope
b.      Resources or artifacts are available everywhere inside your application.
2.       provided
a.       Like compile
b.      Means the artifact is going to be available throughout your entire build cycle, but it’s not going to be added to the final artifact.
c.       Example: servlet-api, xml-apis
3.       runtime
a.       Not needed for compilation
b.      Needed for execution
c.       Included in the runtime and test classpaths, but not the compile classpaths.
d.      Example: Dynamically loaded libraries like jdbc jars
e.      Not bundled with our final artifact
4.       Test
a.       Available for the test compilation and execution phase only.
b.      Not included in the final artifact
5.       system
a.       It is recommended NOT to use system as it is very brittle and breaks the reason for wanting to use maven.
b.      It is used for hard coding a path to a jar on your file system.
6.       import
a.       Deals with dependency management
b.      Advanced topic.
c.       Review at
                                                               i.      http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
                                                             ii.      https://developer.jboss.org/wiki/MavenImportScope?_sscc=t

9.0 Repositories


1.       Repositories are http accessible locations where maven looks at to download code and other artifacts to use in our application.

2.       For internal repo, it is advisable to secure it as an https accessible location.

3.       The default location of the repo is stored in the super pom.xml, which is located inside the maven installation.

4.       This super pom.xml can be overridden using settings.xml or our project’s pom.xml.

5.       Default location is http://repo.maven.apache.org/maven2.

6.       Multiple repositories are allowed.

7.       Corporate repository options:
a.       Nexus (recommended)
b.      Artifactory

9.0.1 Dependency Repo


1.       It is where we download all our dependencies from.

2.       It can contain releases or snapshots or both.

3.       It is common to have releases and snapshots in separate repositories.

4.       Sample repositories section in pom.xml.
              <repositories>
                     <repository>
                     <!-- User defined id -->
                     <id>spring-snapshot</id>
                     <!-- User defined desciption entered in the name tag -->
                     <name>Spring Maven SNAPSHOT Repository</name>
                     <!-- Repo url of the dependency artifact needed in your code -->
                     <url>http://repo.springsource.org/libs-snapshot</url>
                     <snapshots>
                           <enabled>true</enabled>
                     </snapshots>
                     <releases>
                           <enabled>false</enabled>
                     </releases>
                     </repository>
              </repositories>

9.0.2 Plugin Repo


1.       Identical to dependency repositories, just deals with Plugins.

2.       Maven will only look for plugins in this repo as by design a plugins repo is usually a separate repository.

3.       Defined very similar to dependency repository.


4.       Snapshots and releases just like the dependency repository.

5.       Optionally, custom plugins can be created and stored in an internal or corporate repository.

9.0.3 Releases/Snapshots


1.       Snapshots and releases can come from the same repo, but usually organizations prefer to keep them separate.

2.       Most projects end up having a lot of snapshots, release candidates and milestone releases for each release. It is easier to maintain a separate repo for releases to make it easier to push truly releasable code to an app store or a customer access site.

10.0 Maven Plugins

Maven uses plugins to build and package our application beyond just downloading and storing artifacts locally.

10.0.1 Goals

1.       Goals like clean, compile etc. are plugins configured in the maven install.
2.       These goals are defined in the super pom which are added to your project’s effective pom.
3.       Goals are always tied to a phase.
4.       The default goal’s phases can be overridden in your project’s pom if required.

10.0.2 Phases

1.       validate – this validates that
a.       The project is correct
b.      It has all the plugins needed
c.       It has all the artifacts downloaded
d.      All structures are in place
e.      Has permissions to create directories.
2.       compile
a.       Our source code compilation happens.
b.      Testing code does not get compiled.
3.       test
a.       Testing code gets compiled.
b.      Testing of the compiled source code happens.
4.       package
a.       Packages all of our code in its defined packaging such as jar.
b.      It doesn’t do anything with it once it is packaged, but allows us to test to make sure that everything is in the proper order in which it should be.
c.       Usually, developers tie generating sources or JavaDoc to this phase.
5.       integration test
a.       Allows us to deploy and run integration tests
b.      New to maven 3. Not used by most yet.
6.       verify
a.       Runs checks against package to verify integrity before installing to our local repo or our private repo.
7.       install
a.       Install the package in our local repo
8.       deploy
a.       Copy final package to a remote or private repo

10.0.3 Compiler plugin


1.       The plugin used to compile the source code in our application.
2.       Used to compile both source code and test code using different phases.
3.       Invoke java by setting the classpath with the dependencies from our application.
4.       Defaults to java 1.5 regardless of which JDK is installed.
5.       The configuration section allows for customization by overriding the JDK version, memory settings etc.

              <build>
              <!-- Override the target package name. -->
                     <finalName>iAditya</finalName>
                     <plugins>
                           <plugin>
                                  <groupId>org.apache.maven.plugins</groupId>
                                  <artifactId>maven-compiler-plugin</artifactId>
                                  <version>2.3.1</version>
                                  <!-- Different for every plugin as the fields that they support can be different. -->
                                  <!-- Sometimes context sensitive help in IDE for this section is not available because it can be a Cdata field in XML. -->
                                  <configuration>
                                         <source>1.7</source>
                                         <target>1.7</target>
                                  </configuration>
                           </plugin>
                     </plugins>
              </build>


10.0.4 Jar plugin


1.       Used to package our compiled code into a jar file.

2.       It is tied to the package phase of our build lifecycle.

3.       Configuration section allows for customization:
a.       Includes or Excludes – to only package certain things in your jar.
b.      Manifest – builds a manifest for our project. (useDefaultManifestFile)

                           <plugin>
                                  <groupId>org.apache.maven.plugins</groupId>
                                  <artifactId>maven-jar-plugin</artifactId>
                                  <version>2.4</version>
                                  <configuration>
                                         <useDefaultManifestFile>true</useDefaultManifestFile>
                                  </configuration>
                           </plugin>



10.0.5 Sources plugin


1.       Used to attach our source code to a jar.

2.       By default it is tied to the package phase.

3.       It is often overridden to a later phase like install or deploy so that the build is faster when we are developing.

                           <plugin>
                                  <groupId>org.apache.maven.plugins</groupId>
                                  <artifactId>maven-source-plugin</artifactId>
                                  <version>2.2.1</version>
                                  <!-- This is about WHEN the plugin is going to run -->
                                  <executions>
                                         <execution>
                                                <id>attach-sources</id>
                                                <phase>verify</phase>
                                                <goals>
                                                       <goal>jar</goal>
                                                </goals>
                                         </execution>
                                  </executions>
                           </plugin>


10.0.6 Javadoc plugin


1.       Used to attach Javadocs to a jar file when we upload them to our repository.

2.       It is tied to the package phase.

3.       It is often overridden to a later phase to speed up the build time while still developing the code.

4.       The defaults usually work out fine. Optionally, there are customization options for Javadoc format, like add company logo or change colors.

                           <plugin>
                                  <groupId>org.apache.maven.plugins</groupId>
                                  <artifactId>maven-javadoc-plugin</artifactId>
                                  <version>2.9</version>
                                  <executions>
                                         <execution>
                                                <id>attach-javadoc</id>
                                                <phase>verify</phase>
                                                <goals>
                                                       <goal>jar</goal>
                                                </goals>
                                         </execution>
                                  </executions>
                     </plugin>