Skip to content

fix(java): repair JNI signatures out of sync with Java native declarations - #587

Open
hogan-yuan wants to merge 1 commit into
mainfrom
fix/java-jni-rank-list-signature
Open

fix(java): repair JNI signatures out of sync with Java native declarations#587
hogan-yuan wants to merge 1 commit into
mainfrom
fix/java-jni-rank-list-signature

Conversation

@hogan-yuan

Copy link
Copy Markdown
Member

Problem

Reported in longbridge/developers#1249: MarketContext.getRankList throws java.lang.RuntimeException: JNI call failed.

Root cause: the Java layer was migrated to an options-object API (getRankList(RankListOptions), SdkNative.marketContextRankList(long, Object, callback)), but the Rust extern "system" JNI function was left in the old positional form (context, key: String, need_article: bool, callback). JNI marshals arguments according to the Java declaration, so the options object landed where a String was expected and the call aborted.

Audit

I audited all 227 SdkNative native declarations against their Rust JNI implementations (hand-written and macro-generated). The same regression class existed in six methods total:

Method Java native decl Rust JNI (stale) Fix
marketContextRankList (long, Object opts, cb) (key, need_article) read key/needArticle from opts
quoteContextShortTrades (long, Object opts, cb) (symbol, count) read symbol/count from opts
screenerContextStrategy (long, Object opts, cb) (id: i64) read id from opts
fundamentalContextShareholderDetail (long, Object opts, cb) (symbol, object_id) read symbol/objectId from opts
fundamentalContextValuationComparison (long, Object opts, cb) (symbol, currency, comparison_symbols) read the three fields from opts
quoteContextShortPositions (long, String, cb) (symbol, count) Java was missing count; added it

The first five: the Rust JNI now reads fields off the options object via get_field (matching the sibling marketContextTopMovers). No public API change.

getShortPositions is different: the Java binding had dropped the count parameter that the Rust core, Node.js and Python bindings all expose (the Rust JNI still expected it, so the call crashed). getShortPositions(String symbol)getShortPositions(String symbol, int count).

The other 221 native methods matched exactly.

Verification

  • cargo build -p longbridge-java clean
  • cargo clippy -p longbridge-java --all-features — no new warnings (6 pre-existing, all in untouched files)
  • cargo +nightly fmt --all --check clean

Docs fix (Java example for getRankList) is in a separate longbridge/developers PR.

…larations

Six JNI methods had a Rust extern "system" signature that no longer
matched the Java native declaration, so every call aborted with
"JNI call failed" (or read misaligned stack arguments):

- getRankList / getShortTrades / getStrategy / shareholderDetail /
  valuationComparison: the Java side was migrated to an options object
  but the Rust JNI still read the old positional args. They now read the
  fields off the opts object via get_field.
- getShortPositions: was missing the count parameter that the Rust core,
  Node.js and Python all require (the Rust JNI still expected it). Added
  count to the Java native decl and getShortPositions signature.

Reported as longbridge/developers#1249 (getRankList).
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