| ------ |
| 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. |