What is the difference in Maven between dependency and plugin tags in pom.xml?
Asked Answered
H

10

177

Created project with Spring, Hibernate & Maven. My question is what is the logic behind plugin versus dependency ?

Hyperion answered 9/8, 2012 at 10:45 Comment(0)
S
288

Both plugins and dependencies are Jar files.

But the difference between them is, most of the work in maven is done using plugins; whereas dependency is just a Jar file which will be added to the classpath while executing the tasks.

For example, you use a compiler-plugin to compile the java files. You can't use compiler-plugin as a dependency since that will only add the plugin to the classpath, and will not trigger any compilation. The Jar files to be added to the classpath while compiling the file, will be specified as a dependency.

Same goes with your scenario. You have to use spring-plugin to execute some spring executables [ I'm not sure what spring-plugins are used for. I'm just taking a guess here ]. But you need dependencies to execute those executables. And Junit is tagged under dependency since it is used by surefire-plugin for executing unit-tests.

So, we can say, plugin is a Jar file which executes the task, and dependency is a Jar which provides the class files to execute the task.

Hope that answers your question!

Shortbread answered 9/8, 2012 at 12:54 Comment(8)
Can I someone tell me what is the different between phase and goal in execution?? As i knew the phase is talking about the life cycle of maven.. but why goal again? any hints? Sometimes i see people put life cycle keyword at goal... ??? (?.?)Roanna
@Roanna this SO question describes the difference: #16206278Jackfruit
@r981 Your answer needs to be more clear. This answer is better: #26292573Elaboration
I think the missed point of this answer is that: the top-level dependencies are mainly used by your artifact instead of the plugins.Balas
@Shortbread I did'n understand what do you mean with "But you need dependencies to execute those executables". If the spring-plugin is a plugin, why he needs dependencies to execute thespring executables?Baseline
@MichaelPacheco, What I meant was, spring-plugin will perform a certain task of executing a set of code, which might be dependent on some libraries, which will be specified by the 'dependencies'. Take a different example: you need a compiler to execute a piece of code; Here, your compiler is a plugin and your code is the executable. Your compiler alone is capable of executing any code, but your code might be dependent on a library, say apache commons, which will be a dependency. Your compiler can only compile the code when the dependencies are present in the classpath. I hope it's clear now.Shortbread
@Shortbread - I have a multi pom project for api automation testing. One of the maven projects has automation tests. The build section of the project pom had only 1 plugin - maven surefire plugin with reference to a suite. The entire build tag was removed. Could you please tell me what this means ? thanks.Benignant
What if, I want to use <plugin> and force add that to classpath, can we achive that? @ShortbreadMonocyte
C
55

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, 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, clean and site. The 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: compile.
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>

than :

<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 plugin and 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 :
groupId:artifactId:packaging:classifier:version.
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 : groupId:artifactId:version.
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.
The 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).
The 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>
Carburetor answered 31/8, 2018 at 16:44 Comment(4)
great explanation!, since I am not well versed with setting up dependencies in Java, I still have a doubt, I am currently working in IntelliJ, and created a maven project, when I tried to include webdriver-ie I have two options, either include it as plugins or dependency, I included both to compare, & observed both has exactly same groupId the only difference was that the plugins didn't come with a specific version but dependency come with 0.6.685. Could you pl explain it in layman(in relation to this example) terms what's the difference, which one to use when. Any suggestion?Blacksmith
Hard to give the most exact answer without seeing your pom.xml. But a thing that should interest you is that specifying the dependency version is mandatory (in the current pom or in the parent pom if it is an inherited dependency) in any Maven version while since Maven 3 (probably a bad good idea as feature), specifying the plugin version is optional. Maven will use the last version available in the release repository where Maven finds it. (1/2)Carburetor
Note that it is a bad way to specify a plugin. It doesn't make your build reproducible over the time (cwiki.apache.org/confluence/display/MAVEN/…) . You should see a warning in the build. So "what is the difference ?". Plugins perform tasks for a Maven build while dependency are libraries (jar or whatever) needed in the classpath during the build. If the build of your project is the same whatever the case (using library or the plugin way), it means that the plugin is helpless as not used.(2/2)Carburetor
Thank you, this is a great explanationConcession
H
50

