Summary
-------
bson 5.2.0 fails to load on JRuby 10.1.1.0 with a Java InstantiationError,
raised from the native extension's ByteBuf#getLength implementation.
Environment
-----------
- bson gem version: 5.2.0
- JRuby version: 10.1.1.0
- Java version: OpenJDK Temurin 25.0.4 (also reproduced with other JDK 21+ builds)
- OS: Windows
- Rails version: 7.2.3.2
Steps to reproduce
-------------------
1. Install JRuby 10.1.1.0 on a machine with Java 21+.
2. In a Rails app with `gem "bson", "5.2.0"` in the Gemfile, run `rails s`
(or simply `require "bson"` from a jruby console).
3. Observe the exception below during class loading / eager load.
Stack trace (relevant excerpt)
-------------------------------
Unhandled Java exception: java.lang.InstantiationError: org.jruby.RubyFixnum
java.lang.InstantiationError: org.jruby.RubyFixnum
getLength at org/bson_ruby/ByteBuf.java:156
call at org/bson_ruby/ByteBuf$INVOKER$i$0$0$getLength.gen:-1
cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:442
...
(full trace available on request)
Suspected root cause
---------------------
JRuby 10.1 refactored its internal Fixnum representation, splitting the
previously concrete `org.jruby.RubyFixnum` class into two subclasses,
`LongFixnum` and `ShortFixnum`, as part of an object-size/performance
optimization. `RubyFixnum` itself is no longer directly instantiable.
ByteBuf.java (in bson's native extension) appears to construct a
`RubyFixnum` directly (`new RubyFixnum(...)`) rather than obtaining an
Integer instance via the runtime factory method (e.g.
`getRuntime().newFixnum(...)`), which is the JRuby-recommended, ABI-stable
way to create Ruby Integer objects from Java extension code. Direct
construction breaks once `RubyFixnum` is no longer a concrete,
directly-instantiable class.
Notes
- This does not reproduce on JRuby 10.0.x (10.0.6.0 tested), which does not
include the RubyFixnum/LongFixnum/ShortFixnum split. - Not related to JDK/Java version — reproduces regardless of which Java
21+ build is used as the host JVM.
Suggested fix
-------------
Update ByteBuf.java (and any other native extension code constructing
RubyFixnum directly) to use the runtime's public factory API for creating
Integer values, instead of instantiating RubyFixnum's constructor directly.