简介

之前的文章咱们讲到了gradle的根本应用,应用gradle的最终目标就是为了构建java我的项目。明天本文将会具体的解说如何在gradle中构建java我的项目。

构建java我的项目的两大插件

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

不论是构建应用程序还是java库,咱们都能够很不便的应用gradle init来翻新一个新的gradle我的项目:

$ gradle initSelect type of project to generate:  1: basic  2: application  3: library  4: Gradle pluginEnter selection (default: basic) [1..4] 2Select implementation language:  1: C++  2: Groovy  3: Java  4: Kotlin  5: Scala  6: SwiftEnter selection (default: Java) [1..6] 3Select build script DSL:  1: Groovy  2: KotlinEnter selection (default: Groovy) [1..2] 1Select test framework:  1: JUnit 4  2: TestNG  3: Spock  4: JUnit JupiterEnter selection (default: JUnit 4) [1..4]Project name (default: demo):Source package (default: demo):BUILD SUCCESSFUL2 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.0Implementation-Title: libImplementation-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 filterimport org.apache.tools.ant.filters.ReplaceTokens//for including in the copy taskdef 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}
本文已收录于 http://www.flydean.com/gradle-build-java-projects/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!