Repository navigation
Load the HDF5 JNI library before enum constants read HDF5Constants - #14
Conversation
The public enums FileFormatVersion, HDF5DataClass, HDF5StorageLayout, HDF5EnumerationType.EnumStorageForm and CharacterEncoding initialize their constants from HDF5Constants. Touching any of them, or anything that does (FileFormatVersionBounds, the *StorageFeatures classes, switch statements over them), before HDF5Factory, HDF5FactoryProvider or HDFHelper initialized HDF5Constants before HDF5NativeLibrary.load() ran. H5's static initializer then failed for good, and every later HDF5 call failed with UnsatisfiedLinkError: 'int hdf.hdf5lib.H5.H5dont_atexit()'. This is what failed 306 tests on macOS once NativeLibraryBootstrap was removed (HDF5ArchiverTest touches FileFormatVersionBounds first); Linux only passed because of a different test order. Enum constants are created before any static initializer of their enum and their arguments are evaluated before their constructor, so they now read HDF5 constants through HDF5NativeLibrary.intConstant/longConstant, which call load() first. Also, in HDF5NativeLibrary.load(): - only mark the library as loaded once that succeeded, so a failure (e.g. no natives for the platform) is reported to the next caller again instead of surfacing as the UnsatisfiedLinkError above; - don't set the property to null when Loader.load() returns null (JavaCPP's library loading disabled), which threw. Checked by initializing each of the 1104 classes in the jar first, in a fresh JVM, and then writing a file through HDF5Factory: 15 classes failed before this change, none after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Windows CI: what's left, and how to check it on a Windows machineAll 300 Windows test failures here (Java 8 and 21) come from one cause: 1. Build #1814 and install it into the local Maven repositoryPrerequisites (the same as
Expected: 2. Make sure the local build is the one that gets usedThis installs It must say Optionally confirm that only one HDF5 is involved: 3. Run janelia-jhdf5's suite against it
If other failures remain, they're Windows-specific behaviour that the shared-library error has been hiding until now. Triage them like this:
4. Downstream check (optional)saalfeldlab/n5-hdf5#50 against the result:
On macOS this gives 47 tests, 5 skipped, the same as n5-hdf5 5. After #1814 is mergedbytedeco publishes a new snapshot from 🤖 Generated with Claude Code |
Windows verification against bytedeco/javacpp-presets#1814: passesI ran the steps from the earlier comment on a Windows 11 x64 machine. janelia-jhdf5's suite passes with no 1. Preset build
2. Local build was the one used
3. janelia-jhdf5 tests
ConclusionWith #1814, the single-HDF5-copy problem (bytedeco/javacpp-presets#1813) is resolved for this suite on Windows. Once a snapshot containing #1814 is published, rerun this PR's CI and drop Not tested: the n5-hdf5 downstream check (step 4). 🤖 Generated with Claude Code |
Windows follow-up: remaining checks also passFollow-up to my earlier comment, using the same locally built #1814 preset (
The earlier JDK 17 runs on The logs show no Not testable here
Still to do after #1814 mergesRerun this PR's CI against the new snapshot, and if Windows passes, drop 🤖 Generated with Claude Code |
Merges, via the top of the stack, PRs #1 through #19: HDF5 2.2.0 via org.bytedeco:hdf5 (#1, #2), vendored cisd:base (#3-#7), the upstream TestNG suite and fixes (#8, #9, #12, #15), CI (#10, #16), hdf5-platform (#11), native-library loading (#13, #14), imported cisd:base tests (#17), README (#18) and benchmarks (#19). Each PR's commits are preserved.
n5-hdf5 is the first consumer of janelia-jhdf5 and exercises its public API from a separate project, including loading the native library from library code (JaneliaSciComp#13/JaneliaSciComp#14), which this project's own tests can't check. The new job installs the build, checks out n5-hdf5's janelia-jhdf5 branch (saalfeldlab/n5-hdf5#50) and runs its tests against that version, on the same OS/Java matrix as the main tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stacked on #13. The base branch
load-libraryis a copy of #13's commit (04a2568) pushed to this repository, since a pull request here can't use a branch from a fork as its base. When #13 is merged, this can be retargeted to #13's base.Problem
#13 calls
HDF5NativeLibrary.load()from the static initializers ofHDF5Factory,HDF5FactoryProviderandHDFHelper. That covers programs whose first contact with JHDF5 is one of those classes. Five public enums initialize their constants fromHDF5Constants, though:IHDF5WriterConfigurator.FileFormatVersionHDF5DataClassHDF5StorageLayoutHDF5EnumerationType.EnumStorageFormCharacterEncodingWhat goes wrong. Touching any of these first initializes
HDF5Constantsbeforeload()runs. The same applies to anything that uses them:FileFormatVersionBounds, the*StorageFeaturesclasses, and switch statements over them.HDF5Constantsthen runsH5.loadH5Lib(), which can't findhdf5_java, andH5's class initialization fails. A failed class initialization is permanent in Java, so every later HDF5 call in the process fails too, even throughHDF5Factory:Evidence.
HDF5ArchiverTesttouchesFileFormatVersionBoundsbefore any factory. Linux passes only because its test classes happen to run in a different order. The test-onlyNativeLibraryBootstrapthat load H5's JNI library from the main code #13 removes used to hide this.CharacterEncoding.UTF8and then callsHDF5Factory.open(...)fails the same way.Fix
load()call inside the enum would come too late. Instead, the constants read HDF5 values through two new helpers,HDF5NativeLibrary.intConstant(...)andlongConstant(...), which callload()first:HDF5NativeLibrary.load():UnsatisfiedLinkErrorabove.System.setProperty(..., null), which throws, whenLoader.load()returnsnull(JavaCPP's library loading disabled).Verification (macOS arm64, local)
HDF5Factory. 15 failed on load H5's JNI library from the main code #13, 0 with this PR. The 15 were the five enums above plus classes that use them.mvn testpasses 2 runs of 2 with JaCoCo, withoutNativeLibraryBootstrap.masterbaseline. TheCharacterEncoding-first program now works.🤖 Generated with Claude Code