Skip to content

Use Foreign Memory API, introduced in Java 22 #12809

@gortiz

Description

@gortiz

This is a sibling of #12810

TL;DR:

Create a new buffer implementation that uses official Java Foreign Memory API. See JEP-454.

As a requirement, this addition should:

  • Not assume Pinot is compiled with Java 21 or 22
  • Not be loaded if:
    • Option 1 (safer): The runtime is <= 21
    • Option 2: The runtime is <= 20 or equal to 21 and preview is not enabled.

Context

As we may know Java buffers length has been limited to 2GBs. In Apache Pinot we decided to skip that limit by using LArray, a third party buffer library that uses JNI to create larger buffers. That library is not maintained anymore (see xerial/larray#75 (comment) or https://github.com/xerial/larray/issues/80).\

This library has several problems, including:

  • It may produce segmentation faults or buffer overflows (there is no index check when using it).
  • It doesn't work in Mac using arm architecture.
  • It doesn't support Java >= 15.

In order to solve these problems, we introduced a new buffer implementation called unsafe. The name comes from the fact that uses sun.misc.Unsafe, but AFAIK it is safer than LArray. It works and that is what we use by default if at runtime we detect we are using Java >= 15.

But in March 2024, Java 22 was released. This new Java version includes JEP-454 Foreign Memory API, which includes new APIs that solve the original issue (be able to index buffers with 64 bits) while providing a more modern, safer, tested and stable API.

When I've added unsafe buffers, I've also tried Foreign Memory API (in preview state) and it was super simple to create a buffer implementation with that. The single problem I had was maven related. Given this API can only be used in Java 22 (or maybe 21 if preview features are enabled), we can only compile that code with that Java version and we need to be sure that code is not loaded if Java < 21 is used. At the time I didn't had time to deal with these two issues and therefore I'm creating this issue as a reminder for my future self or, alternative, as a birdcall in case someone else wants to learn more about Maven and/or Foreign Memory APi.

Proposed solution

  • Create a new Maven sub-project
  • Only compile sources of this project when using Java 22 by setting a default profile where Java sources are empty
  • This project should use multi release versions, adding the sources under Java version 22. By doing that we can be sure code that runs with Java <= 21 do not see these classes.
  • Be sure we publish this project to Maven (usually we publish code compiled with Java 11)

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomers — GitHub surfaces this in the Contribute tabhelp wantedExtra attention is needed — open for contributions

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions