What are all the default plugins used by maven? - java

From what I read, maven cycles through the lifecycle phases and goals invoked through the command line and it simply cycles through the mentioned phases and goals. The defaults in pom.xml make sure that maven runs sensible defaults by always running a series of plugin goals according to packaging using default bindings.
Also, if I only and only want to download dependencies and do nothing else, I can call mvn dependency:generate-sources.
So my question is:
If we run mvn install, it also downloads the dependencies mentioned in the pom.xml? Does this happen because calling install calls all the phases up till install including generates-sources which is bound to dependency plugin by default?
If not, who is responsible for fetching all the dependencies? Maven core or some other plugin?
If yes, the list of plugins invoked by default does not seem to be exhaustive. What other plugin bindings exist in pom.xml?

Yes
N/A
All maven projects have, at their base the "Super POM" which lists all of the defaults for maven. You can look there for everything. This "Super POM" is placed as the parent for any POM that doesn't list a parent explicitly.

Related

get partial maven dependency tree in offline mode

I'm trying to run some unit tests with Apache Maven. I hoped this would be as simple as running the test "goal". But when I did that, maven complained that it could not download some dependencies and thus can't run my tests. This sounds fine, except that I have no idea why it decided I need those dependencies; they are not in my pom.xml, and I doubt they're in my transitive dependencies either. (I'm not sure about that last part; they very well might be in my transitive dependencies.)
Luckily, maven has the perfect tool for this: dependency:tree will tell us exactly which dependency is getting pulled in by what. Except for the small problem that maven thinks to itself "in order to build the tree, I have to resolve the dependencies first" so it tries (and fails) to download those very same dependencies so that it can build the part of the tree that's under them.
So now I don't have a tree, and I have no idea how to proceed from here.
How exactly would you think that maven could resolve transitive dependencies (= dependencies of dependencies) without resolving the dependencies first? Escpecially for the goal "test" also the dependency scope "test" has to be used, which is more then the default scope "compile".
You can use the goal dependency:go-offline to prepare for the offline mode. Maven downloads then all required dependencies. Find the detailed docs for that on https://maven.apache.org/plugins/maven-dependency-plugin/go-offline-mojo.html
You could also have a look at this answer to get another opinion on going online.
The main problem is maven downloads dependencies by demand, you may just check that by triggering different lifecycle phases like mvn initialize, mvn validate, mvn compile, mvn package and checking what maven is trying to download. Sometimes it is possible to figure out project dependencies via analysing project object model (pom), sometimes it is not, especially when plugins define their own dependencies either implicitly or explicitly, some examples below:
we may ask maven-dependency-plugin to download something via dependency:copy-dependencies
exec-maven-plugin has similar functionality: Running Java programs with the exec goal
maven-invoker-plugin may run poms which are part of project but not a part of reactor.
In short: neither maven plugin will able to download all required dependencies. The only "reliable" way to go offline is to run target goal and only then go offline, unfortunately even in this cases some weird things may happen, especially when you or dependency authors are using snapshot versions, version ranges, third-party repositories, etc (my own preference is to run maven with -llr flag to make it more reliable).

How to decide which plugin to use in maven?

I was going through the maven documentation. I saw maven works using plugins, for each phase there is one or more plugin and for each plugin there is one or more goals. there are plugin for compile, install, deploy, clean etc. I saw in my project they used maven-clean-plugin. Then how maven clean install command is working if we did not put the maven-install-plugin? Question might be bit silly but i am new the this world and appreciate your help.
That would follow up with some default configuration of each plugin inherited with Maven's BOM. Executing
mvn dependency:resolve-plugins
shall help you identify these versions of the plugins inherited.
So primarily to ensure you work with a specific(or updated) version of the plugin with the desired configuration of your project, you can explicitly define them in the pom.xml, otherwise, just let be.
The Maven lifecycle has standard bindings for plugins to the different phases.
If you run mvn clean install you run the plugins that a attached to the phases by default.

What Maven profile is executed when no profile is specified via -P? [duplicate]

