有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何制作一个简单的gradle构建脚本来编译java程序?

我正在尝试学习如何使用gradle使编译和打包java程序变得更容易。我已经有java编程的经验,通常我只是使用eclipse来管理它,或者,我只是手动编译我的程序(在终端中使用javac)。然而,我已经到了一个地步,我想使用似乎最容易使用的库&;与格雷德尔保持联系

为了进一步了解gradle是如何工作的,我访问了gradle网站,在那里他们提供了编写java应用程序时使用的简单gradle设置教程(this就是我找到的)。然而,本教程并没有真正解释这其中的任何一个应该如何工作,它似乎假设您在项目的布局中遵循了一些特定的系统。它还包括一些测试程序或在构建程序时测试程序的东西。除此之外,它从未真正解释过运行gradle构建函数是如何工作的,也没有真正解释过在构建程序时,文件在哪里(以及什么)保存了它所做的操作的说明

因此,从本质上讲,我想问的是,是否有人可以解释一下,如何创建一个简单的gradle环境,该环境只需编译一组.java文件,然后将它们放在一个可执行的jar中,或者将它们作为.class文件放在一个单独的bin文件夹中。如果您解释了每个部分都在做什么,以及我如何进行更改以添加更多内容(如基本依赖项,可能会在.jar周围添加.exe包装,等等),这也会很有帮助


共 (1) 个答案

  1. # 1 楼答案

    让我们从一个简单的问题开始:构建Java项目需要哪些基本步骤?好的,只要您的项目没有使用一些奇特的预处理或代码生成,第一步可能是将.java文件编译成.class文件。然后,这些.class文件(以及资源,如果提供的话)可以打包到.jar文件中。现在对您来说可能不太明显,但一般来说,您还应该在构建项目时运行(单元)测试。根据您的项目,可能还有更多可能的步骤(例如出版、文档编制、质量控制)

    在Gradle中,这些步骤称为任务。任务基本上可以做任何有助于您构建软件的事情。这通常意味着任务获取一些输入文件并将其转换为一些输出文件。例如,编译任务.java文件转换为.class文件。另一个任务可以将.class文件转换为.jar文件(我们将此任务称为jar任务)。由于需要创建.class文件以将它们放入.jar文件中,jar任务取决于编译任务。您可以使用Gradle来表示这种关系,因此每次运行jar任务时,Gradle都会确保编译任务已经提前运行。任务不需要做什么,它们可能只是用来表示这种关系(这样的任务称为生命周期任务)。您可以创建特定任务类型的任务来重用功能,例如,两个不同的任务可用于编译生产代码和测试代码,但它们都在内部使用编译器,并且只对不同的输入文件集进行操作

    您可以手动创建任务,我明确建议您创建一些任务,以了解它们之间的关系及其执行方式,但通常不需要在构建脚本中创建任务,因为所有必要的任务都是由插件创建的。Gradle插件非常强大,因为它们基本上可以完成您在构建脚本中可以手动完成的所有事情,以及there is a plugin for almost everything您可能希望在构建过程中完成的所有事情

    [...] I am asking if someone can explain the steps to take to make a simple gradle environment that simply compiles a set of .java files [...]

    使用Gradle编译Java项目的最简单方法是创建一个包含以下内容的文件build.gradle

    plugins {
        id 'java'
    }
    

    就这样!Gradle已经准备好构建您的项目(只需运行gradle build)。这怎么可能?Java插件创建了编译、测试和打包项目所需的所有任务,并将它们配置为遵循常见约定。看看documentation of the Java plugin,它甚至包括一个显示所有任务及其依赖关系的漂亮图像。如图所示,build任务依赖于所有其他任务。此任务在调用gradle build时执行。您还可以调用gradle jargradle assemble,Gradle将只运行构建.jar文件所需的任务

    [...] it seemed to assume that you were following some specific system for the layout of your project.

    是的,Gradle遵循一种称为“约定优于配置”的方法。这意味着,对于所有需要手动配置的内容,都有一个(某种程度上通用或有用的)约定

    此方法的一个简单示例是预期源文件和资源文件的位置。如您所见,在上面的构建脚本中未配置此位置。但是,有一个约定(由Maven建立).java源文件应该进入生产代码的src/main/java和测试代码的src/test/java。当然,这些路径可能会改变,但在大多数项目中,您只需遵守约定即可

    It would also be helpful if you explained what each part was doing and how I can make changes to add more stuff (like basic dependencies [...])

    让我们简单地看一下教程中的构建文件:

    plugins {
        id 'application' 
    }
    
    repositories {
        jcenter() 
    }
    
    dependencies {
        testImplementation 'junit:junit:4.13' 
        implementation 'com.google.guava:guava:29.0-jre' 
    }
    
    application {
        mainClass = 'demo.App' 
    }
    

    第一个块类似于上面的示例,但不是使用标识符为java的插件,而是应用标识符为application的插件。然而,这不会有太大的改变,因为应用程序插件在内部也应用了Java插件

    现在让我们看一看。在块repositoriesdependencies处。dependencies块可用于注册依赖项。您可以在本地.jar文件、其他Gradle项目(在多项目构建中)或外部模块上添加依赖项。单词external指的是远程存储库,这些存储库提供了可在项目中使用的库。dependencies块内的每一行都通过定义依赖范围和模块标识符来表示特定的依赖关系,模块标识符由组标识符、工件标识符和版本(使用:作为分隔符)组成。依赖范围(在Gradle中也称为配置)基本上定义了在何处以及如何使用依赖关系。例如,第一个依赖项只能在测试代码中使用(由于testImplementation范围)。现在Gradle知道构建项目所需的库,但不知道从哪里获得该库。这里repositories块起到了解救作用,因为它可以用来定义Gradle应该在哪里查找外部模块依赖项。大多数情况下,您将主要使用^{}^{}^{},但是也可以添加可在自定义URL下访问的存储库

    最后一部分应用了一个必要的配置,因为无法应用任何有用的约定。Gradle根本不知道应该将项目中的哪个类用作应用程序的主类,因此必须手动定义它

    现在,多亏了应用程序插件,您不仅可以使用gradle build构建项目,还可以使用gradle run从Gradle运行应用程序,因为任务run是在Java插件创建的任务之上创建的任务之一