首页 > Java > java教程 > 正文

无法从 JAR 文件中读取自定义 Manifest 属性的原因及解决方案

霞舞
发布: 2025-08-06 15:34:11
原创
336人浏览过

无法从 jar 文件中读取自定义 manifest 属性的原因及解决方案

本文旨在解决无法从修改后的 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 文件格式正确。

注意事项

  • 编码问题: 确保在读取和写入 Manifest 文件时使用正确的字符编码,通常推荐使用 UTF-8。
  • 文件完整性: 修改 JAR 文件后,务必验证文件的完整性,确保没有损坏。
  • 依赖管理: 在实际项目中,修改第三方 JAR 文件可能不是一个好的实践。建议通过依赖管理工具(如 Maven 或 Gradle)来管理依赖,并使用插件或构建脚本来修改 Manifest 文件。

总结

通过正确地添加换行符,可以解决无法从 JAR 文件中读取自定义 Manifest 属性的问题。在处理 Manifest 文件时,务必注意其格式规范,确保属性条目之间的分隔符正确。同时,建议在实际项目中采用更规范的依赖管理和构建方式,避免直接修改第三方 JAR 文件。

以上就是无法从 JAR 文件中读取自定义 Manifest 属性的原因及解决方案的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号