5

I am trying to follow best practices when defining data in pom.xml, so I started to look into the Spring source code, and I have seen:


<project xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion&gt
  <groupId&gtorg.springframework</groupId&gt
  <artifactId&gtspring-aop</artifactId&gt
  <packaging&gtjar</packaging&gt
  <version&gt3.1.1.RELEASE</version&gt
.....

<dependency>
      <groupId&gtorg.springframework</groupId&gt
      <artifactId&gtspring-beans</artifactId&gt
      <version&gt${project.version}</version&gt
      <scope&gtcompile</scope&gt
</dependency&gt

---

<dependency&gt
      <groupId&gtlog4j</groupId&gt
      <artifactId>log4j</artifactId&gt
      <scope&gttest</scope&gt
</dependency&gt
-----

But, spring-beans also has a dependency on log4j.

Can you please tell me, for the best practice methods, on what extent should you rely on transitive dependencies?

I am asking this because my first thought was not to redeclare the log4j dependency, since spring-beans had already declared it.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Roxana
  • 1,569
  • 3
  • 24
  • 41

2 Answers2

11

Declare dependencies that you explicitly rely on, whether it provides classes you directly import and use or it's something that provides a service you directly use, like Log4J. Transitive dependencies should only supply dependencies that are needed at runtime but that you don't use yourself.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
1

There are two parts for this:

The log4j is declare for "test" scope, and it will not be part of finalized output (jar/war...). So When spring-beans depend on log4j for their test (scope), that does not mean there is a transitive dependency for projects that uses spring-beans at provided or runtime (scopes).

Dependency scope - this allows you to only include dependencies appropriate for the current stage of the build. ... test: This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. (Apache)

The second part that:

When the version of dependency is not specify, then it relies on "other" pom for managing the dependency. So the dependency is transitive and managed by other. "dependency management"

Dependency management - this allows project authors to directly specify the versions of artifacts to be used when they are encountered in transitive dependencies or in dependencies where no version has been specified. (Apache)

Maven Apache transitive dependency

devBinnooh
  • 611
  • 3
  • 12
  • 1
    Hi devBinnoh, regarding "The log4j is declare for "test" scope, and it will not be part of finalized output (jar/war...). So When spring-beans depend on log4j for their test (scope), that does not mean there is a transitive dependency for projects that uses spring-beans at provided or runtime (scopes).": I have checked and everything works correctly if you rely on the fact that the junit dependency is transitive.... Could it be some other explantion for the spring usage? – Roxana Mar 03 '13 at 18:02
  • Yes, You are right. Log4j in this case relies on the transitive dependency. Why?! Here comes the second part, which is transitive dependency through "Dependency management". when you do "not specify" the version number of a dependency, you rely on "others" to specify it, hence, it's functional dependency. The first part of my answer was to point out the scopes of these dependencies, knowing that scopes can be transitive only on their scopes. However, for spring, I think the second part applies. – devBinnooh Mar 04 '13 at 16:19