在Maven1中,需要把依赖所需要的包每个列出。这对于使用类似如Hibernate的用户来说所操的心太多了,而且也不方便。在Maven2中实现了传递依赖,如此对于Hibernate所依赖的包,Maven2会自动下载,开发人员只需关心Hibernate即可。所以可以看出列出所需要的每个jar是在maven1中的功能,Maven2认为自动下载是一种改进。
这样就产生了一个问题:Maven2虽然把编译时需要的jar都下载了,但并不是所有编译需要的jar在打成war包后运行时也需要。所以也就发现有许多的jar是不需要的,以至war包比较大。我们可以通过以下方式改善:
策略一:
对于容器提供的(如:servlet-api-2.3等)和测试需要时的(如:junit-3.81等),可以直接在pom.xml中去掉。
maven的dependency中有一个tag是<scope>option</scope>,其option有以下几个值:
compile, 缺省值,适用于所有阶段,会随着项目一起发布。
provided,类似compile,期望JDK、容器或使用者会提供这个依赖。如servlet-api-2.3.jar。
runtime, 在运行时使用,如JDBC驱动,适用运行和测试阶段。 如plexus-utils-1.1.jar
test 只在测试时使用,用于编译和运行测试代码。不会随项目发布。如Junit-3.8.1.jar
system, 类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。
如:
<dependency>
<groupId>servletapi</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
策略二:
对于第三方jar包,传递依赖到war包的,但发布时并不需要的。
如:我们项目中使用了webwork-2.2.3.jar。可以我们在打包后发现在war下的lib中多了spring-web-1.2.jar,可是我们项目并不需要这个jar啊。
第一种办法:借用<scope>provided</scope>
虽然provided的本意是指jdk或者容器提供的,只是编译中使用,但不会打到war中,但我们也可借用。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
第二种办法: 使用exclusions; (效果与第一种相同)
<dependency>
<groupId>opensymphony</groupId>
<artifactId>webwork</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
策略三:
对于我们公司内部开发的jar包,我们都加上<optional>true</optional>,这样可以使引用这些jar的项目不会产生传递依赖。
如:项目mycom-csa中使用了mycom-cas-client-1.0.3.jar,然而mycom-cas-client-1.0.3.jar 又使用了mycom-common-security-1.0.3.jar。所以我们在对mycom-csa打包时会把mycom-common-security-1.0.3.jar打进package中。我们当然可以参考“策略二”,但最好的方法是:可以通知开发mycom-cas-client-1.0.3.jar的同事在mycom-cas-client-1.0.3.jar的pom.xml中对dependency修改为:
<dependency>
<groupId>com.mycom</groupId>
<artifactId>mycom-common-security</artifactId>
<version>1.0.3-SNAPSHOT</version>
<optional>true</optional>
</dependency>
添加<optional>true</optional> ,这样我们再打包时mycom-csa中就不会出现mycom-common-security-1.0.3.jar了。