在gradle中构建java项目

简介: 在gradle中构建java项目

目录



简介


之前的文章我们讲到了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
}
相关文章
|
9月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
647 8
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
Java与生成式AI:构建内容生成与创意辅助系统
生成式AI正在重塑内容创作、软件开发和创意设计的方式。本文深入探讨如何在Java生态中构建支持文本、图像、代码等多种生成任务的创意辅助系统。我们将完整展示集成大型生成模型(如GPT、Stable Diffusion)、处理生成任务队列、优化生成结果以及构建企业级生成式AI应用的全流程,为Java开发者提供构建下一代创意辅助系统的完整技术方案。
425 10
|
9月前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
549 3
|
9月前
|
机器学习/深度学习 人工智能 监控
Java与AI模型部署:构建企业级模型服务与生命周期管理平台
随着企业AI模型数量的快速增长,模型部署与生命周期管理成为确保AI应用稳定运行的关键。本文深入探讨如何使用Java生态构建一个企业级的模型服务平台,实现模型的版本控制、A/B测试、灰度发布、监控与回滚。通过集成Spring Boot、Kubernetes、MLflow和监控工具,我们将展示如何构建一个高可用、可扩展的模型服务架构,为大规模AI应用提供坚实的运维基础。
665 0
|
9月前
|
人工智能 Java 物联网
Java与边缘AI:构建离线智能的物联网与移动应用
随着边缘计算和终端设备算力的飞速发展,AI推理正从云端向边缘端迁移。本文深入探讨如何在资源受限的边缘设备上使用Java构建离线智能应用,涵盖从模型优化、推理加速到资源管理的全流程。我们将完整展示在Android设备、嵌入式系统和IoT网关中部署轻量级AI模型的技术方案,为构建真正实时、隐私安全的边缘智能应用提供完整实践指南。
601 3
|
9月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
427 1
|
9月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
394 1
|
10月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
434 0
|
10月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
614 16

热门文章

最新文章

推荐镜像

更多