
本文旨在解决无法从修改后的 JAR 文件中读取自定义 Manifest 属性的问题。通过使用 FileSystem API 修改 JAR 包中的 MANIFEST.MF 文件,添加自定义属性后,使用 JarFile 类读取时却无法获取到该属性。本文将分析问题原因,并提供正确的修改方法,确保自定义属性能够被正确读取。
当尝试向 JAR 文件的 Manifest 文件中添加自定义属性时,如果读取时发现该属性不存在,通常是因为在写入 Manifest 文件时缺少了必要的换行符。Manifest 文件的规范要求每个属性条目之间必须使用换行符分隔。
具体来说,在修改 Manifest 文件时,不仅需要在添加的属性前后添加换行符,还需要确保整个文件以换行符结尾。否则,java.util.jar.Manifest 类在解析 Manifest 文件时可能无法正确识别新添加的属性。
以下代码片段展示了正确的修改 Manifest 文件的方式:
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.nio.file.StandardCopyOption;
public class ManifestModifier {
public static void main(String[] args) throws IOException, URISyntaxException {
File jar = new File("C:\Users\employee1234\Desktop\auth-0.1.3.jar");
String testVersion = "1.2.3";
Map<String, String> env = new HashMap<>();
env.put("create", "true");
// Mount the jar
try (FileSystem fileSystem = FileSystems.newFileSystem(jarFileToURI(jar), env)) {
// Read the manifest
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Path manifestPath = fileSystem.getPath("/META-INF/MANIFEST.MF");
Files.copy(manifestPath, byteArrayOutputStream);
// Convert the manifest bytes to a string and construct a string builder
StringBuilder manifestData = new StringBuilder(byteArrayOutputStream.toString().trim());
// Add the custom manifest attribute, ensuring proper line breaks
manifestData.append("
");
manifestData.append("Deployments-Version: ").append(testVersion).append("
");
//Ensure the end of the file also has a new line character.
manifestData.append("
");
// Write the manifest back to the jar
Files.copy(new ByteArrayInputStream(manifestData.toString().getBytes()), manifestPath,
StandardCopyOption.REPLACE_EXISTING);
// Try-with-resources closes the mounted jar
}
// This part should now work
try (JarFile jarFile = new JarFile(jar)) {
Manifest manifest = jarFile.getManifest();
System.out.println(manifest.getMainAttributes().getValue("Deployments-Version"));
}
}
// Stolen from java.io.File with some modifications
private static URI jarFileToURI(File jarFile) throws URISyntaxException {
String sp = slashify(jarFile.getAbsoluteFile().getPath(), false);
if (sp.startsWith("//"))
sp = "//" + sp;
return new URI("jar:file", null, sp, null);
}
// Stolen from java.io.File;
private static String slashify(String path, boolean isDirectory) {
String p = path;
if (File.separatorChar != '/')
p = p.replace(File.separatorChar, '/');
if (!p.startsWith("/"))
p = "/" + p;
if (!p.endsWith("/") && isDirectory)
p = p + "/";
return p;
}
}关键修改:
manifestData.append("
");
manifestData.append("Deployments-Version: ").append(testVersion).append("
");
manifestData.append("
");这段代码在添加自定义属性后,以及文件末尾,都添加了换行符,确保 Manifest 文件格式正确。
通过正确地添加换行符,可以解决无法从 JAR 文件中读取自定义 Manifest 属性的问题。在处理 Manifest 文件时,务必注意其格式规范,确保属性条目之间的分隔符正确。同时,建议在实际项目中采用更规范的依赖管理和构建方式,避免直接修改第三方 JAR 文件。
以上就是无法从 JAR 文件中读取自定义 Manifest 属性的原因及解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号