使用Gradle编译Java项目
本文带你用Gradle编译一个简单的Java项目。
本文目标
创建一个简单的Java项目,然后用Gradle编译。
你需要
- 15分钟左右
- 文本编辑器或者IDE
- JDK 8+
创建项目
我们首先需要创建项目一个Java项目。为了专注于Gradle的操作,这个Java项目越简单越好。
创建文件夹结构
在你选择的项目文件夹下面,创建子文件夹。
Windows系统的话,在命令行运行命令 :
mkdir src\main\java\hello
*nix系统的话,在运行命令 :
mkdir -p src/main/java/hello
最后文件夹结构如下:
└── src└── main└── java└── hello
在src/main/java/hello文件夹下面,你可以按自己的想法创建任何Java类。为了简单起见,我们只创建两个类:HelloWorld.java和Greeter.java。
package hello;public class HelloWorld {public static void main(String[] args) {Greeter greeter = new Greeter();System.out.println(greeter.sayHello());}
}
package hello;public class Greeter {public String sayHello(){return "Hello world!";}
}
安装Gradle
现在你已经有一个可以编译的项目了,接下来我们开始安装Gradle。
我们可以用管理工具安装Gradle:
- SDKMAN
- Homebrew(使用brew安装gradle)
当然,如果你不想安装额外的工具软件,你可以从https://www.gradle.org/downloads上面直接下载gradle的二进制文件。我们只需要二进制文件,可以直接去找gradle-{version}-bin.zip文件来下载(例如gradle-6.5.1-bin.zip)。
下载下来之后,解压压缩包,然后把里面的bin文件夹添加到你的电脑的 高级系统设置 => 环境变量 => 系统变量 => path 里面。
为了测试Gradle是否安装成功,在你的项目根目录下面,用命令行运行命令:
gradle
如果安装成功,可以看到输出信息如下(版本号可能不同):
> Task :helpWelcome to Gradle 6.5.1.To run a build, run gradle <task> ...To see a list of available tasks, run gradle tasksTo see a list of command-line options, run gradle --helpTo see more detail about a task, run gradle help --task <task>For troubleshooting, visit https://help.gradle.orgDeprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warningsBUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
同时,项目根目录下面多了一个 .gradle 文件夹。
看看Gradle可以做什么
现在Gradle已经安装成功了,看看它可以做什么。在你创建项目编译配置文件 build.gradle 之前,你可以看看Gradle里面有什么任务可以用,运行如下命令:
gradle tasks
你可以看到一个可用任务的列表。假设你还没有添加 build.gradle 文件,你将看到一些非常基本的任务,如下:
> Task :tasks
> Connecting to Daemon
------------------------------------------------------------
Tasks runnable from root project
------------------------------------------------------------Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'learn-gradle'.
components - Displays the components produced by root project 'learn-gradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'learn-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'learn-gradle'.
dependentComponents - Displays the dependent components of components in root project 'learn-gradle'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'learn-gradle'. [incubating]
outgoingVariants - Displays the outgoing variants of root project 'learn-gradle'.
projects - Displays the sub-projects of root project 'learn-gradle'.
properties - Displays the properties of root project 'learn-gradle'.
tasks - Displays the tasks runnable from root project 'learn-gradle'.To see all tasks and more detail, run gradle tasks --allTo see more detail about a task, run gradle help --task <task>Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warningsBUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
尽管这些任务都是可用的,但是在没有项目编译配置文件的情况下,这些任务没有什么意义。随着你向build.gradle里面填充具体的内容,一些任务就会变得有用。
任务列表会随着你添加插件到build.gradle里面而变多,所以你偶尔可以运行tasks命令,看看都有什么任务可用。
说到添加插件,接下来我们添加一个插件,开启基本的Java编译功能。
编译Java代码
开始很简单,在你上面创建的根目录下面新建一个 build.gradle 文件,里面只写一行代码:
apply plugin: 'java'
这简单的一行代码在编译配置里面起很大的作用。重新运行 gradle task ,我们会看到任务列表里面添加的新的任务,包括编译相关的任务,生成JavaDoc的任务和运行测试的任务。
我们将会经常使用 gradle build 任务。这个任务编译,测试和打包字节码文件到一个JAR文件。你可以在命令行里面运行:
gradle build
几秒钟之后,就会显示 “BUILD SUCCESSFUL”,说明这次编译完成了。
为了查看编译的成果,我们看一下新生成的 build 文件夹。在里面我们可以看到多个文件夹,其中值得注意的有三个文件夹:
- classes。项目源代码编译之后生成的.class文件。
- libs。打包好的项目库文件(通常是JAR或者WAR文件)。
classes文件夹里面的.class文件都是通过编译Java源代码生成的。我们可以在里面找到HelloWorld.class和Greeter.class两个文件。
libs文件夹里面包含一个跟项目文件夹的名字一样的JAR文件。下一步,我们就可以看到怎么指定JAR文件的文件名和版本。
声明依赖
我们刚才创建的Hello World项目是完全自包含的,没有依赖额外的类库。但是,大部分的应用,都会使用外部的类库,来处理一些简单的或者复杂的功能。
比如说,我们除了输出"Hello World!",还想打印出当前日期和时间。Java自带的日期和时间工具库可以这个要求,但是你也可以使用一个外部的Joda Time库来实现这个功能。
首先,修改 HelloWorld.java:
package hello;import org.joda.time.LocalTime;public class HelloWorld {public static void main(String[] args) {LocalTime currentTime = new LocalTime();System.out.println("The current local time is:" + currentTime);Greeter greeter = new Greeter();System.out.println(greeter.sayHello());}
}
我们在HelloWorld类里面,使用Joda Time的LocalTime类来获取和打印当前时间。
如果我们现在运行 gradle build 命令,编译过程会失败(提示错误:程序包org.joda.time不存在),因为你还没有声明Joda Time库作为一个编译时的依赖。
为了添加外部依赖,首先我们需要在 build.gradle 里面添加一个第三方的仓库源,如下:
repositories {mavenCentral()
}
repositories使编译系统从Maven Central仓库里面获取依赖库。Gradle严重依靠Maven编译工具已经建立的一些约定和工具,包括以Maven Central作为仓库源的这个选项。
现在我们已经准备好使用第三方库了,继续修改build.gradle:
sourceCompatibility = 1.8
targetCompatibility = 1.8dependencies {compile "joda-time:joda-time:2.2"testCompile "junit:junit:4.12"
}
在dependencies块里面,我们声明一个Joda Time的依赖。我们的要求是(从右往左看):版本为2.2,名字为joda-time的库,在joda-time组里面。
另一个需要注意的是依赖的类型是 **compile ** ,说明编译时必须可用(如果你要打包成WAR文件,会包含到WAR文件的 /WEB-INF/libs 文件夹里面)。其他的需要在意的编译类型是:
- providedCompile。编译项目源码的时候,需要这个依赖。但是运行项目的时候,由运行项目的容器提供该依赖。(例如:Java Servlet API)
- testCompile。编译项目源码和运行项目的测试用例的时候,需要这个依赖。但是打包或者运行项目的执行代码时不需要。
最后,我们指定一下我们的JAR文件的名称:
jar {baseName = 'learn-gradle'version = '0.1.0'
}
jar代码块指定了JAR文件将会怎么命名。本例中,文件名将会变为 learn-gradle-0.1.0.jar。
现在如果我们运行 gradle build 命令,Gradl会从Maven Central库中获取Joda Time依赖库,并且编译会运行成功。
使用Gradle Wrapper编译项目
Gradle Wrapper是开始一个Gradle项目的首选。它包含一个批处理脚本(在Windows中使用)和一个shell脚本(在OS X或者Linux中使用)。这些脚本使你可以不安装Gradle,也能运行一个Gradle项目。你只需要使用下面的命令:
$ gradle wrapper --gradle-version 6.5.1
执行完成之后,我们可以看到增加一些文件。两个脚本文件在根目录下面,而wrapper的jar包和properties文件则被添加到了gradle/wrapper文件下面。如下所示:
└── <project folder>└── gradlew└── gradlew.bat└── gradle└── wrapper└── gradle-wrapper.jar└── gradle-wrapper.properties
Gradle Wrapper已经可以用来编译我们的项目了。我们还可以把项目添加到版本控制系统中,而其他人可以复制你的项目然后编译它。使用Gradle Wrapper和安装了相同版本的Gradle的效果一样。运行wrapper脚本来执行编译任务,就像上面的操作那样:
gradlew build
或者
./gradlew build
控制台输出结果如下:
Downloading https://services.gradle.org/distributions/gradle-6.5.1-bin.zip
.........10%..........20%..........30%..........40%.........50%..........60%..........70%..........80%.........90%..........100%Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warningsBUILD SUCCESSFUL in 1m 21s
2 actionable tasks: 2 up-to-date
在上面我们用–gradle-version设置了Gradle版本为6.5.1,所以Gradle首先下载并缓存了这个版本的Gradle二进制文件(如果已经缓存过,会直接使用缓存)。
Gradle Wrapper的设计目的就是为了直接提交到源码控制系统里面,使任何人都可以直接编译项目,而不用先安装Gradle再编译项目。同时可以配置使用特定版本的Gradle。
现在,你可以看到编译的成果如下:
├─classes
│ └─java
│ └─main
│ └─hello
│ Greeter.class
│ HelloWorld.class
│
├─generated
│ └─sources
│ ├─annotationProcessor
│ │ └─java
│ │ └─main
│ └─headers
│ └─java
│ └─main
├─libs
│ learn-gradle-0.1.0.jar
│
└─tmp├─compileJava│ source-classes-mapping.txt│└─jarMANIFEST.MF
在里面,有我们所期望的class文件Greeter.class和HelloWorld.class,同时还有一个JAR文件。快速浏览一下JAR文件的内容:
$ jar tvf build\libs\learn-gradle-0.1.0.jar0 Sun Jul 12 16:43:56 CST 2020 META-INF/25 Sun Jul 12 14:52:16 CST 2020 META-INF/MANIFEST.MF0 Sun Jul 12 16:43:56 CST 2020 hello/369 Sun Jul 12 16:43:56 CST 2020 hello/Greeter.class987 Sun Jul 12 16:43:56 CST 2020 hello/HelloWorld.class
我们可以看到class文件已经被打包进去了。还有重要的一点,尽管你已经声明了joda-time库的依赖,但是这个库并没有包含到JAR文件里面。而且,这个JAR文件也不能执行。
为了使代码可以执行,我们可以使用gradle’s Gradle的 application 插件。添加如下代码到build.gradle里面:
apply plugin: 'application'mainClassName = 'hello.HelloWorld'
接下来你可以运行程序了!运行命令:
gradlew run
或者
./gradlew run
结果如下:
> Task :run
The current local time is:17:55:34.598
Hello world!Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warningsBUILD SUCCESSFUL in 2s
2 actionable tasks: 1 executed, 1 up-to-date
如果要打包项目里面的依赖包,需要对应的插件。比如说,我们打包成一个WAR文件,我们可以使用Gradle的WAR插件。如果我们使用Spring Boot,并且想要一个可执行的JAR文件的话,spring-boot-gradle-plugin这个插件就很方便满足我们的要求。具体操作就不在这一章中展开了。
整理之后,最终的 build.gradle 如下:
apply plugin: 'java'
apply plugin: 'application'mainClassName = 'hello.HelloWorld'repositories {mavenCentral()
}sourceCompatibility = 1.8
targetCompatibility = 1.8dependencies {compile "joda-time:joda-time:2.2"testCompile "junit:junit:4.12"
}jar {baseName = 'learn-gradle'version = '0.1.0'
}
小结
你已经创建了一个简单但是有效的Gradle编译配置文件,可以正常的编译Java项目了。
源码下载
learn-gradle
参考资料
https://spring.io/guides/gs/gradle/
使用Gradle编译Java项目相关推荐
- 使用 Gradle 编译 Java 项目时报错: Could not find Tools.jar
这是因为 Gradle 找不到 JDK 目录引起的,可以通过设置 Gradle 的全局属性 java.home 来解决. 找到当前用户目录下的 .gradle 目录,并创建 gradle.proper ...
- gradle java ide_使用Gradle构建Java项目
使用Gradle构建Java项目 这个手册将通过一个简单的Java项目向大家介绍如何使用Gradle构建Java项目. 我们将要做什么? 我们将在这篇文档航中创建一个简单的Java项目,然后使用Gra ...
- 使用Gradle构建Java项目
使用Gradle构建Java项目 本指南将引导您使用Gradle构建一个简单的Java项目. 你会建立什么 您将创建一个简单的应用程序,然后使用Gradle进行构建. 你需要什么 约15分钟 最喜欢的 ...
- gradle打包java项目_gradle打包java项目
转载地址:http://www.gfzj.us/series/gradle/2014/12/12/gradle%E5%B0%8F%E7%B3%BB%E5%88%97(4)--gradle%E6%89% ...
- 解决IEDA编译java项目出现 library root ,编译缺少 rt.jar jce.jar
解决IEDA编译java项目出现 library root ,编译缺少 rt.jar jce.jar 问题 编译项目时,提示找不到rt.jar,编译添加后,出现缺少jce.jar,maven依赖项显示 ...
- 【Java】IDEA编译Java项目报错 java: 找不到符号 的解决方法
IDEA编译Java项目报错java: 找不到符号,情况如下所示: 解决方法: 先删除out文件夹,然后选择File → Invalidate Caches → Invalidate and Rest ...
- 使用javac编译Java项目
在缺乏eclipse和idea等IDE的工具的情况下,使用jdk自带的javac命令编译Java项目 当项目只有一个Java文件的时候,可以直接使用 javac 文件名.java 但是如果有多个源文件 ...
- Idea之使用Gradle开发Java项目
IDEA拥有大量的JAVA开发者拥护,相比于开源的eclipse,IDEA拥有更简洁直观的界面,拥有更强大的自动补全功能,号称能"一路敲回车完成编码".如果把IDEA和eclips ...
- 用gradle启动java项目_构建Java项目
#构建Java项目# 上一节我们简要介绍了如何编写一个单机的To Do应用,接下来要打包部署成可执行的应用,我们需要编译源代码,生成的class文件需要打包到JAR文件中.JDK提供了javac 和j ...
- Ant编译Java项目-QuickStart
Ant是专门为Java开发的一款编译工具,很多开源工具都能通过Ant配置文件轻松运行,掌握这个工具对以后编译管理项目很有用处. Ant下载安装 登陆官网http://ant.apache.org/ 下 ...
最新文章
- php-5.6.26源代码 - opcode处理器,“函数调用opcode”处理器,如何调用扩展模块的函数...
- 自己写一个实现ApplicationListener​接口并且把该组件加入到容器中
- 云服务能力评估“国标”出炉,腾讯云TStack首批通过私有云“一级能力”认证
- P4316 绿豆蛙的归宿 期望dp + DAG
- 信息学奥赛一本通(1240:查找最接近的元素)
- git常用命令+git规范(附merge合并及冲突解决)
- 【oracle11g,17】存储结构: 段的类型,数据块(行连接、行迁移,块头),段的管理方式,高水位线...
- linux java缓存失效_转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案...
- linux socket closeconnection,求助:socket的Connection refused
- nefu 984 我是一个粉刷匠
- Apache Solr 4.0今日发布
- HackerRank Twin Arrays 题解
- Latex中的花体格式
- 有关针式打印机和一体机的安装
- 浩辰3D软件中装配零件的操作技巧
- python 报错 'gbk' codec can't encode character '\xb5' in position 7431: illegal multib
- ftp上传工具 绿色,4个好用的绿色 ftp上传工具
- 关于原生table表单在vue中的遍历和合并行
- CP 15 协处理器
- git上传代码和下载代码
热门文章
- python perl 正则_为什么说perl的正则表达式功能比Python强大
- android 圆形相机预览拍照_Android Camera2 Api 实现预览和拍照
- ukf实测信号的预测 matlab,无迹卡尔曼滤波UKF无线传感器网络定位跟踪matlab源码实现.pdf...
- 吉林大学计算机专业张文政,张晋东 - 吉林大学 - 计算机科学与技术学院
- oracle同一天,Oracle统计一个小时内,一天内、一个星期内、一个月内、一年内的数据...
- .net 怎么在控制器action中返回一个试图_ASP.NET Core MVC/WebAPI中另辟蹊径的全局统一异常处理方式...
- 处理机调度算法——先来先服务、高优先权、按时间片轮转调度算法,高响应比调度算法
- webstorm 配置sass 编译
- HTML基础 --- HTML基础
- 51nod1160 压缩算法的矩阵——一道有趣的题