blob: b5bca8b294f34c6a4c921631f66c2d26496a6844 [file] [log] [blame]
------
Introduction to Maven 2.0 Plugin Development
------
John Casey
------
24 June 2005
------
~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements. See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership. The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied. See the License for the
~~ specific language governing permissions and limitations
~~ under the License.
~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html
Introduction to Maven 2.0 Plugin Development
Maven consists of a core engine which provides basic project-processing
capabilities and build-process management, and a host of plugins which are
used to execute the actual build tasks.
* What is a Plugin?
"Maven" is really just a core framework for a collection of
Maven Plugins. In other words, plugins are where much of the real action is
performed, plugins are used to: create jar files, create war files, compile
code, unit test code, create project documentation, and on and on. Almost
any action that you can think of performing on a project is implemented as
a Maven plugin.
Plugins are the central feature of Maven that allow for the reuse of
common build logic across multiple projects. They do this by executing an
"action" (i.e. creating a WAR file or compiling unit tests) in the context
of a project's description - the Project Object Model (POM). Plugin behavior
can be customized through a set of unique parameters which are exposed by a
description of each plugin goal (or Mojo).
One of the simplest plugins in Maven 2.0 is the Clean Plugin. The
{{{../../plugins/maven-clean-plugin/}Maven
Clean plugin}} (maven-clean-plugin) is responsible for removing the target
directory of a Maven 2 project. When you run "mvn clean", Maven 2 executes
the "clean" goal as defined in the Clean plug-in, and the target directory
is removed. The Clean plugin
{{{../../plugins/maven-clean-plugin/clean-mojo.html}defines
a parameter}} which can be used to customize plugin behavior, this parameter is
called outputDirectory and it defaults to $\{project.build.directory\}.
* What is a Mojo (<And Why the H--- is it Named 'Mojo'>)?
A Mojo is really just a goal in Maven 2, and plug-ins consist of
any number of goals (Mojos). Mojos can be defined as annotated Java classes or
Beanshell script. A Mojo specifies
metadata about a goal: a goal name, which phase of the lifecycle it fits into,
and the parameters it is expecting.
MOJO is a play on POJO (Plain-old-Java-object), substituting "Maven" for
"Plain". Mojo is also an iteresting word (see {{{http://www.answers.com/mojo&r=67}definition}}).
From {{{http://www.wikipedia.org}Wikipedia}}, a "mojo" is defined as:
"...a small bag worn by a person under the clothes (also known as a mojo hand).
Such bags were thought to have supernatural powers, such as protecting from evil,
bringing good luck, etc."
* What is the Build Lifecycle? (Overview)
The build lifecycle is a series of common stages through which all project
builds naturally progress. Plugin goals are bound to specific stages in the
lifecycle.
Resources
[[1]] {{{../plugin/guide-java-plugin-development.html}Plugin development guide}}
[[2]] {{{../mini/guide-configuring-plugins.html}Configuring plugins}}
Comparison to Maven 1.x Plugins
* Similarities to Maven 1.x
Maven 2.0 is similar to its predecessor in that it has two main
functions. First, it organizes project data into a coherent whole,
and exposes this data for use within the build process. Second, Maven
marshals a set of plugins to do the heavy lifting and execute the
actual steps of the build.
Many things in Maven 2 will have at least superficial familiarity
to users of Maven 1, and the plugin system is no exception. Maven 2
plugins appear to behave much as their 1.x counterparts do. Like 1.x
plugins, they use both project information and custom-defined
configurations to perform their work. Also, Maven 2 plugins are
organized and executed in a coherent way by the build engine itself -
that is to say, the engine is still responsible for organizing and
fulfilling a plugin's requirements before executing the plugin
itself.
Operationally, Maven 2.0 should feel very much like a more
performant big brother of Maven 1.x. While the POM has definitely
changed, it has the same basic layout and features (with notable
additions). However, this is where the similarity ends. Maven 2.0 is
a complete redesign and reimplementation of the Maven build concept.
As such, it has a much different and more evolved architecture - at least to
our minds. <<;-)>>
* Differences from Maven 1.x
However similar the architectures may seem, Maven 2 offers a much
richer environment for its plugins than Maven 1 ever did. The new
architecture offers a managed lifecycle, multiple implementation
languages, reusability outside of the build system, and many more
advantages. Arguably the biggest advantage is the ability to write
Maven plugins entirely in Java, which allows developers to tap into a
rich landscape of development and testing tools to aid in their
efforts.
Prior to Maven 2.0, the build system organized relevant plugins
into a loosely defined lifecycle, which was determined based on goal
prerequisites and decoration via preGoals and postGoals. That
experience was critical for the Maven community. It taught us that
even though there may be a million different build scenarios out
there, most of the activities in those builds fit into just a few
broad categories. Moreover, the category to which a goal fits serves
as an accurate predictor for where in the build process the goal
should execute. Drawing on this experience, Maven 2.0 defines a
lifecycle within which plugins are managed according to their
relative position within this lifecycle.
Starting with Maven 2.0, plugins implemented in different
programming or scripting languages can coexist within the same build
process. This removes the requirement that plugin developers learn a
particular scripting language in order to interact with Maven. It
also reduced the risk associated with the stability or richness of
any particular scripting language.
Also starting with Maven 2.0 is an effort to integrate multiproject
builds directly into the core architecture. In Maven 1.x, many large
projects were fragmented into smaller builds to sidestep issues such
as conditional compilation of a subset of classes; separation of
client-server code; or cyclical dependencies between distinct
application libraries. This in turn created extra complexity with
running builds, since multiple builds had to be run in order to build
the application as a whole - one or more per project. While the first
version (1.x) did indeed address this new multiple projects issue, it
did so as an afterthought. The Reactor was created to act as a sort
of <apply-to-all-these> function, and the multiproject plugin
was later added to provide Reactor settings for some common build
types. However, this solution (it <is> really only one solution,
plus some macros) really never integrated the idea of the
multi-project build process into the maven core conceptual
framework.
* Why Change the Plugin Architecture?
See the previous section for the long version, but the short version can
be summed up by the following list of benefits.
* A managed lifecycle
* Multiple implementation languages
* Reusability outside of the build system
* The ability to write Maven plugins entirely in Java
In Maven 1.0, a plugin was defined using Jelly, and while it was possibly to
write a plugin in Java, you still had to wrap your plugin with some obligatory
Jelly script. An XML-based scripting language which is interpreted at run-time
isn't going to be the best choice for performance, and the development team
thought it wise to adopt an approach which would allow plugin developers to
choose from an array of plugin implementation choices. The first choice in
Maven 2 should be Java plugins, but you may also use one of the supported
scripting languages like Beanshell.
To summarize, the development team saw some critical gaps in the API and
architecture of Maven 1.0 plug-ins, and the team decided that addressing
these deficiencies was critical to the future progress of Maven from a useful
tool to something more robust.