For those familiar with the basics of Maven, here are some reminders regarding its use.
JAVA_HOME to a local JDK, for example set JAVA_HOME=C:\jdk1.8.0
maven/bin directory to the PATH
${user.home}/.m2/repository
mvn validate - sanity-check for the pom.xml file. (Each project has a pom.xml file that controls the behaviour of Maven.)
mvn compile
mvn test
mvn package
mvn install
mvn dependency:analyze is a good sanity check. It detects 2 kinds of error:
-Dmaven.test.skip=true don't run the unit tests
-Pdev run with a specific profile; profiles often carry data specific to a target environment
-X verbose
-q quiet
-l where to put the output log file
-f a custom name for the pom.xml file
-e verbose error reporting
mvn [options] [goal(s)] [phase(s)]
A simple jar app:
>mvn archetype:generate -DartifactId=my-app -DgroupId=com.mycompany.app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=falseA web app:
>mvn archetype:generate -DartifactId=my-web-app -DgroupId=com.mycompany.app -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=falseFor the web-app archetype, the tree looks like this after you have also run
mvn install:
├───src │ └───main │ ├───resources │ └───webapp │ └───WEB-INF └───target ├───classes ├───maven-archiver └───my-web-app ├───META-INF └───WEB-INF └───classes
Packaging: 'LP(P:)G'
1x Lifecycle
Nx Phase
Nx(plugin:)Goal
Packaging settings:
jar (the default)
pom
war
ear
rar
par
ejb
maven-plugin
There are 3 lifecycles. Here they are, listed with their phases:
pre-clean, clean, post-clean
validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes,
generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test,
prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy
pre-site, site, post-site, site-deploy
The phases in a lifecycle are ordered and cumulative: a later phase includes all earlier ones.
For example, invoking mvn install will always cause all preceding phases in that lifecycle to be executed as well.
Typical invocations of Maven specify 1..N phases.
For example, mvn clean install invokes 2 phases from 2 independent lifecycles.
Each phase, in turn, has N plugin:goal's (much like an Ant target).
Each goal is implemented by a plugin.
You customize the behavior of a plugin by adding a <plugin> entry in the pom.xml.
Some important phases:
validate - validate the project is correct and all necessary information is available
compile - compile the source code
test - run the unit tests
package - create the build target (a jar, for example)
install - put the build target into your local Maven repository
In the resources directory, files can have place-holder references of the form ${blah}.
Values for those references are defined in:
pom.xml profile settings (likely the most common location)
pom.xml properties, as in ${project.name}, for instance
main/filters/blah.properties
settings.xml, a Maven config file, as in ${settings.blah}
${env.blah}
During the build, there is a maven phase (process-resources) which finds resource files and does a find-and-replace on all such
${blah} placeholder strings.
In the pom.xml, you need to turn this mechanism on explicitly, like so:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
coordinates to refer to their conventional names for build
artifacts: the who-what-when information.
Example: myorg.myproj:abc-web:1.1.0
The colon acts as a separator. The 3 basic items are, in order:
groupId who made this
artifactId what is its name - avoid dots in this part
version major.minor.increment.qualifier: 3.2.9, 3.2-beta
SNAPSHOT has specific meaning to Maven: the build is a development build, not a release build.
There are variations in the version string, having these items appearing before the version:
**/*Test.java
**/Test*.java
**/*TestCase.java
main/resources items are put into the root of the jar
test/resources can be accessed in tests, as if they're in the root of the class path
artifactId, because it may lead to problems.
pom.xml, a standard version number, appearing as just 3.2, acts as advice to Maven.
Maven will try to use that version, as your preferred version, but it may, if needed, use a different version instead.
You alter this behaviour, and hard-code to a precise version, by decorating the version with a special syntax, for example [3.2].
Versions have a special syntax:
pom.xml
compile (the default; all cases; propagated to child projects)
runtime (run and test, but not compile)
test (tests only)
provided (compile and test, but not run). For example, the servlet API jars are provided by the container,
so they don't need to be included in the war.
>mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
pom.xml:
Be aware of sloppy terms when reading docs about these ideas: the terms parent and child are used, but they should be avoided, because they mean different things according to who's talking. Your thinking will be clear if you stick to these terms instead:
<parent>, and pointing to a super-pom
packaging to pom
The effective-pom:
mvn help:effective-pom is the command that shows the effective-pom
parent tag.
dependency, then your-pom gets that dependency, no matter what.
dependencyManagement item, then your-pom gets it only if your-pom explicitly declares it as a dependency.
Furthermore, if your-pom's dependency leaves out version/scope for the item, then it gets the super-pom's version/scope.
mvn -Pproduction clean install
pom.xml
<profile> tag are visible during resource-filtering, so that placeholder
strings ${blah} in resource files can be replaced with real values defined by the current profile.
Example of the syntax:
<profile> <id>production</id> <properties> <db.driverClass>oracle.jdbc.driver.OracleDriver</db.driverClass> <db.connectionURL>jdbc:oracle:thin:@10.0.1.14:1521:APPS</db.connectionURL> <db.username>productionuser</db.username> <db.password>productionpassword</db.password> </properties> </profile>
dependencyManagement to centralize versions among modules
pluginManagement, consider defining explicitly all versions of all plugins,
so you don't get clobbered by plugin upgrades (similar behaviour as for dependencyManagement)