This question already has answers here:
How to activate a Maven profile per pom.xml?
(3 answers)
Closed 7 years ago.
I'm not familiar with Maven and am trying to figure out how it works on our existing project.
project and folder structure is basically
A
A\1
A\2
A\3
Inside each folder is a pom file. Each pom contains 1 or more defined profiles.
What I do not understand is with this command
A>mvn install
How do all of the pom get executed and which profiles are being executed?
I don't see any tags marked with activebydefault
Frustrated when I need to spend time learning at step 1 and build some projects but am forced to be at step 50 without anybody on the team that knows the first thing about Maven. Of course solutions are always due yesterday.
Profiles can be specified in your POM, in your parent POM, in your settings. Hence, looking just at your POM file may not be enough.
Running mvn help:active-profiles would give you a list of all active profiles and from which source (pom or settings).
Running mvn help:all-profiles would give you a list of all available profiles, the active ones and from which source (pom or settings).
Running mvn help:effective-pom -Doutput=full-pom.xml would provide you the full POM file (in the full-pom.xml generated file), as a merging of current pom, parent pom and settings. That would be the full source of true.
The structure you describe is for a multi-module maven project, which means A is the aggregator project (having packaging pom, its only delivery is a pom file, its only function is to provide the modules it will build).
However, beware that in Maven aggregation and inheritance are two different concepts, which are often used together: aggregation means I will build as part of my build all of my defined modules; inheritance means I will inherit configuration from my parent pom. As such, A\1 may inherit profiles from project A if in the pom of A\1 you will find A defined as parent (which is often the case, to have an aggregator which is also parent of all the defined modules).
Why to have an aggregator? To have a centralized build and location of correlated sub-projects while still keep a good separation of concerns across sub-modules. Moreover, as Maven best practices, a project should only generate one artefact, hence it might be the case to have a web application having logic in one module, war generation in another module, ear generation in yet another module, for instance.
Why to have inheritance? To have a centralized place where to set shared/common configuration, like profiles but also dependencies and dependencies management.
Lastly, it is a common misunderstanding and hence be also aware that:
If a profile is active by default in Maven, it will be part of the default build. However, if you activate a profile via command line (via the -P option) you will then activate the requested profile but also and automatically deactivate the one which was active by default
the mechanism above doesn't apply to profiles defined in the settings.xml of your maven installation (which are applied by default, if activated, to all the Maven builds on the concerned machine).
Update A further note on this answer leveraged by some comments: a Maven build is specified as part of the build section (a flow of plugins executions), which doesn't necessarily need profiles. Profiles are generally defined to add a further behavior to the build, but it is good practice to have a build building successfully regardless of any activable profile, that is, I don't have to know about the defined profiles to run your build, it's a core concept of maven, harmonization and convention over configuration: given a Maven project, I can always assume that simply mvn clean install would do the required magic.
For a list of common questions about starting with Maven, the official Getting Started Guide already provides a good help.
Also check the Profiles Pitfalls of the official Introduction to Profiles for further guidance on profiles.
No profile is active unless you have one marked as activeByDefault.

mvn install vs jar:jar

What is the difference between the "mvn install" command, versus the use of the jar:jar plugin ?
Its clear that "install" seems to build a jar, and so, I am wondering what the need for the jar:jar plugin would be.
There are two types of things you can specify on the maven command line:
lifecycle phases (these do not include a : character)
plugin goals (these include at least one : character, depending on how fully you specify the plugin, it could be short-name:goal or groupId:artifactId:goal or groupId:artifactId:version:goal)
There are three lifecycles: default, clean and site. Each lifecycle consists of a series of phases. When you specify a phase in a lifecycle then Maven will execute in order all the phases in that lifecycle up to and including the specified phase.
When you specify a plugin goal then that plugin goal is invoked and only that plugin goal.
Maven has a concept of a packaging which defines a default set of plugin bindings to lifecycle phases. For example the jar packaging (which is default unless your pom.xml includes a <packaging>...</packaging> element) by default binds jar:jar to the package phase and binds install:install to the install phase.
So when you type
$ mvn package
Maven will run all the way through the lifecycle phases executing plugins that are bound (either from the lifecycle or by specifying plugin executions in the pom) as it goes along.
When you type
$ mvn jar:jar
Maven will just run the jar plugin's jar goal.
The lifecycle is 99 times out of 100 the one you want to use.
Here are the times you would typically want to invoke plugin goals directly
jetty:run to start a webapp server
surefire:test to quickly re-run the tests (usually with -Dtest=... to specify the specific one
release:prepare release:perform to release your code
versions:... to do some updating or querying of version related stuff, e.g. versions:display-plugin-updates
ship:ship or cargo:deployer-deploy to push (ship) your built artifacts to a hosting environment
mvn install command will "execute" the maven lifecycle up to the install phase.
It means that all previous phases will be executed (including the package phase).
On a simple maven jar project, the package phase is bind to the maven-jar-plugin. And so executing mvn install will execute at some point jar:jar.
install puts the artifact in your local (on your machine) maven repository, jar:jar does not. If you call jar:jar on a library then try to reference that library in another project, it will not be in your local repository.
Also note that mvn package is a cleaner way to do packaging, rather than using jar:jar.

Deploying a maven sub-module to a repository for other projects to use (without parent)

The problem is, in our company we have a project with multiple sub-modules, however one of the sub-modules is just a collection of API declarations and is meant for other (3rd praty) projects to use. I want to keep it as a sub-module because is easier to maintain and build (dependency and property inheritance). Other sub-modules in this project are also dependant on it.
The question I have is, if there exist a good practice or a nice way to execute a deploy phase that will upload just this sub-module to a different repository (can be duplicated too) without it having a dependency to parent pom.
What I have already tried:
I have already checked the deploy:deploy-file, but the problem is when it comes to SNAPSHOT builds. We wish to be able to publish SNAPSHOTS and release builds, and snapshots have different repository than release ones, but deploy-file goal can only have one url parameter. I do not wish to use different profile for snapshot deploy. Than I tried to use maven build-helper and its regex-property to be able to change the repository url if the version is a SNAPSHOT, but was unable to do so because of the plugin and regex limitations.
The last option is I can make a plugin for this, but I wish to know if there is a more elegant way to solve this the "maven way".
You can deploy this module separately but only for SNAPSHOT's for a release it does not make sense. The deployment of a module can be done via:
mvn -pl TheModuleYouWouldLikeToDeploy deploy
may be you need to add the option -am (also make dependencies) like:
mvn -am -pl TheModuleYouWouldLikeToDeploy deploy
Apart from that your approach sounds wrong cause if you are using a multi-module build why not deploying the whole build via mvn deploy ? May be it would be better to let do the job via a CI tool like Jenkins.

Categories