网易首页 > 网易号 > 正文 申请入驻

在gradle中构建java项目

0
分享至

简介

之前的文章我们讲到了gradle的基本使用,使用gradle的最终目的就是为了构建java项目。今天本文将会详细的讲解如何在gradle中构建java项目。

构建java项目的两大插件

安装java项目的目的不同,构建java项目有两大插件,一个是application,表示构建的是java应用程序;一个是java-library,表示构建的是java库,供别的项目使用。

不管是构建应用程序还是java库,我们都可以很方便的使用gradle init来创新一个新的gradle项目:

$ gradle init

Select type of project to generate:
1: basic
2: application
3: library
4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Scala
6: Swift
Enter selection (default: Java) [1..6] 3

Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4]

Project name (default: demo):
Source package (default: demo):

BUILD SUCCESSFUL
2 actionable tasks: 2 executed

application和library的不同之处在于第二步选择的不同。

两者在build.gradle中的不同在于plugins的不同,application的plugin是:

plugins {
id 'application'

而library的plugin是:

plugins {
id 'java-library'

还有一个不同之处是依赖的不同,先看一个application的依赖:

dependencies {
testImplementation 'junit:junit:4.13'

implementation 'com.google.guava:guava:29.0-jre'
}

再看一个library的依赖:

dependencies {
testImplementation 'junit:junit:4.13'

api 'org.apache.commons:commons-math3:3.6.1'

implementation 'com.google.guava:guava:29.0-jre'
}

因为library是需要给第三方应用程序使用的,所以这里多了一个api的使用,api表示是第三方应用程序也需要依赖这个包,而implementation表示的是该包只是在这个项目内部被依赖。

在构建libary的时候,还可以自定义manifest的信息:

tasks.named('jar') {
manifest {
attributes('Implementation-Title': project.name,
'Implementation-Version': project.version)
}
}

上面的例子将会在META-INF/MANIFEST.MF生成:

Manifest-Version: 1.0
Implementation-Title: lib
Implementation-Version: 0.1.0

我们还可以指定编译的java版本号和lib的版本:

java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}

version = '1.2.1'

管理依赖

java的依赖一般都是jar包组成的library。和maven一样,我们在gradle中指定依赖需要指定依赖的名字和版本号,依赖的范围:是运行时依赖还是编译时依赖,还有一个重要的就是在哪里可以找到这个library。

前面两个属性我们可以在dependencies中找到,后面一个我们可以在repositories中找到,看一个例子:

repositories {
mavenCentral()
}

dependencies {
implementation 'org.hibernate:hibernate-core:3.6.7.Final'
}

还可以使用这种形式的maven:

repositories {
maven {
url "http://repo.mycompany.com/maven2"
}
}

或者Ivy:

repositories {
ivy {
url "http://repo.mycompany.com/repo"
}
}

甚至可以使用本地的local dir:

repositories {
flatDir {
dirs 'lib'
}
flatDir {
dirs 'lib1', 'lib2'
}
}

上面定义了一个mavenCentral的仓库,我们可以在这个仓库中去查找hibernate-core这个依赖的jar包。

在dependencies这一块,我们可以定义依赖包的工作范围:

  • compileOnly:表示依赖包只被用来编译代码,并不用在程序的运行。

  • implementation:表示依赖包被用在编译和运行时。

  • runtimeOnly:只在运行时使用。

  • testCompileOnly:仅在test的编译时使用。

  • testImplementation:在test的编译和运行时使用。

  • testRuntimeOnly:在test的运行时使用。

我们还可以添加动态的依赖:

dependencies {
implementation 'org.springframework:spring-web:5.+'
}

使用项目作为依赖:

dependencies {
implementation project(':shared')
}
编译代码

一般情况下你的源代码需要放在src/main/java 目录下,测试代码需要放在src/test/java下面。然后添加compileOnly 或者 implementation依赖,如果需要测试的话,添加testCompileOnly或者testImplementation依赖。

然后就可以运行compileJava和compileTestJava来编译代码了。

当然,如果你有自定义的源文件目录,也可以这样手动指定:

sourceSets {
main {
java {
srcDirs = ['src']
}
}

test {
java {
srcDirs = ['test']
}
}
}

上面的代码中我们给srcDirs重新赋值了。如果我们只是想要在现有的代码路径上再添加一个新的路径,那么可以使用srcDir:

sourceSets {
main {
java {
srcDir 'thirdParty/src/main/java'
}
}
}

除了源代码的路径,我们还可以配置编译的参数,并指定编译的JDK版本号:

compileJava {
options.incremental = true
options.fork = true
options.failOnError = false
options.release = 7
}

注意,gradle必须要在JDK8以上才能运行,但是我们可以指定gradle去使用Java 6 或者 Java 7去编译源代码。

我们还可以指定预览版本的特性:

tasks.withType(JavaCompile) {
options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
jvmArgs += "--enable-preview"
}
管理resource

java除了源代码文件之外,还有一些resource文件,比如配置文件,图片文件,语言文件等等。我们需要将这些配置文件拷贝到特定的目标目录中。

默认情况下,gradle会拷贝src/[sourceSet]/resources 中的文件到目标文件夹中。

我们看一个复杂的拷贝动作:

task copyDocs(type: Copy) {
from 'src/main/doc'
into 'build/target/doc'

//for Ant filter
import org.apache.tools.ant.filters.ReplaceTokens

//for including in the copy task
def dataContent = copySpec {
from 'src/data'
include '*.data'
}

task initConfig(type: Copy) {
from('src/main/config') {
include '**/*.properties'
include '**/*.xml'
filter(ReplaceTokens, tokens: [version: '2.3.1'])
}
from('src/main/config') {
exclude '**/*.properties', '**/*.xml'
}
from('src/main/languages') {
rename 'EN_US_(.*)', '$1'
}
into 'build/target/config'
exclude '**/*.bak'

includeEmptyDirs = false

with dataContent
}

打包和发布

我们可以根据不同的构建类型来打包对应的文件。比如对应java lib来说,我们可以同时上传源代码和java doc文件:

java {
withJavadocJar()
withSourcesJar()

比如说我们还可以打包成一个fat jar包:

plugins {
id 'java'

version = '1.0.0'

repositories {
mavenCentral()
}

dependencies {
implementation 'commons-io:commons-io:2.6'
}

task uberJar(type: Jar) {
archiveClassifier = 'uber'

from sourceSets.main.output

dependsOn configurations.runtimeClasspath
from {
configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
}
}

生成javadoc

gradle的java library插件有一个javadoc task,可以为java项目生成文档。它支持标准的javadoc,也支持其他类型的文档,比如说Asciidoc,我们看一个生成Asciidoc的例子:

configurations {
asciidoclet

dependencies {
asciidoclet 'org.asciidoctor:asciidoclet:1.+'
}

task configureJavadoc {
doLast {
javadoc {
options.doclet = 'org.asciidoctor.Asciidoclet'
options.docletpath = configurations.asciidoclet.files.toList()
}
}
}

javadoc {
dependsOn configureJavadoc
}

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
当伊朗革命卫队走进历史:第二个沙特诞生

当伊朗革命卫队走进历史:第二个沙特诞生

民间胡扯老哥
2026-07-01 07:32:21
7月买菜,少买豆角和茄子,多吃4种应季“黄金菜”,营养又便宜

7月买菜,少买豆角和茄子,多吃4种应季“黄金菜”,营养又便宜

秀厨娘
2026-07-02 16:30:15
研究发现:吃一次皮蛋,就等于给血脂添一次堵,真的假的?

研究发现:吃一次皮蛋,就等于给血脂添一次堵,真的假的?

老马健康讲坛
2026-07-03 09:01:40
终于等到了!国产“抗癌神药”首发,中国患者这次站起来了!

终于等到了!国产“抗癌神药”首发,中国患者这次站起来了!

鬼菜生活
2026-07-03 20:40:47
昨天109元,今天125元!山姆多款牛肉突然涨价,有的甚至涨了50多元,官方:受澳洲牛肉进口配额以及贸易政策影响,澳洲牛肉供应链成本上升

昨天109元,今天125元!山姆多款牛肉突然涨价,有的甚至涨了50多元,官方:受澳洲牛肉进口配额以及贸易政策影响,澳洲牛肉供应链成本上升

极目新闻
2026-07-03 19:55:41
葡萄牙到底有多穷?看看真实的葡萄牙,原来我们一直高估它了

葡萄牙到底有多穷?看看真实的葡萄牙,原来我们一直高估它了

过期少女致幻录
2026-06-26 20:57:25
李嘉诚再次抛售北京房产,价格从10万降至7万

李嘉诚再次抛售北京房产,价格从10万降至7万

专业聊房君
2026-07-01 17:15:46
135公里刀片网背后,泰山是收门票者的山,还是人民的山?

135公里刀片网背后,泰山是收门票者的山,还是人民的山?

非虚构人间
2026-07-01 20:50:30
詹姆斯决定4.0倒计时!5大热门下家各有利弊:下一站究竟是何处?

詹姆斯决定4.0倒计时!5大热门下家各有利弊:下一站究竟是何处?

罗说NBA
2026-07-02 19:42:44
太沉重了!一张殡仪馆的电子显示屏8位逝者,有6人未能活到55岁

太沉重了!一张殡仪馆的电子显示屏8位逝者,有6人未能活到55岁

火山詩话
2026-06-12 08:54:20
日本放任日元疯狂贬值,实际上是给中国做的一个局?

日本放任日元疯狂贬值,实际上是给中国做的一个局?

花小猫的美食日常
2026-07-02 20:59:55
齐达内儿子被梅西打穿后,情绪一度崩溃,淘汰赛重回赛场,比赛50分钟内又被灌进2球

齐达内儿子被梅西打穿后,情绪一度崩溃,淘汰赛重回赛场,比赛50分钟内又被灌进2球

极目新闻
2026-07-03 12:58:07
1年390万美元!李凯尔确定签约猛龙 与前马刺队友小卡再度联手

1年390万美元!李凯尔确定签约猛龙 与前马刺队友小卡再度联手

罗说NBA
2026-07-03 05:56:50
这很科学:89%的人幻想过同时和多人发生性行为,算精神出轨吗?

这很科学:89%的人幻想过同时和多人发生性行为,算精神出轨吗?

宇宙时空
2026-05-26 18:20:10
42岁女上司约我去游泳,到了游泳池,我才发现女上司另有所图

42岁女上司约我去游泳,到了游泳池,我才发现女上司另有所图

千秋文化
2026-06-30 19:19:51
被班主任诬陷作弊,从此我天天考0分,高考结束后却被清北录取

被班主任诬陷作弊,从此我天天考0分,高考结束后却被清北录取

黄家湖的忧伤
2025-04-30 17:09:56
男孩被国防科大录取,读了4年后,国防科大:什么时候录取过你啊

男孩被国防科大录取,读了4年后,国防科大:什么时候录取过你啊

黄家湖的忧伤
2025-08-14 17:18:18
黄仁勋的万亿算盘:宁可把芯片倒进太平洋,也不让美国企业捡漏?

黄仁勋的万亿算盘:宁可把芯片倒进太平洋,也不让美国企业捡漏?

风干迷茫人
2026-07-02 06:33:53
“我都快要生了,他咋还不来娶我?”母亲:放心,200万彩礼不多

“我都快要生了,他咋还不来娶我?”母亲:放心,200万彩礼不多

广西秦胖胖
2026-07-02 16:36:02
A-勒布伦谈击败林诗栋:能够零封取胜,足以证明我当下的竞技水准

A-勒布伦谈击败林诗栋:能够零封取胜,足以证明我当下的竞技水准

懂球帝
2026-07-03 14:44:12
2026-07-03 22:00:49
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

万亿富豪马斯克 舍不得特斯拉员工敞开用AI

头条要闻

中国男篮73比92不敌老对手日本男篮 世预赛出线存变数

头条要闻

中国男篮73比92不敌老对手日本男篮 世预赛出线存变数

体育要闻

C罗穿已故队友若塔球衣谢场 眼中含泪

娱乐要闻

海来阿木孕期出轨指控掀起全网热议

财经要闻

"千亿"众邦银行被接管:系严重信用风险

汽车要闻

方程豹钛9内饰曝光 用上了长联屏设计/下半年上市

态度原创

家居
教育
亲子
健康
本地

家居要闻

传奇筑 日常诗

教育要闻

长沙两同班同学中考数学满分,一起分享考试经验和学习方法

亲子要闻

们要看的小卷毛,她来了哈,伊朗现在节假日中

听说少吃点能抗衰老?专家讲解!

本地新闻

国内足球之旅?这座小城给你高分答案

无障碍浏览 进入关怀版