Skip to content

feat(java): support session#5931

Merged
jackye1995 merged 4 commits intolance-format:mainfrom
jackye1995:java-session
Feb 11, 2026
Merged

feat(java): support session#5931
jackye1995 merged 4 commits intolance-format:mainfrom
jackye1995:java-session

Conversation

@jackye1995
Copy link
Copy Markdown
Contributor

This allows Java to also pass in a Session shared across datasets similar to python and rust. Session can then be used for engine side caching implementation in Spark and Trino

@github-actions github-actions Bot added enhancement New feature or request java labels Feb 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Code Review: feat(java): support session

P0 Issues

Memory leak in Session.fromHandle() (java/src/main/java/org/lance/Session.java:687-690)

When Dataset.session() is called, it invokes nativeGetSessionHandle() which calls handle_from_session() in Rust. This function creates a new Box<Arc<LanceSession>> every time:

pub fn handle_from_session(session: Arc<LanceSession>) -> jlong {
    let boxed: Box<Arc<LanceSession>> = Box::new(session);
    Box::into_raw(boxed) as jlong
}

The Java side then wraps this in a new Session object via Session.fromHandle(handle). However, this creates a new handle that is never released unless the user explicitly closes the returned Session object. The Dataset.session() method caches this internally, but:

  1. If session() is called and the returned Session is not closed, the handle leaks
  2. The cached session in Dataset is never closed when the dataset is closed

Recommendation: Either:

  • Document that users must close the session returned by Dataset.session() (breaking typical Java patterns)
  • Have Dataset.close() also close the cached session if it was created from a handle
  • Change the design to track whether the Session owns its handle or is just referencing it

P1 Issues

Default cache size mismatch (java/src/main/java/org/lance/Session.java:589-593)

public static final long DEFAULT_INDEX_CACHE_SIZE_BYTES = 1L * 1024 * 1024 * 1024;  // 1 GiB
public static final long DEFAULT_METADATA_CACHE_SIZE_BYTES = 256L * 1024 * 1024;    // 256 MiB

But Rust defaults (rust/lance/src/dataset.rs:141-145):

pub const DEFAULT_INDEX_CACHE_SIZE: usize = 6 * 1024 * 1024 * 1024;    // 6 GiB
pub const DEFAULT_METADATA_CACHE_SIZE: usize = 1024 * 1024 * 1024;      // 1 GiB

And ReadOptions.Builder defaults (java/src/main/java/org/lance/ReadOptions.java:103-104):

private long indexCacheSizeBytes = 6L * 1024 * 1024 * 1024;    // 6 GiB
private long metadataCacheSizeBytes = 1024L * 1024 * 1024;      // 1 GiB

The Session defaults are inconsistent with both Rust and ReadOptions. Consider aligning them.


The test coverage is good, and the overall approach of exposing Session to Java is sound. The main concern is the potential memory leak from handles created via Dataset.session().

@jackye1995 jackye1995 requested a review from majin1102 February 11, 2026 06:39
Copy link
Copy Markdown
Contributor

@majin1102 majin1102 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left one non-blocking comment

if (session == null) {
long handle = nativeGetSessionHandle();
if (handle != 0) {
session = Session.fromHandle(handle);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might cause dangling references without write lock. That said, Rust's structures are shared and close() seems to work fine. Up to you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, I updated to just load it at build time

@jackye1995 jackye1995 merged commit 6deadb8 into lance-format:main Feb 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request java

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants