Skip to content

Fix DockerDesktopClientProviderStrategy always being applicable#11832

Open
seonwooj0810 wants to merge 1 commit into
testcontainers:mainfrom
seonwooj0810:fix/issue-11829-docker-desktop-isapplicable
Open

Fix DockerDesktopClientProviderStrategy always being applicable#11832
seonwooj0810 wants to merge 1 commit into
testcontainers:mainfrom
seonwooj0810:fix/issue-11829-docker-desktop-isapplicable

Conversation

@seonwooj0810
Copy link
Copy Markdown

Fixes #11829

Problem

DockerDesktopClientProviderStrategy.isApplicable() returns true on Linux/macOS even when Docker Desktop is not installed, after which getTransportConfig() throws a NullPointerException.

The cause is a Lombok pitfall. The socketPath field is declared with @Getter(lazy = true):

@Getter(lazy = true)
@Nullable
private final Path socketPath = resolveSocketPath();

Lombok rewrites a lazy field into an AtomicReference that holds the memoized value, so the field itself is never null. isApplicable() checked the raw field rather than the generated accessor:

return (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) && this.socketPath != null; // AtomicReference is never null

As a result the strategy is always considered applicable, and getTransportConfig() then dereferences getSocketPath() (which resolves to null when no ~/.docker/desktop/docker.sock or ~/.docker/run/docker.sock exists), producing the NPE reported in #11829.

Fix

Use the Lombok-generated getSocketPath() accessor — which resolves the lazy value to the actual Path (or null) — instead of reading the backing field directly. getDescription() and getTransportConfig() already use the accessor; this aligns isApplicable() with them.

return (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) && getSocketPath() != null;

Tests

Added DockerDesktopClientProviderStrategyTest (no Docker required) covering both directions by pointing user.home at a temp directory:

  • notApplicableWhenDockerDesktopSocketIsMissing — no Docker Desktop socket present ⇒ isApplicable() is false. This fails on the current code (returns true) and passes with the fix.
  • applicableWhenDockerDesktopSocketExists — a .docker/desktop/docker.sock present ⇒ isApplicable() is true.

Verification done: ran ./gradlew :testcontainers:test --tests "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategyTest" — both tests pass with the fix; reverting the one-line change makes notApplicableWhenDockerDesktopSocketIsMissing fail, confirming the test reproduces the bug. ./gradlew spotlessApply reports no formatting changes.

The socketPath field uses Lombok's @Getter(lazy = true), which rewrites
it into an AtomicReference that is never null. isApplicable() compared
the raw field against null, so it always returned true on Linux/macOS
even when Docker Desktop was not installed. The strategy was then
selected and getTransportConfig() threw a NullPointerException because
the lazily-resolved getSocketPath() returned null.

Check the generated getSocketPath() accessor instead so the resolved
socket path (or null when no Docker Desktop socket exists) is evaluated.

Fixes testcontainers#11829

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@seonwooj0810 seonwooj0810 requested a review from a team as a code owner June 5, 2026 00:16
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]: DockerDesktopClientProviderStrategy is always applicable

1 participant