如何在gradle任务中使用源代码来创建文件,然后用它们来制作jar?

vc9ivgsu  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(139)

我在projectRoot/buildSrc中有任务

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不能访问必要的导入类。
如何使用项目代码创建文件,然后将其构建在一个jar中?

btqmn9zl

btqmn9zl1#

最后,我发现解决方案只使用反射

public abstract class SoqTask extends DefaultTask {
    @Input
    public abstract Property<File> getOutputDir();
    @Input
    public abstract ListProperty<URL> getInputUrls();
    @Input
    public abstract Property<String> getSerializerFileName();

    @TaskAction
    public void generate() {
        URL[] urls = getInputUrls().get().toArray(new URL[0]);
        try (URLClassLoader urlClassLoader = new URLClassLoader(urls)) {
            Class<?> factoryClass =
                    urlClassLoader.loadClass("my.org.GoodRecordFactory");
            Method getInstanceMethod = factoryClass.getMethod("instance");
            Object recordSerializer = getInstanceMethod.invoke(factoryClass);
            Objects.requireNonNull(recordSerializer);

            Class<?> serializerUtils =
                    urlClassLoader.loadClass("my.org.Util");
            Method serializeMethod = Arrays.stream(serializerUtils.getMethods())
                    .filter(e -> "serialize".equals(e.getName()))
                    .findFirst().orElseThrow(RuntimeException::new);
            byte[] serializedBytes = (byte[]) serializeMethod.invoke(serializerUtils, recordSerializer);
            
            File outputFile = new File(getOutputDir().get(), getSerializerFileName().get());
            try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                outputStream.write(serializedBytes);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

字符串
在Gradle中使用:

import one.ids.gradle.SoqTask
tasks.register("oqTask", SoqTask) {
    dependsOn(serverJava)
    inputUrls = (sourceSets.server.output.getClassesDirs() + sourceSets.server.runtimeClasspath.files)
            .collect(f -> f.toURI().toURL() as URL)
    outputDir = sourceSets.server.java.destinationDirectory.get().asFile
    serializerFileName = "serializer.bin"
}

相关问题