Plugins and dependencies are very different things and these are complementary.
What plugins are ?
Plugins perform tasks for a Maven build. These are not packaged in the application.
These are the heart of Maven.
Any task executed by Maven is performed by plugins.
There are two categories of plugins : the
build and the
reporting plugins :
- Build plugins will be executed during the build and they should be configured in the
<build/> element from the POM.
- Reporting plugins will be executed during the site generation and they should be configured in the
<reporting/> element from the POM.
According to the maven goal specified in the command line (for example
mvn clean package or
mvn site) , a specific lifecyle will be used and a specific set of plugins goals will be executed.
There are three built-in build lifecycles:
default lifecycle handles your project deployment, the
clean lifecycle handles project cleaning, while the
site lifecycle handles the creation of your project's site documentation.
A plugin goal may be bound to a specific phase of a specific lifecyle.
For example the
maven-compiler-plugin binds by default the
compile goal to the lifecycle phase:
Most of maven plugins (both core plugins and third party plugins) favor convention over configuration. So these generally bound a plugin goal to a specific phase to make their usage simpler.
That is neater and less error prone :
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin>
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <executions> <execution> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin>
What dependencies are ?
Dependencies are Maven artifacts/components required for the project.
Concretely most of dependencies are jar (that is libraries) but these may also be other kinds of archives : war, ear, test-jar, ejb-client ... or still POM or BOM.
In a pom.xml, dependencies may be specified at multiple places : the
<build><dependencies> part , the
dependencies management part or still in a
plugin declaration ! Indeed some plugins may need to have some dependencies in the classpath during their execution. That is not common but that may happen.
Here is an example from the documentation that shows that
dependency may work together :
For instance, the Maven Antrun Plugin version 1.2 uses Ant version 1.6.5, if you want to use the latest Ant version when running this plugin, you need to add
<dependencies> element like the following:
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.2</version> ... <dependencies> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant-launcher</artifactId> <version>1.7.1</version> </dependency> </dependencies> </plugin> </plugins> </build> ... </project>
In Maven, dependencies are referenced in a specific format :
The classifier (that is optional) and the packaging (
JAR by default) are not commonly specified. So the common format in the
dependency declaration is rather :
Here is an example of dependency declared in the
<build><dependencies> part :
<build> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.14.Final</version> </dependency> <dependencies> </build>
Dependency doesn't have a phase binding as plugins to address the "when" question.
But it has a counterpart : the scope.
Indeed declared dependencies are usable by the application at a specific time according to the scope we defined for these.
scope is a central concept about how a dependency will be visible for the project.
The default scope is
compile. That is the most commonly needed scope (convention over configuration again).
compile scope means that the dependency is available in all classpaths of a project.
The scope defines in which classpaths the dependency should be added. For example do we need it at compile and runtime, or only for tests compilation and execution ?
For example we previously defined Hibernate as a
compile dependency as we need it everywhere : source compilation, test compilation, runtime and so for....
But we don't want that testing libraries may be packaged in the application or referenced in the source code. So we specify the
test scope for them :
<build> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.1.0</version> <scope>test</scope> </dependency> <dependencies> </build>