2019独角兽企业重金招聘Python工程师标准>>>

Introduction

This section discusses the functionality of optional dependencies and dependency exclusions. This will help users to understand what are they, how to use them, how they work and when is the best way to use them. It also explains why exclusions are made as per dependency basis not in a POM level.

Optional Dependencies

Optional dependencies are used when it's not really possible (for whatever reason) to split a project up into sub-modules. The idea is that some of the dependencies are only used for certain features in the project, and will not be needed if that feature isn't used. Ideally, such a feature would be split into a sub-module that depended on the core functionality project...this new subproject would have only non-optional dependencies, since you'd need them all if you decided to use the subproject's functionality.

However, since the project cannot be split up (again, for whatever reason), these dependencies are declared optional. If a user wants to use functionality related to an optional dependency, they will have to redeclare that optional dependency in their own project. This is not the most clear way to handle this situation, but then again both optional dependencies and dependency exclusions are stop-gap solutions.

Why use optional dependencies?

It's not only important to declare optional dependencies in order to save space/memory/etc. It's vital to control the list of actual dependencies a person needs in order to use a project, since these jars may eventually make it into a WAR, EAR, EJB, etc. Inclusion of the wrong jars may violate a license agreement, cause classpath issues, etc.

How do I use the optional tag?

A dependency is declared as optional by simply setting the <optional> tag to true in your dependency declaration. See the sample below:

<project>...<dependencies><!-- declare the dependency to be set as optional --><dependency><groupId>sample.ProjectA</groupId><artifactId>Project-A</artifactId><version>1.0</version><scope>compile</scope><optional>true</optional> <!-- value will be true or false only --></dependency></dependencies>
</project>

How do optional dependencies work?

Project-A -> Project-B

The diagram above says that Project-A depends on Project-B. When A declares B as an optional dependency in its POM, this relationship remains unchanged. Its just like a normal build where Project-B will be added in its classpath.

Project-X -> Project-A

But when another project(Project-X) declares Project-A as a dependency in its POM, the optional dependency takes effect. You'll notice that Project-B is not included in the classpath of Project-X; you will need to declare it directly in your POM in order for B to be included in X's classpath.

Example

Let us say that there is a project named X2 that has similar functions with Hibernate which supports many database drivers/dependencies such as mysql, postgre, oracle etc. All of these dependencies are needed for X2 to build but not for your project, so it is very practical for X2 to declare these dependencies as optional, so that whenever your project declares X2 as a direct dependency in your POM, all the drivers supported by the X2 will not be automatically included to your project's classpath instead you'll have to declare it directly on what driver/dependency of the database you are going to use.

Dependency Exclusions

Since maven 2.x resolves dependencies transitively, it is possible for unwanted dependencies to be included in your project's classpath. Projects that you depend on may not have declared their set of dependencies correctly, for example. In order to address this special situtation, maven 2.x has incorporated the notion of explicit dependency exclusion. Exclusions are set on a specific dependency in your POM, and are targeted at a specific groupId and artifactId. When you build your project, that artifact will not be added to your project's classpath by way of the dependency in which the exclusion was declared.

How to use dependency exclusions

We add the <exclusions> tag under the <dependency> section of the pom.

<project>...<dependencies><dependency><groupId>sample.ProjectA</groupId><artifactId>Project-A</artifactId><version>1.0</version><scope>compile</scope><exclusions><exclusion>  <!-- declare the exclusion here --><groupId>sample.ProjectB</groupId><artifactId>Project-B</artifactId></exclusion></exclusions> </dependency></dependencies>
</project>

How dependency exclusion works and when to use it ( as a last resort! )

Project-A-> Project-B-> Project-D <! -- This dependency should be excluded -->-> Project-E-> Project-F-> Project C

The diagram shows that Project-A depends on both Project-B and C. Project-B depends on Project-D. Project-D depends on both Project-E and F. By default, Project A's classpath will include:

B, C, D, E, F

What if we dont want project D and its dependencies to be added to Project A's classpath because we know some of Project-D's dependencies (maybe Project-E for example) was missing from the repository, and you don't need/want the functionality in Project-B that depends on Project-D anyway. In this case, Project-B's developers could provide a dependency on Project-D that is <optional>true</optional>, like this:

<dependency><groupId>sample.ProjectD</groupId><artifactId>ProjectD</artifactId><version>1.0-SNAPSHOT</version><optional>true</optional>
</dependency>

HOWEVER, they didn't. As a last resort, you still have the option to exclude it on your side, in Project-A, like this:

<project><modelVersion>4.0.0</modelVersion><groupId>sample.ProjectA</groupId><artifactId>Project-A</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging>...<dependencies><dependency><groupId>sample.ProjectB</groupId><artifactId>Project-B</artifactId><version>1.0-SNAPSHOT</version><exclusions><exclusion><groupId>sample.ProjectD</groupId> <!-- Exclude Project-D from Project-B --><artifactId>Project-D</artifactId></exclusion></exclusions></dependency></dependencies>
</project>

If we deploy the Project-A to a repository, and Project-X declares a normal dependency on Project-A, will Project-D be excluded from the classpath still?

Project-X -> Project-A

The answer is Yes. Project-A has declared that it doesn't need Project-D to run, so it won't be brought in as a transitive dependency of Project-A.

Now, consider that Project-X depends on Project-Y, as in the diagram below:

Project-X -> Project-Y-> Project-B-> Project-D...

