gpt4 book ai didi

gradle - 如何将 list 部分与 Gradle 和 shadowJar 合并

转载 作者:行者123 更新时间:2023-12-04 08:03:21 24 4
gpt4 key购买 nike

我需要的
我们使用 Gradle 和 shadowJar 打包我们的产品.我们使用的一些库,利用 individual sections in Jar Manifests ,特别是诸如 Implementation-Title 和
实现版本。这些有时会显示在我们的产品(输出)中,所以我希望它们能够在 shawdowJar-Process 中存活下来。
例子
lib1.jar/META-INF/MANIFEST.MF

Manifest-Version: 1.0
...

Name: org/some/lib
...
Implementation-Title: someLib
Implementation-Version: 2.3
...
lib2.jar/META-INF/MANIFEST.MF
Manifest-Version: 1.0
...

Name: org/some/other/lib
...
Implementation-Title: someOtherLib
Implementation-Version: 5.7-RC
...
=>
product.jar/META-INF/MANIFEST.MF
Manifest-Version: 1.0
...

Name: org/some/lib
...
Implementation-Title: someLib
Implementation-Version: 2.3
...

Name: org/some/other/lib
...
Implementation-Title: someOtherLib
Implementation-Version: 5.7-RC
...
我发现了什么
  • manipulate the resulting Manifest 比较容易使用 shadowJar:
  • project.shadowJar {
    manifest {
    attributes(["Implementation-Title" : "someLib"], "org/some/lib")
    attributes(["Implementation-Title" : "someOtherLib"], "org/some/other/lib")
    }
    }
    静态地生成我想要的东西。
  • shadowJar 可以为我提供 a list of dependencies .但是,当我像这样遍历 FileCollection
  • project.shadowJar {
    manifest {
    for (dependency in includedDependencies) {
    // read in jar file and set attributes
    }
    }
    }
    Gradle 不高兴:“在依赖项解析中包含依赖项配置 ':project:products: :compile' 后无法更改依赖项。”
  • 当我定义一个新任务时
  • def dependencies = [];
    project.tasks.register('resolveDependencies') {
    doFirst {
    gradleProject.configurations.compile.resolvedConfiguration.resolvedArtifacts.each {
    dependencies.add(it.file)
    }
    }
    }
    project.tasks['shadowJar'].dependsOn(project.tasks['resolveDependencies']);

    project.shadowJar {
    manifest {
    // dependencies will be empty when this code is called
    for (dependency in dependencies) {
    // read in jar file and set attributes
    }
    }
    }
    依赖关系没有及时解决。
    我想知道的
    如何在不破坏 Gradle 的情况下访问依赖项?或者,是否有另一种方法可以将命名的各个部分与 shadowJar 合并?

    最佳答案

    根据https://github.com/johnrengelman/shadow/issues/369应该使用 shadowJar 的 Transformer 接口(interface)来执行此操作。
    所以来了:

    import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer;
    import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext;

    import java.io.ByteArrayOutputStream;
    import java.util.jar.Attributes;
    import java.util.jar.Manifest;
    import java.util.Map.Entry;

    import shadow.org.apache.tools.zip.ZipOutputStream;
    import shadow.org.apache.tools.zip.ZipEntry;
    import shadow.org.codehaus.plexus.util.IOUtil;

    import org.gradle.api.file.FileTreeElement;

    import static java.nio.charset.StandardCharsets.*
    import static java.util.jar.JarFile.*;

    /**ManifestVersionMergeTransformer appends all version information sections from manifest files to the resulting manifest file.
    * @author Robert Lichtenberger
    */
    public class ManifestMergeTransformer implements Transformer {

    String includePackages; // regular expression that must match a given package
    String excludePackages; // regular expression that must not match a given package

    private Manifest manifest;

    @Override
    public boolean canTransformResource(FileTreeElement element) {
    MANIFEST_NAME.equalsIgnoreCase(element.relativePath.pathString);
    }

    @Override
    public void transform(TransformerContext context) {
    if (manifest == null) {
    manifest = new Manifest(context.is);
    } else {
    Manifest toMerge = new Manifest(context.is);
    for (Entry<String, Attributes> entry : toMerge.getEntries().entrySet()) {
    if (mustInclude(entry.getKey())) {
    manifest.getEntries().put(entry.getKey(), entry.getValue());
    }
    }
    }
    IOUtil.close(context.is);
    }

    private boolean mustInclude(String packageName) {
    return (includePackages == null || packageName.matches(includePackages)) && (excludePackages == null || !packageName.matches(excludePackages));
    }

    @Override
    public boolean hasTransformedResource() {
    return true;
    }

    @Override
    public void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {
    ZipEntry entry = new ZipEntry(MANIFEST_NAME);
    entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time);
    os.putNextEntry(entry);
    if (manifest != null) {
    ByteArrayOutputStream manifestContents = new ByteArrayOutputStream();
    manifest.write(manifestContents);
    os.write(manifestContents.toByteArray());
    }
    }
    }

    关于gradle - 如何将 list 部分与 Gradle 和 shadowJar 合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66333597/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com