Skip to content

GH-1314: Fix PersistentWatcher with CuratorFramework implementations that are not CuratorFrameworkBase - #1315

Merged
kezhuw merged 1 commit into
apache:masterfrom
sftwnd:GH-1314
Oct 26, 2026
Merged

kezhuw merged 1 commit into
apache:masterfrom
sftwnd:GH-1314

Conversation

@sftwnd

@sftwnd sftwnd commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Since #1262, PersistentWatcher casts the client to CuratorFrameworkBase to reach the underlying client, because NamespaceFacade does not support getCuratorListenable(). As a result, PersistentWatcher and CuratorCache fail with ClassCastException for any other CuratorFramework implementation, for example a decorator of the public interface. This worked in 5.8.0.

This change uses the underlying client only for CuratorFrameworkBase instances, so namespaced facades keep working (#1259). For any other implementation it falls back to the public getCuratorListenable(). Both start() and close() are covered; the cast in close() was added by #1293.

Two tests are added to TestPersistentWatcher. They use a java.lang.reflect.Proxy-based delegating client and cover:

  • watch events;
  • the Closed notification;
  • de-registration of listeners on close.

Both tests fail on master with ClassCastException and pass with the fix. TestPersistentWatcher, TestCuratorCache* and spotless:check pass locally on JDK 21.

Fixes #1314.

…tions that are not CuratorFrameworkBase

Use the underlying client only for CuratorFrameworkBase instances (namespaced
facades, apache#1259) and fall back to the public getCuratorListenable() otherwise,
so that PersistentWatcher and CuratorCache work with any CuratorFramework
implementation again, e.g. a decorator of the public interface.

@kezhuw kezhuw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Generally speaking, all implementations should come from curator as CuratorFramework itself is constructed from cutator and some of its api (say, usingNamespace) are depended by internal codes. Before #517, there are plenty casts to CuratorFrameworkImpl. That is why I added the "MUST BE" statement.

I guess forwarding could be the only way to meet curator.

@kezhuw
kezhuw merged commit 0d09f02 into apache:master Oct 26, 2026
18 of 20 checks passed
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.

Regression in 5.9.0: CuratorCache fails with ClassCastException when the client is not a CuratorFrameworkBase

2 participants