Skip to content

fix(config): guard NPE in getGrayLastModifiedTs and add volatile to DCL - #15669

Open
srpatcha wants to merge 1 commit into
alibaba:developfrom
srpatcha:fix/config-cache-npe-and-dcl-volatile
Open

fix(config): guard NPE in getGrayLastModifiedTs and add volatile to DCL#15669
srpatcha wants to merge 1 commit into
alibaba:developfrom
srpatcha:fix/config-cache-npe-and-dcl-volatile

Conversation

@srpatcha

@srpatcha srpatcha commented Aug 6, 2026

Copy link
Copy Markdown

What is the purpose of the change

Fixes #15625

Two targeted correctness fixes in the config module.

1. NPE in ConfigCacheService.getGrayLastModifiedTs

The method dereferenced the CacheItem returned by CACHE.get(groupKey) without a null check, even though that lookup can return null. Every sibling method (getContentGrayMd5, getGrayRule) already guards item == null. A query for a non-existent group key would throw a NullPointerException instead of returning 0.

-        if (item.getConfigCacheGray() == null || !item.getConfigCacheGray().containsKey(grayName)) {
+        if (item == null || item.getConfigCacheGray() == null || !item.getConfigCacheGray().containsKey(grayName)) {

2. Broken double-checked locking in ConfigDiskServiceFactory

The singleton used double-checked locking but the static field was not volatile. Without volatile, the JMM permits a thread to observe a non-null reference to a partially-constructed object (classic broken DCL). Declared the field volatile for safe publication.

-    static ConfigDiskService configDiskService;
+    static volatile ConfigDiskService configDiskService;

Brief changelog

  • ConfigCacheService.getGrayLastModifiedTs: add item == null guard consistent with sibling methods.
  • ConfigDiskServiceFactory.configDiskService: mark volatile.
  • ConfigCacheServiceTest.testGetGrayLastModifiedTs: add regression assertion for the non-existent group-key path.

Verifying this change

  • Existing testGetGrayLastModifiedTs extended to assert getGrayLastModifiedTs("noKey", grayName) == 0 (previously would NPE).
  • No behavior change for existing valid-key callers.

Two issues in the config module:

1. ConfigCacheService.getGrayLastModifiedTs dereferenced the CacheItem
   returned by CACHE.get(groupKey) without a null check, even though
   that map lookup can return null. Every sibling method
   (getContentGrayMd5, getGrayRule) already guards item == null. Added
   the missing guard so a non-existent group key returns 0 instead of
   throwing a NullPointerException.

2. ConfigDiskServiceFactory used double-checked locking on a non-volatile
   static field. Without volatile, the Java Memory Model allows a thread
   to observe a non-null reference to a partially-constructed object.
   Declared configDiskService volatile for safe publication.

Also adds a regression assertion in ConfigCacheServiceTest covering the
non-existent group key path for getGrayLastModifiedTs.

Fixes alibaba#15625

Signed-off-by: Srikanth Patchava <spatchava@meta.com>
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Thanks for your this PR. 🙏
Please check again for your PR changes whether contains any usage/api/configuration change such as Add new API , Add new configuration, Change default value of configuration.
If so, please add or update documents(markdown type) in docs/next/ for repository nacos-group/nacos-group.github.io


感谢您提交的PR。 🙏
请再次查看您的PR内容,确认是否包含任何使用方式/API/配置参数的变更,如:新增API新增配置参数修改默认配置等操作。
如果是,请确保在提交之前,在仓库nacos-group/nacos-group.github.io中的docs/next/目录下添加或更新文档(markdown格式)。

@chenhao26-nineteen

Copy link
Copy Markdown
Collaborator

duplicated PR, reference:#15666

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] ConfigCacheService.getGrayLastModifiedTs NPE risk & ConfigDiskServiceFactory missing volatile

2 participants