Maven itself can be described as food processor which has many different units that can be used to accomplish different tasks. Those units are called plugins. For example, to compile your project maven uses maven-compiler-plugin, to run tests - maven-surefire-plugin and so on.

Dependency in terms of maven is a packaged piece of classes that your project depends on. It can be jar, war etc. For example, if you want to be able to write JUnit test, you'll have to use JUnit annotations and classes thus you have to declare that your project depends on JUnit.

Hayman answered 9/8, 2012 at 10:51 Comment(3)
thanks for the quick reply , sorry but still i am confused as i know JUnit is also a framework and (hibernate,spring) also comes under framework only , so is that means in cases (hibernate,spring) could also be configured in dependency tags ? i hope you got my question.Hyperion
Yes, and as far as I know there is no such thing as Spring maven plugin. Usually, Spring libs (or Hibernate, or JUnit, or TestNG etc.) are declared as dependencies for your project. If you are new to maven I'd recommend to read this very good book.Hayman
@AndrewLogvinov - I have a multi pom project for api automation testing. One of the maven projects has automation tests. The build section of the project pom had only 1 plugin - maven surefire plugin with reference to a suite. The entire build tag was removed. Could you please tell me what this means ? thanks.Benignant
F
13

One line answer - basic understanding

Plugin is a tool you use at the execution of your maven build

Dependency means kind of any library which you will use in your code

Falcate answered 29/4, 2020 at 11:48 Comment(0)
C
11

If you're coming from a front-end background like me, and are familiar with Grunt and npm, think of it like this:

First you would run, say, npm install grunt-contrib-copy --save-dev. This is like maven's <dependency></dependency>. It downloads the files needed to execute a build task.

Then you would configure the task in Gruntfile.js

copy: {
  main: {
    src: 'src/*',
    dest: 'dest/',
  },
}

This is like maven's <plugin>/<plugin>. You are telling the build tool what to do with the code downloaded by npm/<dependency></dependency>.

Of course this is not an exact analogy, but close enough to help wrap your head around it.

Clad answered 20/9, 2015 at 14:41 Comment(1)
Not an exact analogy, but surely a useful one! Thanks :-)Mirabella
S
5

Plug-ins are used for adding functionalities to Maven itself (like adding eclipse support or SpringBoot support to Maven etc.). Dependencies are needed by your source code to pass any Maven phase (compile or test for example). In case of JUnit since the test code is basically part of your code base and you call JUnit specific commands inside test suites and those commands are not provided by Java SDK therefore JUnit must be present at the time Maven is in the test phase and this is handled by mentioning JUnit as a dependency in your pom.xml file.

Shutdown answered 20/8, 2015 at 14:33 Comment(0)
O
4

In simple words:

Plugins are used to add some additonal features to the software/tools(like Maven). Maven will use the added plugins at the time of building when we use the build command.

Dependecies are used to add some addtional code to your source code, so a dependency will make some extra code (like Classes in Java) in the form of library available for your source code.

Overnight answered 2/7, 2022 at 16:53 Comment(0)
C
1

Maven at its heart is a plugin execution framework -- as per formal and standard compact definition. To make it more clear, the commands you use like maven-install/clean/compile/build etc for creating/executing jars, which we sometimes manually run too. So, the things which you want to run (or configure or execute) you basically put them in dependency tag of mavens pom and the answer so as to who will run these dependencies (required for environment setup) be the plugins.

        javac (compiler) dependency.java (dependency) 
Crybaby answered 1/1, 2019 at 17:51 Comment(0)
M
1

A plugin is an extension to Maven, something used to produce your artifact (maven-jar-plugin for an example, is used to, you guess it, make a jar out of your compiled classes and resources).

A dependency is a library that is needed by the application you are building, at compile and/or test and/or runtime time.

plugin and dependancy

Meantime answered 29/10, 2019 at 9:16 Comment(0)
C
0

in simple words:

if you are coming from javascript world. in package.json you have dependencies and dev-dependencies.

in MAVEN plugins are dev-dependencies they are not a part of actual build.

Calabash answered 24/1 at 22:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.