blob: ccf59b7087dade2e6826188ec52e9b2bd6a4bdca [file]
<!DOCTYPE html>
<html lang="en" data-content_root="../" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Development &#8212; Apache DataFusion Java documentation</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
</script>
<!--
this give us a css class that will be invisible only if js is disabled
-->
<noscript>
<style>
.pst-js-only { display: none !important; }
</style>
</noscript>
<!-- Loaded before other Sphinx assets -->
<link href="../_static/styles/theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link href="../_static/styles/pydata-sphinx-theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=8f2a1f02" />
<!-- So that users can add custom icons -->
<script src="../_static/scripts/fontawesome.js?digest=8878045cc6db502f8baf"></script>
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf" />
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf" />
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../_static/doctools.js?v=9a2dae69"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script>DOCUMENTATION_OPTIONS.pagename = 'contributor-guide/development';</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Code style" href="code-style.html" />
<link rel="prev" title="Contributor Guide" href="index.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="en"/>
<meta name="docsearch:version" content="" />
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
<dialog id="pst-search-dialog">
<form class="bd-search d-flex align-items-center"
action="../search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
placeholder="Search the docs ..."
aria-label="Search the docs ..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form>
</dialog>
<div class="pst-async-banner-revealer d-none">
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
<div class="bd-header__inner bd-page-width">
<button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation">
<span class="fa-solid fa-bars"></span>
</button>
<div class="col-lg-3 navbar-header-items__start">
<div class="navbar-item">
<a class="navbar-brand logo" href="../index.html">
<p class="title logo__title">Apache DataFusion Java documentation</p>
</a></div>
</div>
<div class="col-lg-9 navbar-header-items">
<div class="me-auto navbar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion-java">
GitHub Repository
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion-java/issues">
Issue Tracker
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://datafusion.apache.org/">
Apache DataFusion
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion/blob/main/CODE_OF_CONDUCT.md">
Code of Conduct
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="../user-guide/index.html">
User Guide
</a>
</li>
<li class="nav-item dropdown">
<button class="btn dropdown-toggle nav-item" type="button"
data-bs-toggle="dropdown" aria-expanded="false"
aria-controls="pst-nav-more-links">
More
</button>
<ul id="pst-nav-more-links" class="dropdown-menu">
<li class=" current active">
<a class="nav-link dropdown-item nav-internal" href="index.html">
Contributor Guide
</a>
</li>
</ul>
</li>
</ul>
</nav></div>
</div>
<div class="navbar-header-items__end">
<div class="navbar-item navbar-persistent--container">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
</div>
</div>
<div class="navbar-persistent--mobile">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<button class="pst-navbar-icon sidebar-toggle secondary-toggle" aria-label="On this page">
<span class="fa-solid fa-outdent"></span>
</button>
</div>
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<dialog id="pst-primary-sidebar-modal"></dialog>
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar">
<div class="sidebar-header-items sidebar-primary__section">
<div class="sidebar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion-java">
GitHub Repository
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion-java/issues">
Issue Tracker
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://datafusion.apache.org/">
Apache DataFusion
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/apache/datafusion/blob/main/CODE_OF_CONDUCT.md">
Code of Conduct
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="../user-guide/index.html">
User Guide
</a>
</li>
<li class="nav-item current active">
<a class="nav-link nav-internal" href="index.html">
Contributor Guide
</a>
</li>
</ul>
</nav></div>
</div>
<div class="sidebar-header-items__end">
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
</div>
</div>
<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">
<nav class="bd-docs-nav bd-links"
aria-label="Section Navigation">
<p class="bd-links__title" role="heading" aria-level="1">Section Navigation</p>
<div class="bd-toc-item navbar-nav"><ul class="current nav bd-sidenav">
<li class="toctree-l1 current active"><a class="current reference internal" href="#">Development</a></li>
<li class="toctree-l1"><a class="reference internal" href="code-style.html">Code style</a></li>
<li class="toctree-l1"><a class="reference internal" href="releasing.html">Releasing</a></li>
<li class="toctree-l1"><a class="reference internal" href="updating-datafusion-version.html">Updating the DataFusion / protobuf schema version</a></li>
</ul>
</div>
</nav></div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
<div class="sidebar-primary-item">
<div id="ethical-ad-placement"
class="flat"
data-ea-publisher="readthedocs"
data-ea-type="readthedocs-sidebar"
data-ea-manual="true">
</div></div>
</div>
</div>
<main id="main-content" class="bd-main" role="main">
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article d-print-none">
<div class="header-article-items header-article__inner">
<div class="header-article-items__start">
<div class="header-article-item">
<nav aria-label="Breadcrumb" class="d-print-none">
<ul class="bd-breadcrumbs">
<li class="breadcrumb-item breadcrumb-home">
<a href="../index.html" class="nav-link" aria-label="Home">
<i class="fa-solid fa-home"></i>
</a>
</li>
<li class="breadcrumb-item"><a href="index.html" class="nav-link">Contributor Guide</a></li>
<li class="breadcrumb-item active" aria-current="page"><span class="ellipsis">Development</span></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div id="searchbox"></div>
<article class="bd-article">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<section id="development">
<h1>Development<a class="headerlink" href="#development" title="Link to this heading">#</a></h1>
<section id="build-prerequisites">
<h2>Build prerequisites<a class="headerlink" href="#build-prerequisites" title="Link to this heading">#</a></h2>
<ul class="simple">
<li><p>JDK 17 or newer.</p></li>
<li><p>Rust toolchain (stable, installed via <a class="reference external" href="https://rustup.rs/">rustup</a>).</p></li>
<li><p><a class="reference external" href="https://github.com/clflushopt/tpchgen-rs"><code class="docutils literal notranslate"><span class="pre">tpchgen-cli</span></code></a> — only needed to generate test data for the Parquet
integration test (<code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">install</span> <span class="pre">tpchgen-cli</span></code>).</p></li>
</ul>
<p>Maven is bundled via the <code class="docutils literal notranslate"><span class="pre">./mvnw</span></code> wrapper; no separate Maven install is
required.</p>
</section>
<section id="build-and-test">
<h2>Build and test<a class="headerlink" href="#build-and-test" title="Link to this heading">#</a></h2>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>make<span class="w"> </span><span class="nb">test</span>
</pre></div>
</div>
<p>This builds the native Rust crate and runs the JUnit tests. The steps can
be run individually:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>cargo<span class="w"> </span>build<span class="w"> </span>--workspace
./mvnw<span class="w"> </span><span class="nb">test</span>
</pre></div>
</div>
<p>The native library must be built before running JVM tests.</p>
<p>Before pushing, run <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">format</span></code> to apply the Java + Rust formatters in
place. CI verifies formatting, clippy, and license headers on every PR.</p>
<p>The first build in a fresh checkout reaches out to
<code class="docutils literal notranslate"><span class="pre">raw.githubusercontent.com</span></code> to fetch the DataFusion <code class="docutils literal notranslate"><span class="pre">.proto</span></code> files used
to generate the <code class="docutils literal notranslate"><span class="pre">datafusion-proto</span></code> Java classes. Subsequent builds are
offline; the <code class="docutils literal notranslate"><span class="pre">download-maven-plugin</span></code> cache under
<code class="docutils literal notranslate"><span class="pre">~/.m2/repository/.cache/</span></code> satisfies them.</p>
</section>
<section id="test-data">
<h2>Test data<a class="headerlink" href="#test-data" title="Link to this heading">#</a></h2>
<p>The Parquet integration test reads TPC-H SF1 data (~345 MB across 8 tables
in Snappy-compressed Parquet). Generate it once with:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>make<span class="w"> </span>tpch-data
</pre></div>
</div>
<p>Tests that need this data skip cleanly if it is missing. <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">clean</span></code>
does <strong>not</strong> remove <code class="docutils literal notranslate"><span class="pre">tpch-data/</span></code> — delete it manually to reclaim the
disk space.</p>
</section>
<section id="repository-layout">
<h2>Repository layout<a class="headerlink" href="#repository-layout" title="Link to this heading">#</a></h2>
<p>The repository is a multi-module Maven build:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">Cargo.toml</span></code> — Rust workspace root declaring the crate members
(<code class="docutils literal notranslate"><span class="pre">native</span></code>, <code class="docutils literal notranslate"><span class="pre">native-common</span></code>) and <code class="docutils literal notranslate"><span class="pre">[workspace.dependencies]</span></code> that pin
shared versions in one place. Cargo writes artifacts to <code class="docutils literal notranslate"><span class="pre">rust-target/</span></code>
(overridden in <code class="docutils literal notranslate"><span class="pre">.cargo/config.toml</span></code>) so <code class="docutils literal notranslate"><span class="pre">mvn</span> <span class="pre">clean</span></code> at the repo root does
not nuke the Rust build cache.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pom.xml</span></code> — parent POM declaring the <code class="docutils literal notranslate"><span class="pre">core</span></code> and <code class="docutils literal notranslate"><span class="pre">examples</span></code> modules and
shared plugin/dependency versions.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">core/</span></code><code class="docutils literal notranslate"><span class="pre">datafusion-java</span></code> library module (Java sources, tests, and
generated protobuf classes).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">examples/</span></code><code class="docutils literal notranslate"><span class="pre">datafusion-java-examples</span></code> module containing runnable
examples that depend on the library; built alongside the library so they
cannot fall out of sync with the API.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">native/</span></code><code class="docutils literal notranslate"><span class="pre">datafusion-jni</span></code> Rust crate (JNI + Arrow C Data Interface).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">native-common/</span></code><code class="docutils literal notranslate"><span class="pre">datafusion-jni-common</span></code> Rust crate: JNI plumbing
shared across native crates (error→exception mapping, the per-cdylib
Tokio runtime singleton, the async-stream→<code class="docutils literal notranslate"><span class="pre">FFI_ArrowArrayStream</span></code> bridge).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">proto/</span></code> — Protobuf definitions shared between Java and Rust.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Makefile</span></code> — top-level build orchestration (<code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">test</span></code>, <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">format</span></code>,
<code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">tpch-data</span></code>).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mvnw</span></code>, <code class="docutils literal notranslate"><span class="pre">mvnw.cmd</span></code> — bundled Maven wrapper.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">docs/</span></code> — Sphinx documentation source and build scripts.</p></li>
</ul>
</section>
<section id="running-an-example">
<h2>Running an example<a class="headerlink" href="#running-an-example" title="Link to this heading">#</a></h2>
<p>The examples module wires <code class="docutils literal notranslate"><span class="pre">exec-maven-plugin</span></code> with the right
<code class="docutils literal notranslate"><span class="pre">java.library.path</span></code> and <code class="docutils literal notranslate"><span class="pre">--add-opens</span></code> flags. Install the library to the
local Maven repository once, then run any example by main class:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>./mvnw<span class="w"> </span>install<span class="w"> </span>-DskipTests
./mvnw<span class="w"> </span>-pl<span class="w"> </span>:datafusion-java-examples<span class="w"> </span>exec:exec<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-Dexec.mainClass<span class="o">=</span>org.apache.datafusion.examples.SqlQueryExample
</pre></div>
</div>
<p>The bundled examples (under
<code class="docutils literal notranslate"><span class="pre">examples/src/main/java/org/apache/datafusion/examples/</span></code>):</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">SqlQueryExample</span></code> — register a CSV and run a SQL aggregation.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">DataFrameExample</span></code> — read CSV → filter / select / rename / distinct →
write Parquet → read back.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ProtoPlanExample</span></code> — build a DataFusion <code class="docutils literal notranslate"><span class="pre">LogicalPlanNode</span></code> directly via
the generated protobuf classes and execute it through
<code class="docutils literal notranslate"><span class="pre">SessionContext.fromProto</span></code>.</p></li>
</ul>
<p>Re-run <code class="docutils literal notranslate"><span class="pre">mvnw</span> <span class="pre">install</span> <span class="pre">-DskipTests</span></code> whenever you change the library.</p>
</section>
<section id="passing-structured-options-across-the-jni-boundary">
<h2>Passing structured options across the JNI boundary<a class="headerlink" href="#passing-structured-options-across-the-jni-boundary" title="Link to this heading">#</a></h2>
<p>When a JNI call needs to carry more than a handful of scalar arguments —
for example, a struct of nullable knobs like <code class="docutils literal notranslate"><span class="pre">CsvReadOptions</span></code> or
<code class="docutils literal notranslate"><span class="pre">SessionOptions</span></code> — encode the call’s configuration as a protobuf message
rather than expanding the JNI signature with one parameter per field.</p>
<p>Add a <code class="docutils literal notranslate"><span class="pre">.proto</span></code> file under <code class="docutils literal notranslate"><span class="pre">proto/</span></code>, declare <code class="docutils literal notranslate"><span class="pre">package</span> <span class="pre">datafusion_java;</span></code>,
and follow the conventions already in use:</p>
<ul class="simple">
<li><p>One message per logical bundle of options.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">optional</span></code> for fields whose unset-ness must survive the boundary
(so the Rust side can leave a DataFusion default in place).</p></li>
<li><p>Use proto enums for closed sets of choices instead of strings.
Prefix every value with the enum’s name (e.g.
<code class="docutils literal notranslate"><span class="pre">FILE_COMPRESSION_TYPE_GZIP</span></code>, not bare <code class="docutils literal notranslate"><span class="pre">GZIP</span></code>) because proto3 enum
values are scoped at the package level, and the zero value must be a
<code class="docutils literal notranslate"><span class="pre">_UNSPECIFIED</span></code> sentinel — the Rust side should reject <code class="docutils literal notranslate"><span class="pre">UNSPECIFIED</span></code>
rather than silently default it.</p></li>
<li><p>Keep large opaque payloads (Arrow IPC schemas, plan nodes) as separate
<code class="docutils literal notranslate"><span class="pre">byte[]</span></code> JNI arguments next to the options proto, not inside it.</p></li>
<li><p>Suffix the message name with <code class="docutils literal notranslate"><span class="pre">Proto</span></code> if a sibling Java class would
otherwise shadow it (e.g. <code class="docutils literal notranslate"><span class="pre">CsvReadOptionsProto</span></code> vs the public
<code class="docutils literal notranslate"><span class="pre">CsvReadOptions</span></code>).</p></li>
</ul>
<p>The proto is compiled by both <code class="docutils literal notranslate"><span class="pre">prost-build</span></code> (Rust, via <code class="docutils literal notranslate"><span class="pre">native/build.rs</span></code>)
and the Maven <code class="docutils literal notranslate"><span class="pre">protobuf-maven-plugin</span></code> (Java). The Java side builds the
message, serializes to bytes, and passes the byte array through JNI; the
Rust side decodes once and folds the fields into the corresponding
DataFusion struct.</p>
<p>This pattern keeps JNI signatures short, makes nullable and enum fields
explicit in a single typed schema, and lets new fields be added without
touching the signature on either side.</p>
</section>
</section>
</article>
<footer class="prev-next-footer d-print-none">
<div class="prev-next-area">
<a class="left-prev"
href="index.html"
title="previous page">
<i class="fa-solid fa-angle-left"></i>
<div class="prev-next-info">
<p class="prev-next-subtitle">previous</p>
<p class="prev-next-title">Contributor Guide</p>
</div>
</a>
<a class="right-next"
href="code-style.html"
title="next page">
<div class="prev-next-info">
<p class="prev-next-subtitle">next</p>
<p class="prev-next-title">Code style</p>
</div>
<i class="fa-solid fa-angle-right"></i>
</a>
</div>
</footer>
</div>
<dialog id="pst-secondary-sidebar-modal"></dialog>
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> On this page
</div>
<nav class="bd-toc-nav page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#build-prerequisites">Build prerequisites</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#build-and-test">Build and test</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#test-data">Test data</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#repository-layout">Repository layout</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#running-an-example">Running an example</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#passing-structured-options-across-the-jni-boundary">Passing structured options across the JNI boundary</a></li>
</ul>
</nav></div>
<div class="sidebar-secondary-item">
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/contributor-guide/development.md.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div></div>
</div></div>
</div>
<footer class="bd-footer-content">
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script defer src="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf"></script>
<script defer src="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf"></script>
<footer class="bd-footer">
<div class="bd-footer__inner bd-page-width">
<div class="footer-items__start">
<div class="footer-item">
<p class="copyright">
© Copyright 2026, Apache Software Foundation.
<br/>
</p>
</div>
<div class="footer-item">
<p class="sphinx-version">
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.4.7.
<br/>
</p>
</div>
</div>
<div class="footer-items__end">
<div class="footer-item">
<p class="theme-version">
<!-- # L10n: Setting the PST URL as an argument as this does not need to be localized -->
Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.16.1.
</p></div>
</div>
</div>
</footer>
</body>
</html>