HDDS-15963. Fix EC degraded read NPE caused by CodecRegistry depending on TCCL in isolated ClassLoader#10861
HDDS-15963. Fix EC degraded read NPE caused by CodecRegistry depending on TCCL in isolated ClassLoader#10861hiwuya wants to merge 1 commit into
Conversation
chihsuan
left a comment
There was a problem hiding this comment.
Thanks for the fix! @hiwuya The fix itself looks correct. But this test can pass vacuously. I tried this locally. With the fix reverted and a different method order forced, all 8 tests pass, so a regression would go undetected.
Would it make sense to move this test to a separate class?
| } | ||
|
|
||
| @Test | ||
| public void testRegistryLoadsWithoutTccl() { |
There was a problem hiding this comment.
CodecRegistry.instance is a static singleton, so if any other test in this class runs first, the registry is already initialized, and this test passes even with the fix reverted.
|
@chihsuan Good catch. I've moved the test to a separate class TestCodecRegistryTcclIsolation so it runs in its own JVM and is guaranteed to be the first test touching CodecRegistry. |
…g on TCCL in isolated ClassLoader
chihsuan
left a comment
There was a problem hiding this comment.
Thanks for the update! Left a non-blocking nit. Other than that, LGTM.
| .getCoderNames(ECReplicationConfig.EcCodec.RS.name().toLowerCase()); | ||
| assertThat(rsCoderNames).isNotNull(); | ||
| assertThat(rsCoderNames).isNotEmpty(); | ||
| assertThat(rsCoderNames).contains(RSRawErasureCoderFactory.CODER_NAME); |
There was a problem hiding this comment.
nit: assertThat(rsCoderNames).contains(...) alone already implies non-null and non-empty.
What changes were proposed in this pull request?
This PR fixes a
NullPointerExceptionduring EC degraded reads when the Ozone client runs inside an isolated plugin class loader (e.g. Trino Hive connector).Normal reads succeed, but when a DataNode is unavailable, the EC degraded read path fails with:
Root cause:
CodecRegistryloads coder factories viaServiceLoader.load(RawErasureCoderFactory.class), which uses the thread context class loader (TCCL). In Trino's isolated plugin class loader, the TCCL cannot see the OzoneMETA-INF/servicesproviders, sogetCoderNames("rs")returnsnull, causing the NPE inCodecUtil. Spark works because its TCCL can see the Ozone providers.Fix: Use
CodecRegistry's own class loader instead of the TCCL:No changes to the singleton pattern, registration logic, native coder priority, fallback order, or public API.
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-15963
How was this patch tested?
TestCodecRegistryTcclIsolation#testRegistryLoadsWithoutTcclin a separate test class to ensure it runs in its own JVM as the first test to touchCodecRegistry, avoiding vacuous passes when the eager singleton is already initialized under the normal TCCL by other tests. Sets TCCL to an emptyClassLoader(null)before firstCodecRegistryinitialization, then verifiesgetCoderNames("rs")is non-null, non-empty, and containsrs_java. Restores TCCL infinally.