You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gradle任务中调用项目源码生成文件并打包进同一JAR

问题描述

我在项目根目录的buildSrc下编写了如下Gradle任务代码:

package myapp.gradle;

import myapp.Utils;
import myapp.GoodRecord;
import myapp.GoodRecordFactory;
import org.apache.commons.io.FileUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

import java.io.File;
import java.io.IOException;

public class SoqTask extends DefaultTask {
    private File saveToDir;

    public void setSaveToDir(File saveToDir) {
        this.saveToDir = saveToDir;
    }
    @TaskAction
    public void run() {
        try {
            GoodRecord instance = GoodRecordFactory.instance();
            byte[] serialize = Utils.serialize(instance);
            FileUtils.writeByteArrayToFile(new File(saveToDir, "goodrecord.bin"), serialize);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

但SoqTask无法访问所需的导入类(myapp.Utils、myapp.GoodRecord等项目代码),请问如何实现调用项目代码生成文件,并将生成的文件与项目一起打包进同一个JAR文件?

解决方案

1. 推荐方案:调整任务实现逻辑,避免buildSrc依赖项目代码

buildSrc下的代码会在项目构建脚本执行前完成编译,无法直接依赖主项目的源码。正确的做法是把生成文件的逻辑放到主项目源码中,再通过Gradle任务调用。

步骤1:在主项目中编写生成工具类

在myapp包下创建生成逻辑的工具类,把原来SoqTask里的核心逻辑迁移过来:

package myapp;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class GoodRecordGenerator {
    public static void generate(File saveToDir) throws IOException {
        GoodRecord instance = GoodRecordFactory.instance();
        byte[] serialize = Utils.serialize(instance);
        FileUtils.writeByteArrayToFile(new File(saveToDir, "goodrecord.bin"), serialize);
    }
}

步骤2:在Gradle脚本中定义任务并关联打包流程

在项目根目录的build.gradle(或build.gradle.kts)中注册任务,确保依赖主项目编译任务,同时将生成的文件纳入打包资源:

// 注册生成文件的任务
tasks.register('generateGoodRecord', JavaExec) {
    // 先编译主项目代码,再执行生成逻辑
    dependsOn tasks.compileJava
    // 指定要执行的主类
    mainClass = 'myapp.GoodRecordGenerator'
    // 传入文件保存目录,这里指定到构建目录下的资源生成目录
    args = [project.layout.buildDirectory.dir('generated/resources/main').get().asFile.absolutePath]
    // 使用主项目的运行时类路径
    classpath = sourceSets.main.runtimeClasspath
}

// 让jar打包任务依赖生成任务,确保文件生成后再打包
tasks.jar.dependsOn tasks.generateGoodRecord

// 将生成目录添加到主项目资源目录,打包时自动包含生成的文件
sourceSets.main.resources.srcDir project.layout.buildDirectory.dir('generated/resources/main')

2. 不推荐方案:buildSrc直接依赖主项目JAR

如果一定要在buildSrc中实现任务,需要先将主项目代码打包成JAR,再在buildSrc的依赖中引入。但这种方式会产生循环依赖,每次主项目代码变更都需要手动重新打包,维护成本极高。

操作步骤:

  1. 先执行主项目打包:./gradlew jar
  2. 在buildSrc/build.gradle中添加依赖:
dependencies {
    // 引入主项目打包后的JAR
    implementation files('../build/libs/your-project-name.jar')
    implementation 'org.apache.commons:commons-io:2.15.0'
    implementation gradleApi()
}

内容的提问来源于stack exchange,提问作者Micah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:00:17