There are two types of usages for <exclude> tag in pom.xml
Usage1) Not to include in transtive dependency
Usage2) Not to include in JAR
Your question (and the example code snippet that you provided) belongs to second one (Usage2). You are thinking that it is related to the first one (Usage1). That is the reason for confusion.
let me answer your questions with related concept
:
Question1:
Is this something that lombok is also available and when I add it explicitly, it is excluded by adding this block automatically to the pom.xml?
Answer1:
No. The "lombak" dependency that you added is still there and perfectly valid. The <exclude> block inside <plugin> block does not remove/exclude your "lombak" dependency. Purpose of the <exclude> tag here is completely different. Let me explain below.
You added the following "dependency"
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
The following code is added by the system without your knowledge.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
The purpose of using "lombak" is to generate the boilerplate code instead of we writing the getters, setters, etc. As you have added the "lombak" dependency, it allows @Getter, @Setter kind of annotations and generates the required code (getters, setters, constructors, etc) and it's work is done. This code generation takes place at the compilation time. Remember, there are different stages like clean, compile, test, package, install in the life cycle. The "lombak" is required at 'compile' stage only. There is no need of "lombak" in the later stages (Eg: package). So, Maven plans to exclude "lombak" for the later stages. The code generated without your knowledge (inside the <plugin> block) belongs to that exclusion.
In this case, the Lombok library (org.projectlombok:lombok) is being excluded from the final packaged artifact. This means that while Lombok is still available as a dependency during compilation (allowing you to use its annotations), it won't be bundled into the final executable JAR/WAR file. Including Lombok in the final JAR/WAR file would be unnecessary and could potentially cause conflicts or increase the size of the final artifact. Therefore, it is common to exclude Lombok from the final package.
The Usage1 that I have mentioned above has a different purpose. Suppose you have added to dependencies and both of them transitively depend on "lombak". In that case, it is not meaningful to import it two times and there may be some version related conflicts also. To avoid that, we can exclude "lombak" from any one of the dependencies.
Look at the following code
<dependency>
<groupId>com.example</groupId>
<artifactId>dependecy-a</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>dependency-b</artifactId
<exclusions>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</exclusions>
</dependency>
In the above code, we are depending on two dependencies dependency-a and dependency-b and assume both dependencies pull "lombak" transitively. Because of the code above, dependency-a pulls "lombak" transitively and adds to classpath but dependency-b does not pull "lombak". This is because, we mentioned to <exclude> the "lombak".
Question2:
If it is the case, should I use this approach (adding <excludes> block for the related library) when I use a different version for transitive dependencies e.g. snakeyaml ? Or should I just add the properties as shown below and override the transitive dependency version?
Answer2:
Unrelated question (when we understand the Usage1 and Usage2).