使用Gradle进行项目构建管理
-
安装配置Gradle
-
创建项目
-
使用gradle init命令创建root项目
E:\code\myself\china-unicorn>gradle init Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 1 Select build script DSL: 1: Groovy 2: Kotlin Enter selection (default: Groovy) [1..2] 1 Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] Project name (default: china-unicorn): > Task :init Get more help with your project: Learn more about Gradle by exploring our samples at https://docs.gradle.org/7.5.1/samples BUILD SUCCESSFUL in 4m 2 actionable tasks: 2 executed E:\code\myself\china-unicorn>
-
修改
gradle-wrapper.properties
,配置本地distributionUrl。distributionUrl=file:///E:/gradle/gradle-8.0.2-all.zip
-
在根目录下增加root级别的
build.gradle
文件// 这是根目录build.gradle // 应用于所有的project allprojects { apply plugin: 'java' apply plugin: 'maven-publish' sourceCompatibility = '1.8' group 'org.donny.bigdata' version '1.0.0-SNAPSHOT' /* java编译的时候缺省状态下会因为中文字符而失败 */ [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/public' } } } } // 所有子项目的通用配置 subprojects { //版本定义 ext { log4jVersion = '2.20.0' sparkVersion = '2.3.3' scalaMajorMinorVersion = '2.11' // 打包时使用的预发布路径 preDestinationDirectory = "$rootProject.buildDir\\preDist\\$rootProject.name-$rootProject.version" } // 添加通用依赖 dependencies { testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' } // 仓库配置 repositories { mavenLocal() def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public' all { ArtifactRepository repo -> if (repo instanceof MavenArtifactRepository) { def url = repo.url.toString() if (url.startsWith('https://artifacts.elastic.co/maven') || url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://repo.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/') || url.startsWith('https://repo.maven.apache.org/maven2') ) { project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL." remove repo } } } maven { url REPOSITORY_URL } } }
-
用idea,打开项目
图形化创建子模块server和子模块spark-on-yarn-monitor。
-
子模块可以使用父模块定义的变量,在ext中定义版本和一些子模块需要使用的变量
// 这是根目录build.gradle // 应用于所有的project allprojects { apply plugin: 'java' apply plugin: 'maven-publish' sourceCompatibility = '1.8' group 'org.donny.bigdata' version '1.0.0-SNAPSHOT' /* java编译的时候缺省状态下会因为中文字符而失败 */ [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/public' } } } } // 所有子项目的通用配置 subprojects { //版本定义 ext { log4jVersion = '2.20.0' sparkVersion = '2.3.3' scalaMajorMinorVersion = '2.11' // 打包时使用的预发布路径 preDestinationDirectory = "$rootProject.buildDir\\preDist\\$rootProject.name-$rootProject.version" } // 添加通用依赖 dependencies { testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' } // 仓库配置 repositories { mavenLocal() def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public' all { ArtifactRepository repo -> if (repo instanceof MavenArtifactRepository) { def url = repo.url.toString() if (url.startsWith('https://artifacts.elastic.co/maven') || url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://repo.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/') || url.startsWith('https://repo.maven.apache.org/maven2') ) { project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL." remove repo } } } maven { url REPOSITORY_URL } } }
server子模块配置如下,可以看到子模块可以使用父模块定义的变量
import org.gradle.util.GradleVersion archivesBaseName = "Chineseunicorn" ext.mailVersion = '2.0.1' ext.nettyVersion = '4.1.90.Final' dependencies { // 日志依赖 implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: "${log4jVersion}" implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: "${log4jVersion}" // jakarta邮件依赖 implementation "com.sun.mail:jakarta.mail:${mailVersion}" implementation group: 'jakarta.mail', name: 'jakarta.mail-api', version: "${mailVersion}" // netty implementation group: 'io.netty', name: 'netty-all', version: "${nettyVersion}" } test { useJUnitPlatform() }
-
11
-
-
改写父子模块的jar任务
root模块,依赖子模块的jar关系
jar { dependsOn clean // 依赖子模块spark-on-yarn-monitor的jar任务 dependsOn ':spark-on-yarn-monitor:jar' // 依赖子模块server的jar任务 dependsOn ':server:jar' }
server子模块
- 将运行时依赖的jar打入一个单独的lib文件夹
- 依赖其他子模块的任务
dependsOn ':spark-on-yarn-monitor:jar'
- manifest文件编写
// 重写jar jar { dependsOn ':spark-on-yarn-monitor:jar' dependsOn 'clearPreDist' dependsOn 'copyBin' dependsOn 'copyJar' dependsOn 'copyConf' from sourceSets.main.output dependsOn configurations.runtimeClasspath String someString = '' configurations.runtimeClasspath.each { someString = someString + " lib//" + it.name } manifest { attributes 'Implementation-Title': archivesBaseName attributes 'Implementation-Vendor-Id': 'com.donny' attributes 'Implementation-Version': archiveVersion attributes 'Main-Class': 'com.donny.bigdata.surveillance.ChineseUnicorn' attributes 'Created-By': 'Gradle ' + GradleVersion.current() attributes 'Build-Jdk': JavaVersion.current() attributes 'Class-Path': someString } // 控制jar的输出位置 destinationDirectory = file("${preDestinationDirectory}") // 开启zip64压缩输出 zip64 true } // 打包 task clearPreDist(type: Delete) { delete "${preDestinationDirectory}" } // 将依赖包复制到lib目录 task copyJar(type: Copy) { into "${preDestinationDirectory}" + "\\lib" from configurations.runtimeClasspath } // 将配置文件复制到conf目录 task copyConf(type: Copy) { into "${preDestinationDirectory}" + "\\conf" from "$rootProject.rootDir" + "\\conf" } // 将脚本复制到bin目录 task copyBin(type: Copy) { into "${preDestinationDirectory}" + "\\bin" from "$rootProject.rootDir" + "\\bin" }
spark-on-yarn-monitor子模块
// 改写 jar { // 将所有implementation依赖一起打包到jar,需要对冲突定义规则,我这里采用DuplicatesStrategy.EXCLUDE策略 configurations.implementation.canBeResolved = true duplicatesStrategy = DuplicatesStrategy.EXCLUDE from { configurations.implementation.collect { it.isDirectory() ? it : zipTree(it) } } manifest { attributes 'Main-Class': 'com.donny.bigdata.surveillance.spark.SparkOnYarnMonitor' } // 开启zip64压缩输出 zip64 true // 控制jar的输出位置-父工程的plugins文件夹中 destinationDirectory = file("${preDestinationDirectory}" + "\\plugins") }
-
打包成zip或者tar
root模块的配置增加任务,最终发布包在文件夹distributions下。
task Zip(type: Zip) { dependsOn jar //要压缩的文件夹 from("$buildDir\\preDist\\") } task buildTar(type: Tar) { dependsOn jar compression = Compression.GZIP archiveExtension = "tar.gz" //要压缩的文件夹 from("$buildDir\\preDist\\") }