有 Java 编程相关的问题?

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

是否可以将自定义Java库导入Gradle buildSrc Java类?

我用Java编写了一个定制的Gradle任务,它生成一个Java文件。我的任务位于我的项目的buildSrc目录中。 我想扩展这个任务,但我需要从另一个项目访问我的自定义Java库

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

import my.custom.java.library.*;

public class AutoGenerateTask extends DefaultTask {

  @TaskAction
  public void generate() {
    ...
    // java code
    ...
  }

}

我是格拉德尔的新手,我不知道这是否可能


共 (1) 个答案

  1. # 1 楼答案

    是的,有可能。可以使用Gradle复合构建将其他依赖项包含到构建逻辑中

    假设

    让我们先做一些假设:

    简化结构

    .
    ├── project-custom-lib
    │   ├── build.gradle.kts
    │   ├── settings.gradle.kts
    │   └── src/main
    │      └── java/xx/oo/Demo.java
    └── project-app
        ├── buildSrc
        │   ├── build.gradle.kts
        │   └── src/main
        │      ├── java/com/example/AutoGenerateTask.java
        │      └── kotlin/com.example.java-conventions.gradle.kts
        ├── aaa
        │   ├── build.gradle.kts
        │   └── src/
        ├── bbb
        │   ├── build.gradle.kts
        │   └── src/
        └── settings.gradle.kts
    

    project-custom-lib/build.gradle.kts

    ...
    
    group = "xx.oo"
    

    project-custom-lib/settings.gradle.kts

    rootProject.name = "project-custom-lib"
    

    project-custom-lib/src/main/java/xx/oo/Demo.java

    package xx.oo;
    
    public class Demo {
        public static final String VALUE = "DEMO!";
    }
    

    project-app/settings.gradle.kts

    rootProject.name = "project-app"
    include("aaa", "bbb")
    

    project-app/buildSrc/src/kotlin/com.example.java-conventions.gradle.kts

    import com.example.AutoGenerateTask;
    
    ...
    
    tasks.register<AutoGenerateTask>("autogen")
    

    解决方案

    第一步:使buildSrc显式

    buildSrc是一个特殊的文件夹,隐式地作为includeBuild处理。但是,它目前不支持包含其他版本(Gradle 7.0)。因此,我们必须首先明确地打破这一规则

    这一步很简单。只需将文件夹重命名为buildSrc以外的名称,例如build-conventions,并为其创建一个空的settings.gradle.kts

    $ mv project-app/buildSrc project-app/build-conventions
    $ touch project-app/build-conventions/settings.gralde.kts
    

    然后将build-conventions包含在project-app/settings.gradle.kts中:

    rootProject.name = "project-app"
    includeBuild("build-conventions")
    include("aaa", "bbb")
    

    这些更改不应破坏您的项目构建。您现在可以构建它:

    $ cd project-app
    $ ./gradlew build
    
    BUILD SUCCESSFUL in XXs
    XX actionable tasks: XX executed, XX up-to-date
    
    # If you write some tests inside build-conventions, you definitely need this.
    $ ./gradlew -p build-conventions build
    
    BUILD SUCCESSFUL in XXs
    XX actionable tasks: XX executed, XX up-to-date
    

    第2步:使project-custom-lib的类在build-conventions

    中可解析

    实际上,Gradle在Composite Builds中描述了如何做到这一点:

    By default, Gradle will configure each included build in order to determine the dependencies it can provide. The algorithm for doing this is very simple: Gradle will inspect the group and name for the projects in the included build, and substitute project dependencies for any external dependency matching ${project.group}:${project.name}.

    我们先把这一行添加到project-app/build-conventions/settings.gradle.kts中:

    includeBuild("../../project-custom-lib")
    

    然后在project-app/build-conventions/build.gradle.kts中添加依赖项:

    ...
    
    dependencies {
        implementation("xx.oo:project-custom-lib")
    }
    

    现在,您应该能够在代码中导入它:

    ...
    
    import xx.oo.Demo;
    
    public class AutoGenerateTask extends DefaultTask {
        @TaskAction
        public void generate() {
            System.out.println(Demo.VALUE);
    
            ...
        }
    }