gpt4 book ai didi

java - 以编程方式替换 JAR 中的 MANIFEST.MF 文件

转载 作者:行者123 更新时间:2023-12-01 13:37:16 33 4
gpt4 key购买 nike

我想在创建 JAR 后修改 MANIFEST.MFexclude certain Class-Path entries .为此,我决定使用 zip4j .提取似乎工作正常,但为了将 MANIFEST.MF 文件放回 JAR,我使用以下代码:

String metaInfFolderName = "META-INF";
Path extractedManifestFilePath = Paths.get("...");
ZipFile zipFile = new ZipFile("Test-Zip-File.zip");
ZipParameters zipParameters = new ZipParameters();
zipParameters.setDefaultFolderPath(metaInfFolderName);
zipFile.addFile(extractedManifestFilePath.toFile(), zipParameters);

但是,此代码无法按预期工作:父目录最终总是被命名为 NF 而不是完整的 META-INF。似乎起始字符被切断了。这可能是什么原因,或者是否有另一种有意义的可能性来替换 JAR(本质上只是 ZIP)中的文件?

maven 依赖:

<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.6.1</version>
</dependency>

此外,我尝试使用 jar 实用程序,如 here 所述但是当调用命令 jar uf MyJAR.jar META-INF/MANIFEST.MF 时,JAR 中的 MANIFEST.MF 被删除而不是被替换.通过 zip -ur MyJAR.jar "META-INF/MANIFEST.MF" 使用 zip 实用程序可以工作,但会损坏 JAR 文件,因此它是不再可运行:

Error: An unexpected error occurred while trying to open file MyJAR.jar

最佳答案

你可以这样使用:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.Manifest;

public class ManifestManipulator {

public static final void main(String... args) throws IOException {
if (args.length == 0) {
throw new IllegalArgumentException("at least the path to the JAR file expected!");
}
Path jarPath = Paths.get(args[0]);
Set<String> attributeNames = args.length > 1 ? new LinkedHashSet<>(List.of(args).subList(1, args.length)) : Set.of();

if (!attributeNames.isEmpty()) {
ManifestManipulator manifestManipulator = new ManifestManipulator();
manifestManipulator.removeManifestEntries(jarPath, attributeNames);
} else {
System.out.println("Warning: no entries specified to remove!");
}
}

private void removeManifestEntries(Path jarPath, Set<String> attributeNames) throws IOException {
System.out.println("Going to remove: " + attributeNames);
try (FileSystem jarFS = FileSystems.newFileSystem(URI.create("jar:" + jarPath.toUri()), Map.of())) {
Path manifestPath = jarFS.getPath("META-INF", "MANIFEST.MF");
Manifest manifest = readManifest(manifestPath);
Attributes mainAttributes = manifest.getMainAttributes();
System.out.println("Found main attribute names: " + mainAttributes.keySet());

boolean removed = mainAttributes.entrySet().removeIf(entry -> attributeNames.contains(((Name) entry.getKey()).toString()));
if (removed) {
writeManifest(manifestPath, manifest);
} else {
System.out.println("Warning: nothing removed");
}
}
}

private Manifest readManifest(Path manifestPath) throws IOException {
try (InputStream is = Files.newInputStream(manifestPath)) {
return new Manifest(is);
}
}

private void writeManifest(Path manifestPath, Manifest manifest) throws IOException {
try (OutputStream os = Files.newOutputStream(manifestPath)) {
manifest.write(os);
}
}

}

请确保您已添加 jdk.zipfs模块,它将提供一个 FileSystemProvider对于 ZIP/JAR 文件(参见 technote )。

关于java - 以编程方式替换 JAR 中的 MANIFEST.MF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62313791/

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