18.依赖管理
Play的依赖管理系统允许你通过一个单独的dependencies.yml 文件来描述你的应用程序所采用的扩展依赖。
Play应用程序可以有三种类型的依赖:
一旦在conf/dependencies.yml文件里描述了应用程序的依赖,Play将会进行检索、下载并安装所有需要的依赖。
依赖格式
在dependencies.yml文件里用开发模拟的组织名称+所依赖的模块名称和对应的版本号就可以描述一个依赖关系,如:
organisation -> name revision
因此,1.0版本的PlayPDF module应该描述为:
play -> pdf 1.0
有些时候组织名称和依赖名称完全一致,比如commons-lang:
commons-lang -> commons-lang 2.5
在这种情况下,你可以省略组织名称:
commons-lang 2.5
动态版本
修订本可以是已经修订好的(应用于play1.2版本)或是动态的。一个动态的修订本的表示需要指定范围,比如:
dependencies.yml
当创建一个新play应用程序时,系统会自动在conf目录下创建一个dependencies.yml描述文件,其内容如下:
# Application dependencies
require:
- play 1.2
require节用于列出所有的依赖。在这里,新创建的play只依赖Play version 1.2,如果应用程序需要依赖GoogleGuava,那么应该修改为:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07
‘play dependencies’命令
为了让play检索、下载并安装上面描述的新依赖,请运行play dependencies:
$ play dependencies
~ _ _
~ _ __ | | __ __ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.2, http://www.playframework.org
~ framework ID is gbo
~
~ Resolving dependencies using~/Documents/coco/conf/dependencies.yml,
~
~ com.google.guava->guavar07 (from mavenCentral)
~ com.google.code.findbugs->jsr3051.3.7 (from mavenCentral)
~
~ Downloading required dependencies,
~
~ downloadedhttp://repo1.maven.org/maven2/com/google/guava/guava/r07/guava-r07.jar
~ downloadedhttp://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/1.3.7/jsr305-1.3.7.jar
~
~ Installing resolved dependencies,
~
~ lib/guava-r07.jar
~ lib/jsr305-1.3.7.jar
~
~ Done!
~
这时,play会从Maven仓库里为GoogleGuava下载两个jar文件(guava-r07.jar, jsr305-1.3.7.jar) ,并将它们安装到应用程序的lib目录下。
为什么只声明了一个依赖,但play却下载了两个jars文件?这是因为Google Guava还有一个透明依赖。事实上jsr305-1.3.7.jar我们并不需要,我们可以排除它。
透明依赖
默认情况下,任何透明依赖都会被play自动恢复和找回。如果需要,可以使用以下方式排除它们:
1. 在描述时使用particular:false设置来实现:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07:
transitive:false
2. 对整个项目禁用透明依赖:
# Application dependencies
transitiveDependencies: false
require:
- play 1.2
-com.google.guava -> guava r07
3.或排除特定依赖:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07:
exclude:
-com.google.code.findbugs -> *
保持lib/和modules/目录同步
现在如果再次运行play dependencies命令时,jsr305-1.3.7.jar依赖将被忽略:
$ play deps
~ _ _
~ _ __ | | __ __ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.2, http://www.playframework.org
~ framework ID is gbo
~
~ Resolving dependencies using~/Documents/coco/conf/dependencies.yml,
~
~ com.google.guava->guavar07 (from mavenCentral)
~
~ Installing resolved dependencies,
~
~ lib/guava-r07.jar
~
~ ********************************************************************
~ WARNING: Your lib/ and modules/ directories and notsynced with
~ current dependencies (use --sync to automaticallydelete them)
~
~ Unknown:~/Documents/coco/lib/jsr305-1.3.7.jar
~********************************************************************
~
~ Done!
~
然而之前下载的jsr305-1.3.7.jar仍旧在lib/目录里。
play的依赖管理系统负责保持lib/和modules/目录同步,这里可以使用--sync作为play dependencies命令的参数:
play deps --sync
如果再次运行play deps命令,不想要的jar文件将会被删除。
当部署应用程序到生产环境时,可以通过删除模块源代码和模块文档来减少模块的大小,方法是使用--forProd参数运行如下命令:
play dependencies --forProd
这时,将删除每个模块下的documentation/, src/, tmp/, *sample*/ 和*test*/等目录。
冲突判定Conflict resolution
当两个组件需要不同修订版本的同一个依赖时,冲突管理只选择一个作为最终依赖。默认情况下是使用最新版本,放弃其他版本。
但这里有一个例外情况:当play框架自己的核心依赖发生冲突时,在$PLAY/framework/lib目录下的可用版本具有最高优先级。比如,Play依赖于commons-lang 2.5,如果你的应用程序需要commons-lang 3.0时:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07:
transitive:false
- commons-lang3.0
运行play dependencies命令将不会采用commons-lang 3.0,虽然它是最新的:
play dependencies
~ _ _
~ _ __ | | __ __ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.2, http://www.playframework.org
~ framework ID is gbo
~
~ Resolving dependencies using~/Documents/coco/conf/dependencies.yml,
~
~ com.google.guava->guavar07 (from mavenCentral)
~
~ Some dependencies have been evicted驱逐,
~
~ commons-lang3.0 is overriden by commons-lang 2.5
~
~ Installing resolved dependencies,
~
~ lib/guava-r07.jar
~
~ Done!
~
同样要注意,在$PLAY/framework/lib下可用的依赖将不会安装到你的应用程序的lib目录下。
有时你可能需要强制指定一个依赖的版本,要么是为了覆盖核心依赖,或是为了选择最新发布的修订版本。
这时就可以在某个依赖上指定force选项:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07:
transitive:false
- commons-lang3.0:
force: true
增加要的仓库
默认情况下,play将搜索central Mavenrepository下的所有jar依赖,同时搜索central Play modules repository下的所有Play模块。
在配置文件的repositories节里,你可以指定新的定制仓库:
# Application dependencies
require:
- play 1.2
-com.google.guava -> guava r07:
transitive:false
- commons-lang3.0:
force: true
- com.zenexity-> sso 1.0
# My custom repositories
repositories:
- zenexity:
type: http
artifact: "http://www.zenexity.com/repo/[module]-[revision].[ext]"
contains:
-com.zenexity -> *
使用这个配置后,所有com.zenexity organisation 下的依赖都会被检索,并且从远程http服务器进行下载。
Maven仓库
使用iBiblio(公共库和数字档案)类型,也可以增加maven2-compatible兼容仓库,比如:
# Application dependencies
require:
- play
- play ->scala 0.8
- org.jbpm-> jbpm-persistence-jpa 5.0.0:
exclude:
-javassist -> javassist *
-org.hibernate -> hibernate-annotations *
-javax.persistence -> persistence-api *
repositories:
- jboss:
type: iBiblio
root:"http://repository.jboss.org/nexus/content/groups/public-jboss/"
contains:
-org.jbpm -> *
-org.drools -> *
本地仓库
最后,最重要的是你可能想要定义一个引用本地模块的仓库。就和在application.conf配置文件中配置模块一样(play1.2开始不再赞成使用),依赖可以很好工作。
首先创建以下目录结构:
myplayapp/
myfirstmodule/
mysecondmodule/
然后如下设置myplayapp/conf/depencencies.yml就可以实现了:
# Application dependencies
require:
- play
- myfirstmodule-> myfirstmodule
-mysecondmodule -> mysecondmodule
repositories:
- My modules:
type: local
artifact: ${application.path}/../[module]
contains:
-myfirstmodule
-mysecondmodule
注意:不要忘记了运行playdependencies myplayapp命令。
定制ivy设置(Apache ivy:项目依赖管理工具)
Play在hood下使用Ivy来管理项目依赖。如果你需要指定一个特定配置,比如调协一个代理proxy用于验证内部maven网络仓库,那么你可以修改ivysettings.xml文件,这个文件位于play主目录的.ivy2目录。
示例1,让ivy忽略checksums:
示例2,使用基本验证:
username="user" passwd="reallygreatpassword"/> 示例3,重用本地maven仓库,并进行仓库管理: value="${user.home}/.m2/repository/[organisation]/[module]/[revision]/[module]-[revision]" override="false" /> cache="nocache"> root="http://your.repomanager.intra/path/to/repo"cache="default"/> 详见 Ivy settings documentation。 清除Ivy缓存 Ivy缓存可能会损坏,特别是在conf/dependencies.yml文件里的repositories节使用http类型时很容易损坏。如果发生这样的事,并且依赖解决方案不能正常工作时,可以使用—clearcache选项清除ivy缓存。 $ play dependencies --clearcache 这个命令等效于rm -r ~/.ivy2/cache。