Project-Y also has a dependency on Project-B, and it does need the features supported by Project-D. Therefore, it will NOT place an exclusion on Project-D in its dependency list. It may also supply an additional repository, from which we can resolve Project-E. In this case, it's important that Project-D is not excluded globally, since it is a legitimate dependency of Project-Y.

As another scenario, what if the dependency we don't want is Project-E instead of Project-D. How will we exclude it? See the diagram below:

Project-A-> Project-B-> Project-D -> Project-E <!-- Exclude this dependency -->-> Project-F-> Project C

Exclusions work on the entire dependency graph below the point where they are declared. If you wanted to exclude Project-E instead of Project-D, you'd simply change the exclusion to point at Project-E, but you wouldn't move the exclusion down to Project-D...you cannot change Project-D's POM. If you could, you would use optional dependencies instead of exclusions, or split Project-D up into multiple subprojects, each with nothing but normal dependencies.

<project><modelVersion>4.0.0</modelVersion><groupId>sample.ProjectA</groupId><artifactId>Project-A</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging>...<dependencies><dependency><groupId>sample.ProjectB</groupId><artifactId>Project-B</artifactId><version>1.0-SNAPSHOT</version><exclusions><exclusion><groupId>sample.ProjectE</groupId> <!-- Exclude Project-E from Project-B --><artifactId>Project-E</artifactId></exclusion></exclusions></dependency></dependencies>
</project>

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.

转载于:https://my.oschina.net/u/2308739/blog/632063

MAVEN POM dependencies and Dependency Exclusions相关推荐

  1. maven可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)

    我们知道,maven的依赖关系是有传递性的.如:A-->B,B-->C.但有时候,项目A可能不是必需依赖C,因此需要在项目A中排除对A的依赖.在maven的依赖管理中,有两种方式可以对依赖 ...

  2. Maven中的可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)

    1.Maven中依赖概述 Maven中的依赖关系是有传递性的.例如:项目B依赖项目C(B -> C),如果有一个项目A依赖项目B(A -> B)的话,那么项目A也会依赖项目C(A -> ...

  3. maven坐标Dependencies和Exclusions详解

    1.概念介绍 Dependencies:是可选依赖(Optional Dependencies) Exclusions:是依赖排除(Dependency Exclusions) 2.Dependenc ...

  4. Maven pom.xml 全配置(一)常用配置

    Maven pom.xml 全配置(一)常用配置 这里贴出一个Maven中出现频率较高的配置参数注释,方便理解项目中Maven的配置具体的作用.如果在此博文中没有找到你想看到的参数,可以移步Maven ...

  5. 你真的了解Maven pom.xml 的配置吗?【详解maven pom】

    Maven POM POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖 ...

  6. Maven(3)---Maven POM

    Maven POM POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖 ...

  7. maven pom.xml解析、命令说明、依赖传递、继承、聚合、properties、build、依赖范围、版本仲裁、profile

    maven是当前Java项目中用到最多的依赖管理工具.最开始的项目比较小引入的依赖包也少所以可以通过手动加载jar包的方式来管理依赖包:但随着项目越来越复杂各种大小框架层出不穷,一个项目的开发往往依赖 ...

  8. Maven pom.xml 全配置(二)不常用配置

    Maven pom.xml 全配置(二)不常用配置 这里贴出Maven pom.xml文件中使用率较少的配置参数,如果此篇文档中没有找到你想要的参数,移步Maven pom.xml 全配置(一)常用配 ...

  9. Maven pom.xml 元素配置说明(一)

    部分来源: Maven中 dependencies 节点和 dependencyManagement 节点的区别 dependencies与dependencyManagement的区别 maven ...

最新文章

  1. 精通python能干嘛-一个程序员怎样才算精通Python?
  2. C++基础之继承类和派生类
  3. i.mx6ul 移植Openwrt
  4. 命令行方法查看和设置环境变量
  5. Android双列表联动和固定头部ScrollView效果实现
  6. 在线安装docker
  7. Oracle用户和模式的区别
  8. IIS搭建站点错误系列
  9. python中类的嵌套_python 中的嵌套类
  10. (转)SQL中WITH的用法
  11. linux源码头文件_您必须在2020年尝试的十大最佳Linux码头
  12. 自己写代码解析工具的注意事项
  13. python制作微信聊天机器人:10行代码让你秒变撩妹达人
  14. 操作系统 实时调度
  15. ECharts数据可视化项目
  16. Windows下搭配AirSim环境
  17. [高效学习]之1学习金字塔
  18. webpack和脚手架
  19. 基于业务描述语言BDL的需求方法论
  20. 谁是滕尚华?两获哥德尔奖,上交大校友,喜欢「躺平式」科研

热门文章

  1. 卷积神经网络只是一种全连接神经网络的特殊情况
  2. java比较三个数的编程_Java小程序输入三个数求最大数
  3. python样本期望值_用 python 做 z 检验,t 检验
  4. verilog case语句_浅谈Design Compiler -- Verilog语言结构到门级的映射
  5. jacobi迭代法matlab_解线性方程组的经典迭代法(1)-理论
  6. 讲解虚拟服务器的书_程序员不得不看的书
  7. 计算机中级职称考试答题卡,内科学中级职称考试答题形式
  8. 目睹鸿蒙开创四大至高位面,吞噬星空 绝非鸿蒙系列,完结前最后的分析【申精】...
  9. 笔记-项目进度管理-精简
  10. CentOS7中卸载Docker