POM files to use - spring

I'm going to be building a project from the Spring Examples package. Specifically, I am going to be building onto the Simple JPA Example. When I view the POM file however I notice that it references a parent, which contains pretty much every Spring project you can imagine.
Is there a way to tell which POM files I need in order to have the 'Simple JPA Example' project work?
EDIT:
This is why Maven needs to go away!

You can move all the dependencies into the project's pom, remove the reference to the parent pom, then use the maven dependency plugin's analyze goal to sort out what you need. There are examples and a rather nifty script referenced from this popular SO question.

Which parent pom is it (and which sample)? If it's this one have another look at the parent - it doesn't define any dependencies, only dependency management, so that you get a consistent set of versions of everything without having the specify versions in your own dependencies. It's quite a common pattern (look for a blog on "bill of materials" configuration). See also docs on how to use your own parent.

Related

Is it possible to see the actual pom.xml executed, including parent dependencies/plugins?

I need to extract a project from a repository which uses several layers of parent projects. Every parent project adds some dependency or plugins or properties. This is becoming a nightmare as I'm not able to build any more the project, once I've manually added pieces from parent projects.
Is there a way to create a list of all dependencies/plugins/properties which are linked by a single pom.xml so that I can build a portable, single Maven project?
Thanks
You can create the effective pom (https://maven.apache.org/plugins/maven-help-plugin/effective-pom-mojo.html) that is a kind of merge with all parent POMs.
This is useful to understand the complete list and configuration of plugins.
Whether this helps you to build a "portable" Maven project, I don't know. Without the appropriate Maven repositories with all the plugins, dependencies and so on, Maven will not build.
Base concept of Maven is CoC (Convention over Configuration). Maven has a SuperPOM and all model is inherited from that. SuperPOM is located in maven-model-builder jar. Here is the source https://maven.apache.org/ref/3.6.2/maven-model-builder/super-pom.html
Each Maven goal is using a merged model called effective pom. The help plugin has effective-pom goal which displays the full model including parent model(s) and SuperPOM.
So the answer is just run: mvn help:effective-pom command to see actual model.

How does the Intellij Idea change the scope of dependencies?

I found this function in Project Structure in Intellij Idea:
It seems that this UI can manually change the scope of the dependencies. However I found that it does not change the pom.xml file, so how can it manages to change the scope?
Besides, what is the corresponding operation in Linux?
That particular view is geared more towards projects which lack dependency management from something like Maven or Gradle, and will not interfere with either. In fact, this particular listing is built based on those dependencies and exclusions.
If you want to change the scope of your dependencies in a project that already contains Maven and Gradle, look to do so in their respective files (pom.xml / build.gradle).

Maven dependency aliasing

I've just noted that my war contains both woodstox-core-asl-4.4.1.jar and woodstox-core-5.0.2.jar. They are two different version of the same library, but the library changed both groupId and artifactId. Furthermore both are included in my war as transitive dependencies by two different modules of my project.
I know that I can use exclusions to remove the old version of the library but in this case I should also explicitly "include" the new version in case that module would be used alone (that is not with the other one that includes woodstox-core-5.0.2.jar).
I don't like this solution. Is there any way to declare that woodstox-core is an alias of woodstox-core-asl so that Maven includes only one of these jars?
A similar problem affects old Spring 2.x that published both an all-in-one artifact and smaller separated artifacts. However I think that the most common issue is the one related to artifacts that change their groupId and/or artifactId.
There is no way to do this. Maven doesn't understand the concept of aliases. If it did, then that would open the door to a whole other kind of dependency hell.
What you've described -- adding an <exclusion/> for the <dependency/> for all dependencies that need it and then explicitly adding a new <dependency/> for the renamed artifact -- is the only way you can achieve this at the moment.

Module inheritance vs aggregation

We have a big and deep module structure with three "real" layers of inheritance and three to four layers of module aggregation.
I am fine with the real inheritance: a company wide super-pom, a product-wide parent and a customer-wide parent for customizations of the product.
But I observe that also the "empty" aggregating modules are defined as parents of their submodules.
If the whole concept is the same as in OO, this makes no sense to me if the aggregating modules (they are empty besides their submodules) add no specific configuration to the pom.
Is there any other reason (perhaps operational) why this could be useful?
Sidenote: Introduction to the pom is not clear in this respect: term "parent" is not clear: it can mean super-pom (=parent in inheritance tree) or aggregating pom (=parent in filesystem...)
There is a great problem in the definition of these concepts in the Maven community. You are right with stating that a parent-pom is inheritance and module-pom is composition. But unfortunately the separation of these two concepts have no history in Maven. The Maven documentation says clearly that it is better to separate them. This would result in this ideal structure
app-api/
app-impl/
app-war/
app-parent/
pom.xml
Where pom.xml is the module pom.
But almost every project you will see in the open source sector does not distinguish between them.
This has a reason: Many plugins do not distiguish between them as well. And even Maven itself assumes another setting: If <relativePath> is not set Maven assumes that the parent is at ... So every project has to point to <relativePath>../app-parent</relativePath> as parent.
The most popular plugin that has huge problems with the mentioned structure is the maven-release-plugin! You will face strange problems when you do not follow the assumption that the module-pom is the parent-pom.
The worst bug is that the release-plugin cannot replace version-properties in your parent and fails because of SNAPSHOT-Dependencies. Your parent perhaps will contain something like this
<properties>
<app-api.version>1.1-SNAPSHOT</app-api.version>
<app-impl.version>1.2-SNAPSHOT</app-impl.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>myorg</groupId>
<artifactId>app-api</artifactId>
<version>${app-api.version}</version>
</dependency>
<dependency>
<groupId>myorg</groupId>
<artifactId>app-impl</artifactId>
<version>${app-impl.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
Normally while releasing these properties would automatically be set to their release versions 1.1 and 1.2. But the release-plugin (tested up to version 2.2.2) fails with a message that the module cannot be released with snapshot dependencies.
If you only "skip" some module-poms this might not be a problem when you define <relativePath> correctly. But you have to try and expect some bugs in Maven plugins. Besides these bugs you are totally right to seperate the poms and I would give it a try if you have the time to make a sandboxed release.
The short answer IIUC is, you don't inherit from your aggregation-only poms. You do when your aggregator is the same as your parent, as in the canonical maven structure. But if you separate aggregator from parent, don't inherit from the aggregator
The inheritance of a parent pom is usefull if you have properties that are valid for several projects. From what I understood you already got that part right ;-)
What you call aggregating modules has a valid practical use too. You can group several submodules into a single pom. If you want to build your project you mostly don't want to build every module sperately but join them into one single application. This can be done by such a pom that references all the submodules as such. It can't be done with just the concept of a parent pom as it knows nothing of the other modules.
Adding an eclipse perspective here :
when you create maven module within a maven project using eclipse IDE's wizard, by default, the new module will created as child of top level project and also top level project will be an aggregation of child.

How should I share Maven DepdendencyManagement from multiple sources?

I have a Maven project multimodule project. Some of the modules create custom packaging for the libraries produced by the other modules. The packaging being used has its own suite of versioned dependencies that I need to play nice with.
As an example: my parent POM might have an entry for e.g. commons-codec:commons-codec 1.4, my "core-lib" POM includes it as a dependency (sans explicit version), and I want to make sure my packaging module bundles in the right version. However, the specific type of custom packaging that I'm using also needs e.g. log4j:log4j 1.2.15, and I want to make sure that when my packaging module runs, it also bundles the correct log4j version.
Here's the wrinkle: the example POM I'm working from for "project that makes {custom packaging}" uses a parent that's provided by the custom-packaging team. If I use their parent, I lose the version info for commons-codec. If I use my parent, I lose the version info for log4j.
Now, ordinarily if I ask "how do I make A and B depend on the same version", you'd answer "make A and B have the same parent, and include a dependencyManagementsection in the parent". My problem is, I need A, B, and C to depend on the same version, but I don't have any control over C.
I think this is what Maven "mixins" are meant to address, but of course they don't exist yet. In the meantime, what I've been doing is picking one parent, then copy-and-pasting the dependencyManagement section from the other POM, with a comment saying "make sure you keep this up to date". Obviously this is an ugly, ugly hack, but I haven't found another way to keep current with both sides.
What about using the assembly plugin to pack up your artifact with all its dependencies and having your packaging module run on that instead? Then you're not trying any pom magic. It's just a matter of one project using the artifact from another project, like usual.
For now, I'm going to accept the answer of "this is one of the really sucky things about Maven". Maybe this question can get updated when Maven 3.1 finally launches.
Could you not activate multiple profiles which have their own dependency section pulling in the required libraries when enabled. This allows some nice flexibility due to the ways that profiles can be activated.

Resources