Bruno <x.ma...@melloni.com> wrote:

> I read that BOM article and many others that I googled.  If I understood 
> correctly, it seems that the ideal POM structure is:
> 
> * To have a master BOM POM that specifies key library versions and
>   pre-supplied BOMs (like  spring-framework-bom) in the
>   dependencyManagement section.
> * Maybe have a couple "parent" POMs for the different types of
>   projects (like REST service, webapp) that inherit from the master
>   BOM POM.
> * And finally inheriting from one of those parent POMs in the
>   individual project POMs.
> 
> *First question*:  Is that correct?

I’m sorry, but I don’t have enough information about your goals to answer your 
question. Before I was under the impression that you were creating a single 
library, but it seems that you plan on creating something more complex, 
possibly a multi-module project?

A BOM is basically a POM which only consists of a dependencyManagement section 
to be included elsewhere. You should generally create a BOM artifact yourself 
if you have a multi-module project, and you should only include your own 
project’s artifacts in this BOM. This BOM is a service for consumers of your 
multi-module project, because instead of having to add all individual modules 
to their project’s dependencyManagement section, they can just import a single 
BOM artifact and then depend on any module from that multi-module project, 
without having to specify its version.

You can see that for instance the Spring Boot Dependencies BOM also imports a 
lot of BOMs from other projects itself (kotlin-bom, reactor-bom, etc.): 
https://search.maven.org/artifact/org.springframework.boot/spring-boot-dependencies/2.6.3/pom

When you want to use Spring Boot’s dependencyManagement into your own project, 
you need to import it like this into your pom.xml file, and this transitively 
imports all dependencyManagement which spring-boot-dependencies contains:

——
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.6.3</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
——

This import will allow you to add any dependency managed by Spring Boot 2.6.3 
without having to specify the version in your project. For instance, to add a 
dependency on the Kotlin Coroutine core module:

——
<dependencies>
  <dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-core</artifactId>
  </dependency>
</dependencies>
——

If you plan on creating a multi-module project and you want to use a 
third-party BOM for all of your project’s submodules, then it might make sense 
to create a ‘parent’ module in your multi-module project which imports for 
instance the spring-boot-dependencies BOM, and then your submodules can use 
this parent module as their parent.

Another option is to create a parent module for your own multi-module project 
which uses spring-boot-starter-parent as its parent. As you can see 
spring-boot-starter-parent uses spring-boot-dependencies as its parent: 
https://search.maven.org/artifact/org.springframework.boot/spring-boot-starter-parent/2.6.3/pom
 By using spring-boot-starter-parent are your own multi-module's parent’s 
parent you not only import dependencyManagement from spring-boot-dependencies, 
but also all Maven plugin stuff in spring-boot-starter-parent, which may or may 
not be what you want.

> *Second question*:  Where do I place the master BOM POM and the Parent POMs 
> so that they end up in the local Maven repository and visible to project 
> builds?  I suspect that the answer might be to create a dummy Eclipse project 
> with multiple POMs and no code, then use something like the following but I 
> am not sure:
> 
> |||<||parent||>|
> |||<||groupId||>com.mydomain</||groupId||>|
> |||<||artifactId||>poms</||artifactId||>|
> |||<||version||>0.0.1-SNAPSHOT</||version||>|
> |||<||relativePath||>bom-pom.xml</||relativePath||>|
> |||</||parent||>|
> |||<||parent||>|
> |||<||groupId||>com.mydomain</||groupId||>|
> |||<||artifactId||>poms</||artifactId||>|
> |||<||version||>0.0.1-SNAPSHOT</||version||>|
> |||<||relativePath||>parent-rest-pom.xml</||relativePath||>|
> |||</||parent||>|

It doesn’t really matter where you place them. You could have the parent and 
BOM modules in separate projects, or as part of a multi-module project. If you 
look at the Spring Cloud project for instance, you’ll see that have their 
spring-cloud-dependencies BOM and spring-cloud-starter-parent modules in a 
separate spring-cloud-release repository: 
https://github.com/spring-cloud/spring-cloud-release But Spring Boot has its 
spring-boot-dependencies and spring-boot-parent modules in the same project as 
a bunch of other Spring Boot modules: 
https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project

After you install any Maven module in your local Maven repository (or even 
better: publish it to your local Maven artifact manager), your other modules 
should be to use it. If they are all part of the same multi-module project, 
then all modules in the same should be able to use them directly, without first 
needing to install them.

I realize this is all maybe a bit too much information at once, and maybe I 
haven’t really answered your questions yet. If you can let us know more about 
what exactly you’re trying to achieve, we may be able to help you with more 
focused issues.

Nils.

> On 1/26/2022 5:26 AM, Nils Breunese wrote:
>> Bruno Melloni<x.lo...@melloni.com>  wrote:
>> 
>>> If I understood the explanation, it seems that the spring boot starter 
>>> (parent) defaults to slf4j and that the code above removes that support 
>>> while replacing it with log4j2.
>> I don’t know what your goals are for this library, but I do wonder if it’s a 
>> good idea to let a library depend on Spring Boot starters. I would expect 
>> that more gets pulled in than you actually want or need, as you’ve found. 
>> Spring Boot starters are just artifacts that depend on one ore more other 
>> artifacts and are generally meant to be used by applications. Libraries 
>> typically depend on one or more those ‘lower level’ artifacts directly to 
>> explicitly define what they depend on and not pull in too much.
>> 
>> I maintain an in-house framework based on Spring Boot myself and I’d 
>> recommend importing the spring-boot-dependencies BOM of the Spring Boot 
>> version you’re targeting with your library into your library’s 
>> <dependencyManagement> section. That will allow you to use any dependency 
>> managed by Spring Boot without having to specify its version.
>> 
>> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms
>> 
>> Nils.
>> 
>> P.S. I notice your old POM uses Log4J 2.15.0, which is vulnerable to the 
>> pretty serious Log4Shell vulnerabilities.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@maven.apache.org
For additional commands, e-mail: users-h...@maven.apache.org

Reply via email to