Skip to content

Fix BloscCompression class poisoning when Blosc is unavailable#6

Merged
ksugar merged 1 commit into
mainfrom
v1-spec-compat-impl
Jun 23, 2026
Merged

Fix BloscCompression class poisoning when Blosc is unavailable#6
ksugar merged 1 commit into
mainfrom
v1-spec-compat-impl

Conversation

@ksugar

@ksugar ksugar commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

GeffUtils.DEFAULT_COMPRESSION was a static field initialized at class load time. When computeFirstDimChunk() was called before N5ZarrWriter was constructed, loading GeffUtils triggered new BloscCompression(), which threw UnsatisfiedLinkError and permanently marked the class as failed. N5ZarrWriter subsequently called Class.forName("BloscCompression") internally and received NoClassDefFoundError, which it does not catch, causing a crash.

Replace the static field with a lazy-initialization holder (the initialization-on-demand holder idiom). DefaultCompressionHolder.INSTANCE is only initialized the first time a write method calls defaultCompression(), by which point N5ZarrWriter has already handled the UnsatisfiedLinkError itself. The subsequent NoClassDefFoundError thrown inside createDefaultCompression() is caught by the existing Throwable handler and falls back to RawCompression as intended.

GeffUtils.DEFAULT_COMPRESSION was a static field initialized at class
load time. When computeFirstDimChunk() was called before N5ZarrWriter
was constructed, loading GeffUtils triggered new BloscCompression(),
which threw UnsatisfiedLinkError and permanently marked the class as
failed. N5ZarrWriter subsequently called Class.forName("BloscCompression")
internally and received NoClassDefFoundError, which it does not catch,
causing a crash.

Replace the static field with a lazy-initialization holder (the
initialization-on-demand holder idiom). DefaultCompressionHolder.INSTANCE
is only initialized the first time a write method calls defaultCompression(),
by which point N5ZarrWriter has already handled the UnsatisfiedLinkError
itself. The subsequent NoClassDefFoundError thrown inside
createDefaultCompression() is caught by the existing Throwable handler and
falls back to RawCompression as intended.
@ksugar ksugar merged commit 49bdceb into main Jun 23, 2026
1 check 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.

1 participant