You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java API生成JAR文件时两次输出字节不一致的原因排查

动态生成的JAR文件字节内容不一致的原因

我们在通过代码动态构建JAR文件时,发现多次生成的文件HEX信息存在固定位置的差异。为排查问题,简化场景后仅使用Java API和空Manifest测试,代码如下:

public class MyObject {
    public static void main(String[] args) {
        System.out.println("START");
        MyObject myObject = new MyObject();
        myObject.myTest();
        System.out.println("END");
        return;
    }

    protected void myTest() {
        System.out.println("Inside myTest()");
        try {
            Manifest manifest = new Manifest();
            
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream, manifest);
            
            byteArrayOutputStream.flush();
            byteArrayOutputStream.close();
            jarOutputStream.flush();
            jarOutputStream.close();

            OutputStream outputStream = new FileOutputStream("c:\\Downloads\\outputJar1.jar");     
            outputStream.write(byteArrayOutputStream.toByteArray());
            
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {}
    }
}

执行代码生成outputJar1.jar,修改输出路径后再次执行得到outputJar2.jar,理论上两个文件应完全一致,但对比工具显示存在固定位置的字节差异,且每次生成的文件对应位置的十六进制值固定但两次文件间不同。


原因分析

核心问题在于JAR本质是ZIP格式文件,其中每个条目(包括META-INF/MANIFEST.MF)都会存储条目的最后修改时间戳:

  • 当你通过JarOutputStream写入Manifest时,系统会自动为该Manifest条目添加当前系统时间作为最后修改时间
  • 两次执行代码的时间不同,这个时间戳字段的字节值会随之变化,而该字段在ZIP/JAR文件中的位置是固定的,因此两次生成的文件会在固定位置出现差异

额外代码问题提示

你的代码存在流关闭顺序错误:应先关闭JarOutputStream,再关闭ByteArrayOutputStream。因为JarOutputStream在关闭时才会将Manifest的完整内容写入底层的ByteArrayOutputStream,当前的关闭顺序可能导致数据不完整(测试场景中未暴露,但属于潜在风险)。另外,catch块直接吞掉异常的做法不建议,建议添加e.printStackTrace()以便排查后续问题。


内容的提问来源于stack exchange,提问作者Unhandled Exception

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:46