提问人:Micah 提问时间:11/18/2023 更新时间:11/18/2023 访问量:19
如何使用gradle任务中的源代码创建文件,然后用所有这些文件制作jar?
How to use source code inside gradle task for create file and then make jar with all of them?
问:
我在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 中一起构建?
答:
0赞
Micah
11/27/2023
#1
最后,我找到了仅使用反射的解决方案
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"
}
评论