Skip to content

(Closeable)ThreadContext putAll removes entire context #2946

@nielsm5

Description

@nielsm5

Description

The ThreadContext no longer works as intended. The new version closes/removes items from the stack when it shouldn't.

CloseableThreadContext calls ThreadContext.putAll.

if (!valuesToReplace.isEmpty()) {
    ThreadContext.putAll(valuesToReplace);
}

Once putAll has been called, the stack is gone, and only the newly inserted values are present.
Since it's used by CloseableThreadContext#close() it's quite destructive...

Configuration

Version: 2.24.0

Operating system: All

JDK: All

Reproduction

	@Test
	public void testAutoCloseableThreadContext() {
		try (final CloseableThreadContext.Instance ctc1 = CloseableThreadContext.put("outer", "one")) {
			try (final CloseableThreadContext.Instance ctc2 = CloseableThreadContext.put("outer", "two")) {
				assertEquals("two", ThreadContext.get("outer"));

				try (final CloseableThreadContext.Instance ctc3 = CloseableThreadContext.put("inner", "one")) {
					assertEquals("one", ThreadContext.get("inner"));

					ThreadContext.put("not-in-closeable", "true");
					assertEquals("two", ThreadContext.get("outer"));
				}

				assertEquals("two", ThreadContext.get("outer"));
				assertNull(ThreadContext.get("inner"));
			}

			assertEquals("one", ThreadContext.get("outer"));
			assertNull(ThreadContext.get("inner"));
		}
		assertEquals("true", ThreadContext.get("not-in-closeable"));

		assertNull(ThreadContext.get("inner"));
		assertNull(ThreadContext.get("outer"));
	}

and

	@Test
	public void testAutoCloseableThreadContextPutAll() {
		try (final CloseableThreadContext.Instance ctc1 = CloseableThreadContext.put("outer", "one")) {
			try (final CloseableThreadContext.Instance ctc2 = CloseableThreadContext.put("outer", "two")) {
				assertEquals("two", ThreadContext.get("outer"));

				try (final CloseableThreadContext.Instance ctc3 = CloseableThreadContext.put("inner", "one")) {
					assertEquals("one", ThreadContext.get("inner"));

					ThreadContext.put("not-in-closeable", "true");
					ThreadContext.putAll(Collections.singletonMap("inner", "two"));
					assertEquals("two", ThreadContext.get("inner"));
					assertEquals("two", ThreadContext.get("outer"));
				}

				assertEquals("two", ThreadContext.get("outer"));
				assertNull(ThreadContext.get("inner"));
			}

			assertEquals("one", ThreadContext.get("outer"));
			assertNull(ThreadContext.get("inner"));
		}
		assertEquals("true", ThreadContext.get("not-in-closeable"));

		assertNull(ThreadContext.get("inner"));
		assertNull(ThreadContext.get("outer"));
	}

Metadata

Metadata

Assignees

Labels

apiAffects the public APIbugIncorrect, unexpected, or unintended behavior of existing code

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions