【系列教程1】Gradle入门系列二:第一个Java项目
这篇教程的主要内容是讲解如何用Gradle编译和打包一个简单的Java项目。
该Java项目只有一个需求:我们的构建脚本必须创建一个可执行的Jar文件,换句话说,我们必须能够使用命令java -jar jarfile.jar 来运行我们的程序。我们来看一下如何满足这个需求。
创建一个Java项目
我们可以使用Java插件来创建一个Java项目,为了做到这点,我们需要把下面这段语句加入到build.gradle文件中:
apply plugin: 'java'
就是这样,现在我们已经创建了一个Java项目。Java插件会在我们的构建中添加一些新的约定(如默认的项目结构),新的任务,和新的属性。
让我们来快速地看一下默认的项目结构。
Java项目结构
默认的项目结构如下:
- src/main/java目录包含了项目的源代码。
- src/main/resources目录包含了项目的资源(如属性文件)。
- src/test/java目录包含了测试类。
- src/test/resources目录包含了测试资源。所有我们构建生成的文件都会在build目录下被创建,这个目录涵盖了以下的子目录,这些子目录我们会在这篇教程中提到,另外还有一些子目录我们会放在以后讲解。
- classes目录包含编译过的.class文件。
- libs目录包含构建生成的jar或war文件。
为构建加入一个主类(main class)
让我们创建一个简单的主类,在这个类中会打印一个“Hello world”然后System.out出来。这个HelloWorld类的源代码如下:
package net.petrikainulainen.gradle; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
HelloWorld类存放在src/main/java/net/petrikainulainen/gradle目录
这很好,然而,我们还需要编译和打包我们的项目,不是吗?我们先看一下这个Java工程中的任务。
Java工程中的任务
Java插件在我们的构建中加入了很多任务,我们这篇教程涉及到的任务如下:
- assemble任务会编译程序中的源代码,并打包生成Jar文件,这个任务不执行单元测试。
- build任务会执行一个完整的项目构建。
- clean任务会删除构建目录。
- compileJava任务会编译程序中的源代码。
我们还可以执行以下命令得到一个可运行任务及其描述的完整列表
gradle tasks
这是一个很好的方式,不需要阅读构建脚本,就能对你的项目进行大致的浏览,如果我们在项目根目录下运行这个命令,我们可以看到以下输出:
> gradle tasks :tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Build tasks ----------- assemble - Assembles the outputs of this project. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. classes - Assembles classes 'main'. clean - Deletes the build directory. jar - Assembles a jar archive containing the main classes. testClasses - Assembles classes 'test'. Build Setup tasks ----------------- init - Initializes a new Gradle build. [incubating] wrapper - Generates Gradle wrapper files. [incubating] Documentation tasks ------------------- javadoc - Generates Javadoc API documentation for the main source code. Help tasks ---------- dependencies - Displays all dependencies declared in root project 'first-java-project'. dependencyInsight - Displays the insight into a specific dependency in root project 'first-java-project'. help - Displays a help message projects - Displays the sub-projects of root project 'first-java-project'. properties - Displays the properties of root project 'first-java-project'. tasks - Displays the tasks runnable from root project 'first-java-project'. Verification tasks ------------------ check - Runs all checks. test - Runs the unit tests. Rules ----- Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration. Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration. Pattern: clean<TaskName>: Cleans the output files of a task. To see all tasks and more detail, run with --all. BUILD SUCCESSFUL Total time: 2.792 secs
我们继续,下面要讲怎样打包我们的项目。
项目打包
我们可以通过使用两个不同的任务来打包项目。
如果我们在命令提示符中执行命令gradle assemble,我们可以看到以下输出:
> gradle assemble :compileJava :processResources :classes :jar :assemble BUILD SUCCESSFUL Total time: 3.163 secs
如果我们在命令提示符中执行命令gradle build,我们可以看到以下输出:
> gradle build :compileJava :processResources :classes :jar :assemble :compileTestJava :processTestResources :testClasses :test :check :build BUILD SUCCESSFUL Total time: 3.01 secs
这些命令的输出表明了它们的区别:
- assemble任务仅仅执行项目打包所必须的任务集。
- build任务执行项目打包所必须的任务集,以及执行自动化测试。这两个命令都会在build/libs目录中创建一个file-java-project.jar文件。默认创建的Jar文件名称是由这个模版决定的:[projectname].jar,此外,项目的默认名称和其所处的目录名称是一致的。因此如果你的项目目录名称是first-java-project,那么创建的Jar文件名称就是first-java-project.jar。
现在,我们尝试使用以下命令运行我们的程序:
java -jar first-java-project.jar
我们可以看到以下输出:
> java -jar first-java.project.jar No main manifest attribute, in first-java-project.jar
问题出在,我们没有在manifest文件中配置Jar文件的主类,让我们继续看看怎样解决这个问题。
配置Jar文件的主类
Java插件在我们的项目中加入了一个Jar任务,每一个Jar对象都一个manifest属性,这个属性是Manifest的一个实例。
我们可以对生成的Jar文件的主类进行配置,使用Manifest接口的attributes()方法。换句话说,我们可以使用一个包含键值对的map结构指定加入到manifest文件的属性集。
我们能够通过设置Main-Class属性的值,指定我们程序的入口点。在我们对build.gradle文件进行必要的改动后,代码如下:
apply plugin: 'java' jar { manifest { attributes 'Main-Class': 'net.petrikainulainen.gradle.HelloWorld' } }
(JavaSE教程提供了关于manifest文件的更多信息。)
在我们执行gradle assemble或gradle build命令生成一个新的jar文件之后,我们可以执行以下命令运行jar文件:
java -jar first-java-project.jar
当我们运行程序时,System.out会打印出以下信息:
> java -jar first-java-project.jar Hello World!
这就是我们今天所有的内容,我们看一下我们学到了什么。
总结
我们已经通过Gradle创建了一个简单的Java项目,这篇教程教会了我们四点:
- 我们了解了可以使用Gradle的Java插件创建一个Java项目。
- 我们知道了Java项目的默认结构和Maven项目的默认结构是一样的。
- 我们知道了构建所生成的所有文件都能在build目录下找到。
- 我们知道了我们可以自定义加入到manifest文件中的属性。
【系列教程1】Gradle入门系列二:第一个Java项目的更多相关文章
- gradle入门(1-6)将Java项目从maven迁移到gradle
gradle项目与maven项目相互转化(转) 转自: http://www.cnblogs.com/yjmyzz/p/gradle-to-maven.html 一.maven项目->gradl ...
- Android Studio系列教程四--Gradle基础
Android Studio系列教程四--Gradle基础 2014 年 12 月 18 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang ...
- [转]Android Studio系列教程六--Gradle多渠道打包
转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...
- Android Studio系列教程六--Gradle多渠道打包
Android Studio系列教程六--Gradle多渠道打包 2015 年 01 月 15 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzh ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- Gradle入门系列(转)
Gradle是一种构建工具,它抛弃了基于XML的构建脚本,取而代之的是采用一种基于Groovy的内部领域特定语言.近期,Gradle获得了极大的关注,这也是我决定去研究Gradle的原因. 这篇文章是 ...
- 【Gradle教程】Gradle 入门
本文为我在学习群内分享时在B站直播分享时的文档,直播间地址 http://live.bilibili.com/22263819 PS:问一下,Linux下有什么好用的会议软件么? 知道的朋友烦请评论告 ...
- 【系列教程1】Gradle入门系列一:简介
Gradle是一种构建工具,它抛弃了基于XML的构建脚本,取而代之的是采用一种基于Groovy的内部领域特定语言.近期,Gradle获得了极大的关注. 这篇文章是Gradle教程的第一篇,我们有两个目 ...
- Angular入门到精通系列教程(4)- 开发环境搭建以及入手项目
1. 本地开发环境搭建 1.1. node.js 1.2. Angular CLI 2. 开发工具 - Visual Studio Code 第一个Anuglar项目 创建第一个anuglar项目 A ...
随机推荐
- 《大话设计模式》c++实现 装饰者模式
一.UML图 介绍 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创 ...
- MVC 中的Model对象
最近实在是太忙,客户丢了一个框架,没有任何说明文档,更没有所谓的技术支持,一直忙于学习,最后好歹还有点头绪,话不多说,MVC的学习是不能拉下的,就当前小白的我,认为MVC中的M并不是想象中的那样简单, ...
- mitmproxy 中间人攻击的小玩笑
import mitmproxy.http from mitmproxy import ctx, http class Joker: def request(self, flow: mitmproxy ...
- 举例说明Unicode 和UTF-8之间的转换
1)写这篇博客的原因 首先我要感谢这篇博客,卡了很久,看完下面这篇博客终于明白Unicode怎么转换成UTF-8了. https://blog.csdn.net/qq_32252957/article ...
- 【转载】selenium与自动化测试成神之路
Python selenium —— selenium与自动化测试成神之路 置顶 2016年09月17日 00:33:04 阅读数:43886 Python selenium —— selenium与 ...
- 了解一下 Linux 上用于的 SSH 图形界面工具
如果你碰巧喜欢好的图形界面工具,你肯定很乐于了解一些 Linux 上优秀的 SSH 图形界面工具.让我们来看看这三个工具,看看它们中的一个(或多个)是否完全符合你的需求. 在你担任 Linux 管理员 ...
- memcache,redis对比
一.问题: 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 ( ...
- ubuntu重启+sublime快捷键
sudo reboot Sublime常用快捷键: 掌握基本的代码编辑器的快捷键,能让你打码更有效率,刚开始可能不大记得住,多敲几次就能熟悉并使用它 精华键 : Ctrl+Shift+P:打开命令面板 ...
- Python数据类型的显式转换
数据类型的显示转换,也称为数据类型的强制类型转换,是通过Python的内建函数来实现的类型转换. 显式转换的多种类型: int(x [,base]) ⇒ 将x转换为一个十进制的整数 long(x [, ...
- Docker学习笔记之搭建Docker运行环境
0x00 概述 既然 Docker 是一款实用软件,我们就不得不先从它的安装说起,只有让 Docker 运行在我们的计算机上,才能更方便我们对 Docker 相关知识和使用方式的学习.得益于与商业性的 ...