I have a maven project composed of several submodules.
Let's call the submodules shared and webapp. The project is normally built from the parent POM, which resides in the parent directory. So the directory layout looks like:
myproject/pom.xml
myproject/shared/pom.xml
myproject/webapp/pom.xml
I have a specific plugin that I want to be executable from the command line in the top-level directory. I do not want it to run by default in any phase. So usually I want to run mvn clean install, and the plugin should not execute at all in this case. But also I want to be able to say mvn clean install com.mycompany:myplugin:goal and the execution should run in this case, but the execution should only run once for the webapp submodule. The execution should not run either for the parent POM or for the shared submodule when I specify this on the command line.
The problem I have is that if I define the execution in the parent POM, it runs repeatedly for every submodule. If I define the execution in the webapp POM, it is not accessible through a command line invocation of Maven.
I want to do this in a single Maven comand and that single command must also be able to build & run phases for all submodules -- not just the webapp submodule -- hence the -pl command line option does not work for this case?
Related: Running a specific Maven plugin goal from the command line in a sub-module of a multi-module reactor project
Is such a thing possible? If it's impossible, I'll accept an answer stating that.
The plugin has to be defined in the parent pom to be executable at the parent level. But if defined in the parent, the plugin is executed for all modules.
Since this is your plugin (com.mycompany:myplugin), you can define a "no-op" configuration option in the plugin implementation. Then, in each pom where you want the plugin to do nothing, you use that configuration option.
As an example, the docker-maven-plugin does exactly that. If you use:
<configuration>
<skipDocker>true</skipDocker>
</configuration>
the plugin will not execute for that pom.
Related
I have several Maven projects which share a common parent as following:
project-parent
project-1
project-2: includes project-1
project-3: includes project-2
Here, project-3 has project-2 in its dependencies and project-2 has project-1 in its dependencies, as an example.
When I push a project to git, Jenkins automatically rebuilds to dependent projects. For example, when I push project-3, project-2 will be rebuilt. Because of that, project-1 will be rebuilt as well. This happens because Jenkins has knowledge about the dependency graph.
However, when I build project-3 locally on my development machine, I have to remember to rebuild project-2 (and project-1) as well.
I could add a <modules>...</modules> section to the parent project and simply rebuild the parent project. This will rebuild the whole project, all child projects included. However, I would rather not do that, as there are a lot of projects and some of them require a lot of time to build.
So I want to build one project (the one I'm working on) and somehow automatically (or conveniently) rebuild all dependent projects, similar to the Jenkins behavior. Basically, I want to achieve the Jenkins behavior locally on my development machine. Is this possible?
You can execute the following command from your parent project (assuming you have the my-child-module in the <module>...</module>:
mvn clean install -pl my-child-module -am
This command will build the project my-child-module and its dependencies.
-pl, --projects
Build specified reactor projects instead of all projects
-am, --also-make
If project list is specified, also build projects required by the list
-amd, --also-make-dependents
If project list is specified, also build projects that depend on projects on the list
Source
You can also create an aggregator completely independent of the rest: each <module> point to a path of a folder containing a pom.xml (it may also directly target a pom.xml).
<project>
...
<modules>
<module>project-parent</module>
<module>project-1</module>
<module>project-2</module>
<module>project-3</module>
</modules>
...
</project>
In this scenario, building from that aggregator will allow maven to take full knowledge of your dependency graph and build in order. You will only have to take care to update properly the version to ensure it match (if project-2 depends of version 2 of project-1 and project-1 is in version 3, then this won't work).
You need not put module you don't want, however be aware that if a module have children <module>, it will also build them.
I have 2 Java projects where project2 depends on project1's jar. Bot are Maven projects. At the moment this is what I do to create a jar from project2:
c:\eclipse\workspace\project1> mvn install
c:\eclipse\workspace\project2> mvn package
Could I somehow "include" the mvn install command inside projects2's pom.xml so that only the last command would be enough to create the jar?
You have described a basic use case of Maven Reactor (i.e. Maven's fancy name for multi-project/module build).
In this respect, you'd have your two projects alongside a parent pom (which would be the predecessor of both project1 and project2).
Within a Maven multi-module build, modules are allowed to depend one on another; so in your case you'd specify project1 as a dependency of project2's just like you do with any other dependency. Then, when you run package (on the parent pom) Maven will see the dependency, build project1 first and then use the built jar for project2.
I want to see the dependency tree of a project without actually downloading those dependencies.
I have a project whose build fails because there is some dependency which is not present in central repo, however it is not a direct dependency and I am not aware which one of my dependencies refers to it.
Now when I run mvn dependency:tree command, it builds the project and hence fails.
One way to do it is keep a dummy jar in local repo with the same name. It will not try to download the dependency and generate the entire tree. However is there any other way to do this ?
If you are using eclipse there is a "Maven POM Editor", which shows not only the maven XML, but also a dependency hierarchy view.
A working build is not necessary for it, just a correct POM XML file.
It should get installed, when you install the eclipse m2e plugin.
The update site is http://download.eclipse.org/technology/m2e/releases.
Maybe Maven dependency:analyze-only
mvn dependency:analyze-only
Analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared. This goal is intended to be used in the build lifecycle, thus it assumes that the test-compile phase has been executed - use the dependency:analyze goal instead when running standalone.
or dependency:resolve:
mvn dependency:resolve
mvn dependency:tree -DoutputFile=tree.txt
I just starting using maven in my new project.
I am trying to create artifacts(java files) of a project A into another project B in order to resolve their cyclic dependency.
If I run the whole build for the first time,its working fine. The jar of B contains classes of both project A and B.
However, if I make changes to only project B , and run the build, only project B is running and build is failing . Thats because sine no changes are done to project A, maven is not running it and the artifacts are also not getting generated.
Can anyone advise how can I trigger the build of a project even though no changes are done to it.
exec mvn with clean phase! i.e.
mvn clean package
Phases are actually mapped to underlying goals. The specific goals executed per phase is dependant upon the packaging type of the project. For example, package executes jar:jar if the project type is a JAR, and war:war if the project type is - you guessed it - a WAR.
An interesting thing to note is that phases and goals may be executed in sequence.
mvn clean dependency:copy-dependencies package
This command will clean the project, copy dependencies, and package the project
mvn site
This phase generates a site based upon information on the project's pom. You can look at the documentation generated under target/site.
What is the difference between mvn clean install and mvn install?
clean is its own build lifecycle phase (which can be thought of as an action or task) in Maven. mvn clean install tells Maven to do the clean phase in each module before running the install phase for each module.
What this does is clear any compiled files you have, making sure that you're really compiling each module from scratch.
Maven lets you specify either goals or lifecycle phases on the command line (or both).
clean and install are two different phases of two different lifecycles, to which different plugin goals are bound (either per default or explicitly in your pom.xml)
The clean phase, per convention, is meant to make a build reproducible, i.e. it cleans up anything that was created by previous builds. In most cases it does that by calling clean:clean, which deletes the directory bound to ${project.build.directory} (usually called "target")
You can call more than one target goal with maven. mvn clean install calls clean first, then install. You have to clean manually, because clean is not a standard target goal and not executed automatically on every install.
clean removes the target folder - it deletes all class files, the java docs, the jars, reports and so on. If you don't clean, then maven will only "do what has to be done", like it won't compile classes when the corresponding source files haven't changed (in brief).
we call it target in ant and goal in maven
To stick with the Maven terms:
"clean" is a phase of the clean
lifecycle
"install" is a phase of the
default lifecycle
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference
Ditto for #Andreas_D, in addition if you say update Spring from 1 version to another in your project without doing a clean, you'll wind up with both in your artifact. Ran into this a lot when doing Flex development with Maven.