本文旨在解决无法从修改后的 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 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号