Maven comes from Yiddish meyvn , "one who understands."
Extrapolated due to usage, a maven is someone who is an expert.
Apache Maven is an Apache Software Foundation project that is used
primarily to build and manage Java-based projects, but it can be used for C#,
Ruby, Scala and many other languages.
Maven is basically a plug-in execution framework. Everthing that happens in the
build process happens because some plug-in accomplishes it. There is a core if
limited set of plug-ins provided when Maven is installed, but there are also
important third-party plug-ins.
Any time a developer nees to perform custom tasks just a bit out of the
ordinary, such as create WAR or NAR files, often it's a third-party developer
that wrote it.
Mojo
Mojo is, inspired by Java's POJO , short for "Maven old Java object." A
mojo is a goal in Maven context. Plug-ins consist of one or more goals.
They can be defined as annotated Java classes (using @Mojo ). They
specify metadata about a goal including a name, which phase of the Maven
lifecycle the mojo fits into and the parameters it's expecting.
One plug-in is a distribution of one or more related mojos. A mojo is an
executable goal in Maven.
Purpose of these notes...
At some point, I want to write a tutorial on implementing a Maven plug-in.
There are many, about one-half are badly written, leave much information out or
don't work unless you already know enough to fix or go beyond what they say. I
want to correct that, but I'm far from having the time or being able to do so.
In the meantime, I'm going to make notes on crucial points—things that
will make you fail when you write a plug-in.
Useful links
Google search string: "how to write a maven plugin"
How to write your own Maven plugins ; Omnifaces hello-world
tutorial—quite well written. It says Hello, world!, but proposes
an interactive enhancement in which you are asked to type your name in
whereupon it says, "Hello, Russ!".
Step by Step Guide to Developing a Custom Maven Plugin ; this
one work and it's pretty well written. It takes an XML file and translates
it to JSON—probably nothing you'd ever use, but it's cool.
How to Create a Maven Plugin ; Baeldung's tutorials are usually
well written and formatted, however, this one leaves things out that a
clueless beginning would not know—wasted a lot of my time, but I got
it working. It displays the list of dependencies in (its own) pom.xml .
Beginner's Guide to Creating a Maven Plugin ; very poorly written,
broken images in HTML, undertook too much despite being a beginner's
tutorial.
Apache Maven Project: Plug-in Development Guide ; ordinarily, I
stay away from formal documentation from the likes of Apache and Oracle
using it for reference only because I always feel like a moron trying to
understand what they're saying. This one's a bit better than most.
How to back-translate Java 8 lambda- and stream expressions ;
in case you don't want to use Java 8+ constructs inside your plug-in code.
Steps to set up a plug-in development project
As noted, I haven't undertake to write a tutorial yet. Pick one from those
I listed in the links above. I particularly recommend the Omnifaces one for
its ease.
(Because I'm an old guy used to doing things old ways, I tend to set up any new
project by writing its pom.xml , creating all the subdirectories I know
I'll need, then in IDEA I do File → New → Project from Existing
Sources... , then I navigate to the root of my new project and choose it.
At some point, some IDEA/Maven thing will pop up and ask me if I want to
Recreate something, that's confusing, but I click to do that and it's
all good from there-on.)
Your mileage may vary, but using some Maven artifact command might be what you
want to do; some of the tutorials give that to you, others leave you on your
own.
Command-line invocation shorthand
In the Baeldung tutorial, you learn that there is a long, formal way to invoke
the plug-in from the command line, but, as a super Maven champion, you would
also know of a shorthand. However, this never worked for me.
(Formal pattern:)
$ mvn groupId :artifactId :version :goal
(Example:)
$ mvn com.baeldung:counter-maven-plugin:0.0.1-SNAPSHOT:dependency-counter
(Shorthand—doesn't work for me:)
$ mvn counter:dependency-counter
Debugging steps
Here's how to set up IntelliJ IDEA to debug your plug-in. Let's say you've got
your project on the path /home/russ/dev/hello and you've done the
Omnifaces hello-world project from the links above.
At the command line, install your plug-in in Maven (goes into
~/.m2/repository/... ).
$ mvn clean install
Your plug-in project running in IDEA.
Create a run/debug configuration:
Run → Edit Configurations...
Click the + sign, look for Remote JVM Debug .
Name: the configuration, something like Hello plug-in.
Leave Host: as localhost .
Set the Port: to 8000 .
At the command line, run your plug-in thus:
$ mvnDebug org.omnifaces.example:hello-maven-plugin:hello
Preparing to execute Maven in debug mode
Listening for transport dt_socket at address: 8000
Now go back to IDEA and set a breakpoint in your setLog() or
execute() method.
Click Run → Debug... .
Choose the debug configuration you made.
You should find yourself halted at one of your breakpoints—likely
the one in setLog() , if you set it, because that method, of
the several you have coded to, is the first one to be called. Note that
method execute() is the one that does the heavy lifting.
Failed to execute goal
If this is what you get when beginning to test a plug-in you're writing, it
means you'ce screwed something up.
[ERROR ] Failed to execute goal groupId :artifactId :version :goal (default-cli) on project project-name : etc.
What's screwed up? One of the following:
Formally, you must have the following in your plug-in's pom.xml :
groupId —crucial in plug-in development
artifactId —crucial in consuming project pom.xml
version —crucial in consuming project pom.xml
packaging —maven-plugin
If the first two don't match the package paths in your plug-in source code,
you'll get the error above. My example here uses the Baeldung tutorial:
Plug-in's pom.xml :
<groupId>com.windofkeltia.maven.plugin</groupId>
<artifactId>counter-maven-plugin</artifactId>
<version>1.0.0</version>
<packaging>maven-plugin</packaging>
The filesystem of your project:
src
└── main
└── java
└── com ✓
└── windofkeltia ✓
└── maven ✓
└── plugin ✓
└── FirstMojo.java
Compare the above from the line containing com with the groupId
defined in pom.xml .
Invoking a plug-in from the command line will also give the error above.
The format to invoke locally is:
mvn groupId :artifactId :version :goal
Here are two sample invocations:
$ mvn com.windofkeltia.maven.plugin:counter-maven-plugin:1.0.0:dependency-counter
$ mvnDebug com.windofkeltia.maven.plugin:counter-maven-plugin:1.0.0:dependency-counter
Command execution failed
This is about consuming a plug-in, not developing one. This problem occurs
when you invoke Maven in a consuming project.
[ERROR ] Failed to execute goal groupId :artifactId :version :goal (default-cli) on project project-name : \
Command execution failed.: Process exited with an error: 1 (Exit value: 1) -> [Help 1]
This usually means that something is broken in the configuration of the
plug-in, a bad parameter, execution, configuration, etc.
Maven errors are not the most informative on this planet. I don't always find
invocation option -X to be helpful—it just creates a lot more
crap to sort through. The best thing is just to use your brain. However, if you
don't know what Maven's up to when it blows up in the first place (which is a
problem most of us suffer from), then, by definition, it's a bad-hair day and
you have my sincerest sympathy.