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

Java BlobStore completeMultipartUpload方法ETag为空触发空指针异常

本地多部分上传CSV文件时ETag为空触发NPE的问题解决思路

问题概述

本地环境执行多部分上传保存.csv文件时,前9个MultipartPart的blobPart.getMetadata().getETag()返回正常,但第10个及之后的分片ETag始终为空,进而触发NullPointerException。所有分片的添加方式一致且属性配置正确,其他同事的运行环境无此问题。

相关代码

@Override
public String completeMultipartUpload(MultipartUpload mpu, List<MultipartPart> parts) {
  ImmutableList.Builder<Blob> blobs = ImmutableList.builder();
  long contentLength = 0;
  Hasher md5Hasher = Hashing.md5().newHasher();

  for (MultipartPart part : parts) {
     Blob blobPart = getBlob(mpu.containerName(), MULTIPART_PREFIX + mpu.id() + "-" + mpu.blobName() + "-" + part.partNumber());
     contentLength += blobPart.getMetadata().getContentMetadata().getContentLength();
     blobs.add(blobPart);
     md5Hasher.putBytes(BaseEncoding.base16().lowerCase().decode(blobPart.getMetadata().getETag()));
  }
}

已尝试的排查操作

  • 重新安装IntelliJ
  • 重新安装/更换Java版本
  • 移除并重新安装所有依赖库

怀疑方向

推测问题可能与编码相关,代码中使用了BaseEncoding.base16(),且正常运行的同事位于其他国家,可能存在Locale或字符编码差异。

堆栈信息

java.lang.NullPointerException: null
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878)
at com.google.common.io.BaseEncoding$StandardBaseEncoding.trimTrailingPadding(BaseEncoding.java:676)
at com.google.common.io.BaseEncoding.decodeChecked(BaseEncoding.java:231)
at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:217)
at org.jclouds.blobstore.config.LocalBlobStore.completeMultipartUpload(LocalBlobStore.java:843)

解决思路与方案

1. 验证分片Blob的命名与存储完整性

  • 检查第10个及以上分片的Blob名称生成逻辑:确认part.partNumber()返回的编号格式(如是否带前导零),对比同事环境下的分片命名规则,排查是否因命名格式差异导致无法正确读取Blob元数据。
  • 手动检查本地LocalBlobStore的存储目录,确认第10个及之后的分片文件是否存在,以及对应的元数据中ETag字段是否被正确写入。

2. 排查编码与Locale差异

  • 对比本地与同事的JVM默认Locale设置:执行System.out.println(Locale.getDefault())查看本地Locale,若与同事不同,尝试临时修改JVM启动参数(如-Duser.language=en -Duser.region=US)验证问题是否消失。
  • 显式指定字符编码:在处理ETag字符串时,确保使用统一的字符集(如UTF-8),避免依赖系统默认编码。

3. 分析LocalBlobStore的元数据写入逻辑

  • 查看LocalBlobStore中分片上传时ETag的生成与写入代码,确认是否在分片编号超过9时,元数据写入出现异常(例如本地文件系统路径长度限制、文件名特殊字符处理差异)。
  • 若LocalBlobStore基于文件系统存储元数据,直接查看对应分片的元数据文件内容,确认ETag字段是否为空或存在格式错误。

4. 代码层面添加防御性处理

在调用decode前增加非空校验与日志记录,既避免NPE,也能获取更详细的排查信息:

@Override
public String completeMultipartUpload(MultipartUpload mpu, List<MultipartPart> parts) {
  ImmutableList.Builder<Blob> blobs = ImmutableList.builder();
  long contentLength = 0;
  Hasher md5Hasher = Hashing.md5().newHasher();

  for (MultipartPart part : parts) {
     Blob blobPart = getBlob(mpu.containerName(), MULTIPART_PREFIX + mpu.id() + "-" + mpu.blobName() + "-" + part.partNumber());
     contentLength += blobPart.getMetadata().getContentMetadata().getContentLength();
     blobs.add(blobPart);
     String eTag = blobPart.getMetadata().getETag();
     if (eTag == null) {
         throw new IllegalStateException("ETag is missing for part number: " + part.partNumber() + ", blob name: " + blobPart.getName());
     }
     md5Hasher.putBytes(BaseEncoding.base16().lowerCase().decode(eTag));
  }
}

5. 对比操作系统与文件系统差异

  • 检查本地与同事的操作系统类型(如Windows vs macOS/Linux),Windows文件系统对文件名长度、特殊字符的限制与类Unix系统不同,可能导致分片文件或元数据存储异常。
  • 确认本地文件系统的大小写敏感性,若与同事环境不同,排查是否因文件名大小写问题导致无法正确读取Blob。

内容的提问来源于stack exchange,提问作者Silny ToJa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:18:24