GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(#261): support heap (address-less) ByteBuf in ByteBufProxy.in() by bernardladenthin · Pull Request #291 · lmdbjava/lmdbjava

Conversation

@bernardladenthin

@bernardladenthin bernardladenthin commented Jul 24, 2026

Copy link
Copy Markdown

Addresses the concrete, reproducible failure behind #261.

Root cause (verified)

ByteBufProxy.in() called buffer.memoryAddress() unconditionally. That throws UnsupportedOperationException for any ByteBuf with hasMemoryAddress() == false — i.e. any heap buffer:

java.lang.UnsupportedOperationException
    at io.netty.buffer.PooledHeapByteBuf.memoryAddress(...)
    at org.lmdbjava.ByteBufProxy.in(ByteBufProxy.java:201)
    at org.lmdbjava.Dbi.put(...)

Netty 4.2's adaptive allocator can hand back heap-backed AdaptiveByteBuf instances (e.g. heapBuffer()), so 4.2 apps trip this — but it is not 4.2-specific: a plain PooledHeapByteBuf fails identically on 4.1. So the fix targets the underlying issue and applies on both.

Fix

When the buffer has no memory address, copy its readable bytes into native scratch (MemoryManager.allocateDirect) and point the MDB_val there, returning the Pointer so lmdbjava keeps the scratch reachable for the native call — the same pattern ByteArrayProxy.in() already uses. Direct buffers keep the zero-copy fast path unchanged.

The reserve variant in(buffer, size, ptr) can't support heap buffers (its out() repoints the caller's buffer at LMDB memory via a PooledUnsafeDirectByteBuf field swap, which requires a direct buffer), so it now throws a clear LmdbException instead of an opaque UnsupportedOperationException.

What this does NOT do (deliberately)

It does not touch allocate()'s exact-class check or out()'s zero-copy field swap. During investigation I could not reproduce the report's stated mechanism — "allocate() gets AdaptivePoolingAllocator$AdaptiveByteBuf": PROXY_NETTY pins PooledByteBufAllocator, which still returns PooledUnsafeDirectByteBuf on 4.2, and the full suite passes on 4.2 (verified locally, 918/918). So that part of the writeup appears inaccurate; I've asked on the issue for a concrete stack trace in case there's a different failure to address separately.

Tests

ByteBufHeapBufferTest — heap value round-trip, and heap key+value round-trip (both put and lookup). Full suite green; fmt-maven-plugin:check clean. No change to the direct-buffer fast path.

Refs #261.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bernardladenthin @claude
fix(lmdbjava#261): support heap (address-less) ByteBuf in ByteBufProx…
421b52b
…y.in()

ByteBufProxy.in() called buffer.memoryAddress() unconditionally, which throws
UnsupportedOperationException for any ByteBuf without a native address
(hasMemoryAddress()==false) — i.e. any heap buffer. Netty 4.2's adaptive allocator
can hand back heap-backed AdaptiveByteBuf instances (e.g. heapBuffer()), so apps on
4.2 hit this; but it is not 4.2-specific — a plain PooledHeapByteBuf fails identically
on 4.1.

Fix: when the buffer has no memory address, copy its readable bytes into native
scratch (MemoryManager.allocateDirect) and point the MDB_val there, returning the
Pointer so lmdbjava keeps the scratch reachable for the native call. This mirrors the
existing ByteArrayProxy.in() copy path. Direct buffers keep the zero-copy fast path
unchanged (in()'s null return).

The reserve variant in(buffer, size, ptr) cannot support heap buffers (out() repoints
the caller's buffer at LMDB memory via a PooledUnsafeDirectByteBuf field swap, which
needs a direct buffer), so it now throws a clear LmdbException instead of an opaque
UnsupportedOperationException.

Note: this fixes the concrete, reproducible failure in lmdbjava#261. It deliberately does NOT
touch allocate()'s exact-class check or out()'s zero-copy field swap; the report's
claim that allocate() receives an AdaptiveByteBuf is not reproducible (PROXY_NETTY
pins PooledByteBufAllocator, which still yields PooledUnsafeDirectByteBuf on 4.2, and
the full suite passes on 4.2).

Tests: ByteBufHeapBufferTest (heap value; heap key+value round-trip). Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01GdiZ3ABYsVHXBRNCkEizpE
@bernardladenthin bernardladenthin mentioned this pull request Jul 24, 2026
Netty 4.2 series and the adaptive allocator. #261
Open
@bernardladenthin bernardladenthin mentioned this pull request Oct 14, 2026
Fix #215: correct NIO buffer for Netty ByteBuf reads (nioBufferView + nioBufferCopy) #290
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@bernardladenthin
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.