gradle支持多项目构建。本章将从零开始讲多项目构建。
1、多项目结构
~/Desktop/multiproject$ gradle projects
> Task :projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'multiproject'
+--- Project ':api'
+--- Project ':services'
| +--- Project ':services:shared'
| \--- Project ':services:webservice'
\--- Project ':shared'
- 项目api编译出一个Jar文件供项目webservice使用;
- 项目shared编译出一个Jar文件存放项目api和services/webservice、项目services/shared/的共用代码;
- 项目webservice是一个返回XML文件的webapp。
2、根目录的settings.gradle
构建一个多项目,需要在根目录下创建一个settings.gradle文件,并指定哪些项目需要构建。 如:
include "shared","api","services:webservice","services:shared"
3、根目录的build.gradle
// 配置所有子项目的公共部分
subprojects {
// 使用Java插件
apply plugin: 'java'
// 使用eclipse-wtp插件
apply plugin: 'eclipse-wtp'
// 外部依赖的仓库,到时gradle在本地找不到就可以到仓库找依赖
repositories {
mavenCentral()
}
// 外部依赖
dependencies {
testCompile 'junit:junit:4.12'
}
// 指定项目版本号
version = '1.0'
// 指定JDK版本号
sourceCompatibility = '1.8'
jar {
manifest.attributes provider: 'gradle'
}
}
allprojects {
tasks.create('hello') {
doLast {
task ->
print "project name is $task.project.name \n"
}
}
}
- subprojects{}:配置这个项目的子项目。使用多模块项目时,不同模块之间有相同的配置,导致重复配置,可以将相同的部分抽取出来,使用配置注入的技术完成子项目的配置。根项目就像一个容器, subprojects 方法遍历这个容器的所有元素并且注入指定的配置。allprojects是对所有project的配置,包括Root Project。而subprojects是对所有Child Project的配置
- buildscript{}里是gradle脚本执行所需依赖,分别是对应的maven库和插件。
- allprojects里是项目本身需要的依赖,比如代码中某个类是打包到maven私有库中的,那么在allprojects->repositories中需要配置maven私有库,而不是buildscript中,不然找不到
4、Gradle Java插件的约定
参考《使用gradle构建Java项目》 Gradle Java插件有以下约定:
- 存放项目源码:src/main/java
- 存放测试源码:src/test/java
- 存放资源文件:src/main/resources
- 在src/test/resources目录下的任何文件都会被添加到classpath中用于运行测试
- 所有的输出文件都被创建在build目录里,其中JAR文件在build/libs目录里
3、根据约定创建目录
/*api 项目*/
~/Desktop/multiproject$ mkdir api
~/Desktop/multiproject$ mkdir -p api/src/main/java
~/Desktop/multiproject$ mkdir -p api/src/main/resources
~/Desktop/multiproject$ mkdir -p api/src/test/java
~/Desktop/multiproject$ mkdir -p api/src/test/resources
/*api建两个包*/
/*com.wong.api*/
~/Desktop/multiproject$ mkdir -p api/src/main/java/com/wong/api
/*com.wong.api.impl*/
~/Desktop/multiproject$ mkdir -p api/src/main/java/com/wong/api/impl
/*shared项目*/
~/Desktop/multiproject$ mkdir shared
~/Desktop/multiproject$ mkdir -p shared/src/main/java
~/Desktop/multiproject$ mkdir -p shared/src/main/resources
~/Desktop/multiproject$ mkdir -p shared/src/test/java
~/Desktop/multiproject$ mkdir -p shared/src/test/resources
/*创建包*/
/*com.wong.shared*/
~/Desktop/multiproject$ mkdir -p shared/src/main/java/com/wong/shared
/*com.wong.shared*/
~/Desktop/multiproject$ mkdir -p shared/src/test/java/com/wong/shared
/*resources*/
~/Desktop/multiproject$ mkdir -p shared/src/main/resources/com/wong/shared
~/Desktop/multiproject$ mkdir -p shared/src/test/resources/com/wong/shared
/*services/shared项目*/
~/Desktop/multiproject$ mkdir -p services/shared
~/Desktop/multiproject$ mkdir -p services/shared/src/main/java
~/Desktop/multiproject$ mkdir -p services/shared/src/main/resources
~/Desktop/multiproject$ mkdir -p services/shared/src/test/java
~/Desktop/multiproject$ mkdir -p services/shared/src/test/resources
/*创建包com.wong.services.shared*/
~/Desktop/multiproject$ mkdir -p services/shared/src/main/java/com/wong/services/shared
/*services/webservice项目*/
~/Desktop/multiproject$ mkdir -p services/webservice
~/Desktop/multiproject$ mkdir -p services/webservice/src/main/java
~/Desktop/multiproject$ mkdir -p services/webservice/src/main/resources
~/Desktop/multiproject$ mkdir -p services/webservice/src/test/java
~/Desktop/multiproject$ mkdir -p services/webservice/src/test/resources
/*创建两个包*/
/*com.wong.webservice*/
~/Desktop/multiproject$ mkdir -p services/webservice/src/main/java/com/wong/webservice
/*com.wong.webservice*/
~/Desktop/multiproject$ mkdir -p services/webservice/src/test/java/com/wong/webservice
4、向各个目录加入源码文件
(一)项目api
- 添加PersonList.java
~/Desktop/multiproject$ touch api/src/main/java/com/wong/api/PersonList.java
~/Desktop/multiproject$ vim api/src/main/java/com/wong/api/PersonList.java
package com.wong.api;
import java.util.ArrayList;
import com.wong.shared.Person;
import com.wong.api.impl.Impl;
public class PersonList{
private ArrayList<Person> persons = new ArrayList<Person>();
public void doWithImpl(){
try{
Class.forName("org.apache.commons.io.FileUtils");
}catch(ClassNotFoundException e){
throw new RuntimeException(e);
}
new Impl().implMethod();
}
}
- Impl.java
package com.wong.api.impl;
public class Impl{
public void implMethod(){
double a = 4.0 * 4;
}
}
- 添加构建脚本build.gradle
~/Desktop/multiproject$ touch api/build.gradle
~/Desktop/multiproject$ vim build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'commons-math:commons-math:1.1'
}
}
configurations {
spi
}
dependencies {
compile project(':shared')
compile module("commons-lang:commons-lang:2.4") {
dependency("commons-io:commons-io:1.2")
}
}
// Just a smoke test that using this option does not lead to any exception
compileJava.options.compilerArgs = ['-Xlint:unchecked']
task spiJar(type: Jar) {
appendix = 'spi'
from sourceSets.main.output
include 'com/wong/api/'
}
artifacts {
spi spiJar
}
task dist(type: Zip) {
dependsOn spiJar
from 'src/dist'
into('libs') {
from spiJar.archivePath
from configurations.runtime
}
}
artifacts {
archives dist
}
// We want to test if commons-math was properly added to the build script classpath
org.apache.commons.math.fraction.Fraction lhs = new org.apache.commons.math.fraction.Fraction(1, 3);
org.gradle.buildsrc.BuildSrcClass bsc = new org.gradle.buildsrc.BuildSrcClass()
task checkProjectDependency(dependsOn: project(':shared').jar) {
doLast {
File cachedSharedJarDir = new File(gradle.gradleUserHomeDir, "cache/multiproject/shared/jars")
copy {
from project(':shared').jar.archivePath
into cachedSharedJarDir
}
File sharedJar = configurations.compile.files.find { File file -> file.name.startsWith('shared') }
assert sharedJar.absolutePath == project(':shared').jar.archivePath.absolutePath
}
}
(二)项目shared
- 添加资源文件main.properties
~/Desktop/multiproject$ touch shared/src/main/resources/com/wong/shared/main.properties
~/Desktop/multiproject$ vim shared/src/main/resources/com/wong/shared/main.properties
并加入如下内容:
main=mainValue
- 添加Person.java
~/Desktop/multiproject$ touch shared/src/main/java/com/wong/shared/Person.java
~/Desktop/multiproject$ vim shared/src/main/java/com/wong/shared/Person.java
package com.wong.shared;
import java.util.Properties;
import java.io.IOException;
public class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String readProperty() throws IOException{
Properties properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream("com/wong/shared/main.properties"));
return properties.getProperty("main");
}
}
(三)项目services/shared
- 添加TestPerson.java
~/Desktop/multiproject$ touch services/shared/src/main/java/com/wong/services/shared/TestPerson.java
~/Desktop/multiproject$ vim services/shared/src/main/java/com/wong/services/shared/TestPerson.java
package com.wong.services.shared;
import com.wong.shared.Person;
public class TestPerson{
private String name;
public void method(){
new Person("Tom");
}
}
因为上面要用到项目shared里的Person类,所以我们要为项目services/shared,添加依赖,因此在services/shared根目录下创建build.gradle,并添加如下内容:
~/Desktop/multiproject$ touch services/shared/build.gradle
~/Desktop/multiproject$ vim services/shared/build.gradle
dependencies{
implementation project(':shared')
}
(四)项目services/webservice
- 添加TestMan.java
~/Desktop/multiproject$ touch services/webservice/src/main/java/com/wong/webservice/TestMan.java
~/Desktop/multiproject$ vim services/webservice/src/main/java/com/wong/webservice/TestMan.java
package com.wong.webservice;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.collections.list.GrowthList;
import com.wong.shared.Person;
import com.wong.api.PersonList;
public class TestMan{
private String name;
public void method(){
FilenameUtils.separatorsToUnix("my/unix/filename");
ToStringBuilder.reflectionToString(new Person("name"));
new GrowthList();
new PersonList().doWithImpl();
}
}
- 添加测试类TestMe
~/Desktop/multiproject$ touch services/webservice/src/test/java/com/wong/webservice/TestMe.java
~/Desktop/multiproject$ vim services/webservice/src/test/java/com/wong/webservice/TestMe.java
package com.wong.webservice;
import junit.framework.TestCase;
public class TestMe extends TestCase{
public void testClassPath(){
new TestPerson().method();
}
public void testApiCompileClasspath(){
new com.wong.api.PersonList();
}
}
- 为项目services/webservice添加依赖
在services/webservice根目录下创建build.gradle,并添加如下内容:
~/Desktop/multiproject$ touch services/webservice/build.gradle
~/Desktop/multiproject$ vim services/webservice/build.gradle
apply plugin: 'war'
version = '3.0'
dependencies {
implementation project(':shared'),'commons-collections:commons-collectio
ns:3.2.2@jar','commons-io:commons-io:1.2','commons-lang:commons-lang:2.4@jar'
implementation project(':api',configuration:'spi')
runtime project(':api')
}
构建结构
在根目录执行gradle build就可以编译成功了。这样多项目编译就完成了。gradle都是通过相应的插件提供的功能来完成编译的。
谢谢阅读。