How to turn off transitive dependencies for maven projects?

In Maven you cannot switch off transitive dependencies for all declared dependencies in a single way, as stated by official documentation

Why exclusions are made on a per-dependency basis, rather than at the POM level

This is mainly done to be sure the dependency graph is predictable, and to keep inheritance effects from excluding a dependency that should not be excluded. If you get to the method of last resort and have to put in an exclusion, you should be absolutely certain which of your dependencies is bringing in that unwanted transitive dependency.


Indeed, since Maven 3.2.1 you can specify wildcards to exclude all transitive dependencies for a specific dependency, but that's still per dependency and not global.

What you actually would like to have something like the following per each and every dependency in each and every pom (!!):

<dependency>
    <groupId>groupId</groupId>
    <artifactId>artifactId</artifactId>
    <version>version</version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Although this is not advisable since it may easily (and negatively) affect maintainability of concerned projects, a possible solution would be to have a common parent POM for all of the concerned projects, so that each pom would declare:

<parent>
    <groupId>com.sample</groupId>
    <artifactId>projects-governance</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

Then, in the concerned parent POM you would have:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample</groupId>
    <artifactId>modules</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <!-- for each and every foreseen dependency of children poms -->
            <dependency>
                <groupId>groupId</groupId>
                <artifactId>artifactId</artifactId>
                <version>version</version>
                <exclusions>
                    <exclusion>
                        <groupId>*</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

Note the dependencyManagement section, here we are saying: to all children POMs, whenever you use the concerned dependencies I declare, for this groupId and this artifacId by default this version and this exclusions will be applied.

The main advantages of this solution is that you centralize this mechanism/management so that at least you don't have to touch each and every POM (except the change concerning the new parent).

However, you would still need to list in the parent POM all the dependencies used by all the projects and apply a wildcard exclusion for all of them.


To get a list of all dependencies per project, you can probably go for a manual approach (open each and every POM!) or run on each project the following:

mvn dependency:list -DexcludeTransitive=true -DoutputFile=dependencies.txt -DappendOutput=true

The Maven Dependency Plugin would then write in the specified dependencies.txt file the declared dependencies (in the format groupId:artifactId:packaging:version:scope) of the concerned project. Note the last parameter, appendOutput, could be helpful to write at the end of the same file in order to keep them centralized for further processing (removing duplicates, moving them to the new parent pom).


To apply wildcards to all declared dependencies, a quick hint is to simply replace (with any text editor or via shell scripting) the following tokens:

    </version>
</dependency>

By the following ones:

    </version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Then save the file. And automatically you would have in a quite safe manner applied wildcard exclusions to all dependencies.

Update by OP: Finally we decided not to do this and instead, solve the original problem by using dependency tree command to generate reports of the newly added/removed dependencies for each project and broadcast it.