This is an automated email from the ASF dual-hosted git repository. afs pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit d6d1735f17e32ceee5b040f4663bccc63eb689f5 Author: shah <[email protected]> AuthorDate: Thu Jul 23 21:52:04 2026 +0200 GH-4084: Fix ByteBufferPool sizing in Fuseki's Jetty Server Fuseki builds its Jetty Server with new Server(threadPool), which wires in a default ArrayByteBufferPool capped at 64KB. Fuseki configures a 5MB outputBufferSize, so output buffers exceed the pool's max capacity and are discarded on release instead of reused, causing continuous DirectMemory churn under load. Fixed in JettyServer.jettyServer(...), the shared factory both JettyHttps.java and FusekiServer.java call, so neither file needs changes. Constructs an ArrayByteBufferPool sized to FusekiSystemConstants.jettyOutputBufferSize and passes it into Server(ThreadPool, Scheduler, ByteBufferPool) at construction time, since adding the pool via addBean() afterward has no effect (the default pool is already wired in during construction). --- .../main/java/org/apache/jena/fuseki/main/JettyServer.java | 12 +++++++++++- .../org/apache/jena/fuseki/main/TestFusekiServerBuild.java | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/JettyServer.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/JettyServer.java index f38ea4e15b..f7d94dc1fa 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/JettyServer.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/JettyServer.java @@ -50,6 +50,8 @@ import org.eclipse.jetty.ee11.servlet.FilterHolder; import org.eclipse.jetty.ee11.servlet.ServletContextHandler; import org.eclipse.jetty.ee11.servlet.ServletHolder; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.io.ArrayByteBufferPool; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ErrorHandler; @@ -472,10 +474,18 @@ public class JettyServer { maxThreads = Math.max(minThreads, maxThreads); // Args reversed: Jetty uses (max,min) threadPool = new QueuedThreadPool(maxThreads, minThreads); - Server server = new Server(threadPool); + // Server(ThreadPool) alone installs a default 64KB ArrayByteBufferPool; pass ours explicitly. + Server server = new Server(threadPool, null, newByteBufferPool()); return server; } + /** ByteBufferPool sized so its maximum pooled buffer capacity is at least + * {@link FusekiSystemConstants#jettyOutputBufferSize}. */ + private static ByteBufferPool newByteBufferPool() { + int maxCapacity = FusekiSystemConstants.jettyOutputBufferSize; + return new ArrayByteBufferPool(0, 2048, maxCapacity, -1, -1, -1); + } + private static void serverAddConnectors(Server server, int port, boolean loopback) { HttpConfiguration httpConnectionFactory = JettyLib.httpConfiguration(); HttpConnectionFactory f1 = new HttpConnectionFactory(httpConnectionFactory); diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiServerBuild.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiServerBuild.java index a254704c80..24cc9e325f 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiServerBuild.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiServerBuild.java @@ -54,8 +54,11 @@ import org.apache.jena.sparql.exec.RowSet; import org.apache.jena.sparql.exec.http.GSP; import org.apache.jena.sparql.exec.http.QueryExecHTTP; import org.apache.jena.sparql.sse.SSE; +import org.apache.jena.fuseki.main.sys.FusekiSystemConstants; import org.apache.jena.system.Txn; import org.apache.jena.update.UpdateExecution; +import org.eclipse.jetty.io.ArrayByteBufferPool; +import org.eclipse.jetty.server.Server; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -85,6 +88,14 @@ public class TestFusekiServerBuild { } finally { server.stop(); } } + @Test public void fuseki_build_byte_buffer_pool() { + FusekiServer server = FusekiServer.create().port(0).build(); + Server jettyServer = server.getJettyServer(); + ArrayByteBufferPool pool = jettyServer.getBean(ArrayByteBufferPool.class); + assertNotNull(pool); + assertTrue(pool.getMaxCapacity() >= FusekiSystemConstants.jettyOutputBufferSize); + } + // The port in "testing/jetty.xml" is 1077 @Test public void fuseki_ext_jetty_xml_1() {
