Skip to content

fix(native): register every jsbml tree node for reflection (0.0.24) - #31

Merged
jcschaff merged 3 commits into
mainfrom
fix/jsbml-tostring-reflection
Oct 25, 2026
Merged

jcschaff merged 3 commits into
mainfrom
fix/jsbml-tostring-reflection

Conversation

@jcschaff

Copy link
Copy Markdown
Member

Why

In compose-api's biomodels-curated-300 run 3, six models failed in sbml_to_vcml with this error:

MissingReflectionRegistrationError: The program tried to reflectively invoke method
   public boolean org.sbml.jsbml.Annotation.isSetAbout()

The models were BIOMD 56, 94, 150, 168, 169 and 192. The stack trace runs through SBMLReader → XMLNodeReader.processNamespace → MessageFormat.format → AbstractTreeNode.toString.

jsbml formats its debug messages eagerly, even when debug logging is off. When <annotation> declares a namespace, the message's context object is the Annotation. AbstractTreeNode.toString() then reflects over its isSet*/get*/set* methods and fields. The native image only registers what MainRecorder's run reaches, and its models never take that path.

What

  • The config: vcell-native/src/main/native-image/jsbml/reachability-metadata.json registers allDeclaredMethods, allPublicMethods and allDeclaredFields for every jsbml tree node class, 127 of them, core and spatial.
  • The generator: scripts/JsbmlReflection.java writes the file from the jsbml jar. Regenerate it when the jsbml version changes.
  • The build: both native profiles read it with the recording (-H:ConfigurationFileDirectories=target/recording,src/main/native-image/jsbml).
  • The test: test_sbml_to_vcml_with_an_annotation_namespace is a 10-line model with <annotation xmlns:jd=…>. It fails on 0.0.23 with the error above.
  • Version: bumped to 0.0.24.

Checked (macOS arm64, GraalVM 23.0.2)

  • The minimal model and BIOMD 56, 94, 150, 168, 169, 192: all failed on 0.0.23, and all import with the rebuilt library.
  • pytest tests: 26 passed, 4 skipped.

🤖 Generated with Claude Code

jcschaff and others added 3 commits October 25, 2026 01:41
jsbml's AbstractTreeNode.toString() reflects over a node's isSet*/get*/set*
methods and fields, and jsbml calls it while formatting debug messages even
when debug logging is off: XMLNodeReader.processNamespace formats its context
object, an Annotation, whenever <annotation> declares a namespace. The native
library only had what MainRecorder's run reached, so sbml_to_vcml failed with
MissingReflectionRegistrationError for Annotation.isSetAbout() on such models
(BioModels 56, 94, 150, 168, 169, 192 in compose-api's biomodels-curated-300).

A checked-in reachability-metadata.json, generated by
scripts/JsbmlReflection.java from the jsbml jar, registers the declared and
public methods and declared fields of all 127 jsbml tree node classes, and the
native build reads it with the recording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jcschaff
jcschaff merged commit d488c00 into main Oct 25, 2026
5 checks 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