does it make sense to have a maven submodule (which doesn't have any submodules to itself) to have a pom packaging?
Is there any use of doing that at some instance?
If not does it mean that all my last level submodules should have a packaging which is not pom?
Typically, there is a certain lifecycle associated with the packaging, e.g. the "jar" packaging will run the maven-compiler-plugin during the "compile" phase, etc.
If you choose "pom", then there is a very limited default lifecycle - I guess only the the "install" and "deploy" plugins are bound to the respective phases. You could probably use it if you want to have more control over what happens in a build.
Typically, you only would use "pom" packaging for aggregator modules (those that have submodules).
For more details on packagings and the Maven lifecycle, you can refer to Maven: The Complete Reference - 4.2. Package-specific Lifecycles
As a real-world where I actually use "pom" packaging in a submodule:
In some projects, I have a submodule called "PROJECT-doc" which contains asciidoc documentation that I compile to HTML and PDF as part of the build. These modules have the "pom" packaging - there is no Java code to compile, no JAR to build, and no unit tests to run - just the documentation is built. I manually bind the "asciidoctor-maven-plugin" to the "generate-resources" and that's it.
I think the main question is the use of packaging pom in maven - this question was answered here: What is "pom" packaging in maven?
The short form is: yes, you shouldn't have a module without submodules that uses packaging pom.
Related
I have a parent project(has its own pom.xml) in which I import the child project as a jar with its own pom.xml.
In the parent pom.xml I have specified my child jar as a dependency - this gets resolved, but i want maven to resolve the dependencies required by my child jar.
My Use case to replicate :
When I include spring-web-mvc.jar the transitive dependencies are resolved automatically.
I have a similar requirement where I include my child.jar into a main framework project and expect the transitive dependencies to get resolved (Notw: the child.jar is not hosted it is packaged as jar and present on the local file system)
Current Structure:
Child Project:
|----/src/main/java
|----/src/main/resources
|----child-pom.xml
>This child project will be a jar as dependency in the parent project
Parent Project
|----/src/main/java
|----/src/main/resources
|----/src/main/webapp/WEB-INF/lib/child.jar
|---- parent-pom.xml
The problem:
When i create a war from parent project i want all the dependecy including transitive ones to show in WEB-INF lib.
Currently this is not happening.
First when talking of parent/ child Maven projects normaly you have your"childs" specified as modules in a common parent project which itself is beeing packed with the packaging type pom rather than make them a dependency of the parent project.
When it comes to the dependencies of your "childs" or generally "dependencies of your dependencies" those are called transitive dependencies and are pretty well explained in the official documentation found here: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
The resolving of those transitive dependencies is one of Mavens core strenghts and guaranteed by default unless they lead to conflicts that make the build fail.
Two things to help here are having a closer look into the enforcer plugin (http://maven.apache.org/enforcer/maven-enforcer-plugin/) and the shader plugin (http://maven.apache.org/plugins/maven-shade-plugin/) .... well and the official documentation of corse (reading the whole thing takes less than a day - then supports you further for specific topics whereas we gladly further support you too if you already have pom.xml files and you are stuck somewhere.
While the enforcer-plugin covers certain conflicts regarding different versions of the same artefacts the shader plugin will just pack everything you specified to a single jar for reverseengineering (its not the normal use case but i sometimes use it that way if i am not absolutly sure what ends in my final archives).
Also worth a look at is the dependency-plugin already available in the maven distributions - mvn dependency:tree -Dverbose will give you pretty detailed information on the resolved dependencies (and probably version conflicts).
Could somebody explain to me, what are are differences between the file pom.xml and the file effective pom.xml in an apache maven project?
The Super POM
All Maven project POMs extend the Super POM, which defines a set of defaults shared by all projects.
The Simplest POM
All Maven POMs inherit defaults from the Super POM. If you are just writing a simple project that produces a JAR from some source in src/main/java, want to run your JUnit tests in src/test/java, and want to build a project site using mvn site, you don’t have to customize anything. All you would need, in this case, is the simplest possible POM shown in The Simplest POM. This POM defines a groupId, artifactId, and version: the three required coordinates for every project.
The Effective POM
It is the merge between The Super POM and the POM from The Simplest POM.
NOTE: This info was extracted from the following link (in the link the explanation is very complete)
Maven: The Complete Reference - 3.2. The POM
You can see the difference of a pom.xml and the effective pom.xml using
mvn help:effective-pom
which is describe here.
In a multi module project you'll use a parent pom.xml for defining general settings for all modules and then in each module there will only be specific settings.
The above goal will help you analyze the resulting pom that you could of course actually use instead of the parent reference.
The whole idea is by using the generalization (super-pom) / specialization (module pom) approach there is a central place where you can specify the general configuration. This is much more efficient then having to cut&paste the general parts.
Please also note that the effective pom will add the default behavior e.g. for the jar plugin so that you can debug issues like
Maven JAR Plugin 3.0.2 Error: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them
with this approach. See also Maven `help:effective-pom` only generating for a single project, not all projects
According to the Maven lifecycle, mvn install will "install the package into the local repository, for use as a dependency in other projects locally". The local repository then stores all the jars that I downloaded remotely.
My modules have dependencies with other modules. When I run mvn package, nothing is stored in my local repository, but the dependencies appear to be fulfilled. So how does Maven handle the inter-module dependencies? Does Maven refer to the jars of each module from the built target directories or does it fetch them from another location?
Corey,
You are correct, going strictly by Maven docs implies mvn compile on:
parent_pom/
subA/
pom.xml
subB/
pom.xml # depends on subA
should fail since subA hasn't been pushed out to the local repo.
What's happening under the hood is that Maven uses the reactor to trick the build into looking into target dir of earlier submodules on the same build.
Beyond the scope of this particular question, the maven-reactor-plugin is one of the most opaque parts of Maven, but also one of the most powerful if you master it. You would do well to read up on it.
Hope that helps.
It depends on the phase you're executing. Before compile, Maven will fail, since there are no classes compiled. Between compile and package, the target/classes is used. For package and later, the target/artifactId-version.jar is used.
I have a multi module maven project. One of the modules is a reusable part which is packaged into a jar, and the other is a war web-app which depends on the first module. When I use jetty:run-exploded on the second module, the packaged jar is taken from local maven repository whereas I want the first module to be rebuild and packaged into the resulting war. Is there any way to force such behavior instead of the default one?
From everything I can tell from reading documents about Maven's design and using Maven myself this cannot be done in the projects own directory.
Maven will not follow module paths UP a hierarchy. Using -amd (also make dependencies) will only work at the top level module that ties all the other multi-module pom's together. So what you can do is this:
At the TOP level directory
mvn -amd -pl jetty_module jetty:run-exploded
I think you can use maven Advanced Reactor Options to archive this.
http://www.sonatype.com/people/2009/10/maven-tips-and-tricks-advanced-reactor-options/
The -pl or –projects option allows you to select a list of projects from a multimodule project. This option can be useful if you are working on a specific set of projects, and you’d rather not wait through a full build of a multi-module project during a development cycle.
Maven -amd(also-make-dependents ) also help to build multi module project once. Using that you can build a project and any project that depends on that project.
I've got a project with Maven in which one subproject (A) wants to depend on another subproject (B) which uses "pom" packaging.
If I do this the straightforward way, where A specifies a dependency on B with <type>pom</type>, things work perfectly if I do "mvn install", but if I run any phase earlier than install, such as mvn compile or mvn package, then it fails while trying to build A: it goes looking for B's pom in the repository, and doesn't find it.
I don't really want this pom in the repository, because it's part of our active source code and changes frequently.
For all the jar-packaged projects we build, it seems to work fine to keep them out of the repository, build with mvn package, and Maven knows how to find all the dependencies in the source and build trees it manages without resorting to the repository; however for the pom-packaged project it always wants to go to the repository.
A couple things I learned while trying to understand this:
Maven best practices encourage you to use pom-packaged projects to group dependencies, but with the added step of "mvn install" on the POM project
Maven lifecycle documentation says "a project that is purely metadata (packaging value is pom) only binds goals to the install and deploy phases"; maybe this is why the POM project is invisible as a dependency target unless I invoke the install phase? I tried binding the compiler plugin to the compile phase and this didn't seem to help.
Is there a way that I can specify the POM subproject as a dependency of another subproject in the same parent project, without installing the POM project to the repository?
It isn't purely a question of which goals are bound to which lifecycle phases for POM projects. If it were, then binding the "package" goal would solve the problem.
When building a multi-module project, Maven reads the POMs of all modules to determine dependencies between modules, so that it can build the depended-upon modules before the depending modules. It's able to achieve this even when running the "package" goal (such that the depended-upon modules are not yet in the local repository).
Therefore, the code that constructs the classpath for builds must be managing several cases, notably:
extra-project jar dependency, where it looks for the POM in the local repository, handles its dependencies, and adds the POM's jar to the classpath
extra-project pom dependency, where it looks for the POM in the local repository and handles its dependencies
intra-project jar dependency, where it looks for the POM within the project tree, handles its dependencies, and adds that module's target/classes folder to the classpath
intra-project pom dependency, where for some reason it doesn't look for the POM within the project tree, and therefore doesn't handle it's dependencies.
Notice the asymmetry in the last two cases, as compared to the first two.
I can see two solutions to your problem. One is to file a bug report, or rather a request to change the behaviour (since it's obviously intentional), perhaps only for the case of intra-project dependencies on multi-module projects. Or indeed propose a patch. But since the behaviour is intentional, you might meet a refusal. In the best of cases, you're in for a long wait. (I'd vote for your bug report though - I've been stung by that same behaviour, in a different context.)
The other solution is simply to run an install on your project. I don't really understand why you don't want the POM project in your repository: if needs be, you can use a snapshot repository, where it doesn't matter if things change frequently, to avoid polluting your main repository.
Configuring maven-install-plugin to run during the compile phase, and copy the relevant pom.xml to the repository, seems to accomplish what I wanted as far as Maven itself is concerned, though m2eclipse still is not happy (it throws "failed to read artifact descriptor" errors with no additional description for the pom.xml that has a dependency on the other POM project).