Skip to main content

6.0.0 Milestone 1

RDF4J 6.0.0-M1 is the first Milestone build of the upcoming 6.0.0 release of RDF4J.

RDF4J 6.0.0 is a major release of the RDF4J framework.

Some of the highlights covered in this first milestone:

  • Upgrade to Java 25 as the minimally-required version of Java
  • Introduction of a pluggable HTTP client SPI with Apache HttpComponents 5 and JDK built-in backends
  • Migration from Apache HttpComponents 4 to the new HTTP client facade

This milestone build is not yet feature-complete, but we are putting it out to receive early feedback on all the improvements we have put in.

Upgrade notes

RDF4J 6.0.0 contains several backward incompatible changes.

HTTP client migration (Apache HttpComponents 4 removed)

RDF4J previously used Apache HttpComponents 4 (AHC4) as its sole HTTP client, with AHC4 types directly exposed in the public API. In 6.0.0, this dependency has been replaced by a new HTTP-client-agnostic facade. Apache HC4 is no longer exposed through the rdf4j-http-client public API or required as a transitive dependency of rdf4j-http-client for standard use.

User-facing changes

No dependency changes required for most users. The rdf4j-http-client artifact continues to bundle both built-in backend implementations as runtime dependencies, so upgrading the RDF4J version is sufficient for standard use cases.

Two HTTP client backends are now available:

  • Apache HttpComponents 5 (rdf4j-http-client-apache5) — the default backend when on the classpath.
  • JDK built-in HTTP client (rdf4j-http-client-jdk) — a zero-dependency alternative using the JDK 11+ java.net.http.HttpClient API; RDF4J 6.0.0 itself requires Java 25.

To select a specific backend, set the system property rdf4j.http.client.factory to either apache5 or jdk:

-Drdf4j.http.client.factory=jdk

If you previously configured connection pooling or timeouts via system properties on SharedHttpClientSessionManager, those properties are still supported:

  • org.eclipse.rdf4j.client.http.maxConnPerRoute (default: 25)
  • org.eclipse.rdf4j.client.http.maxConnTotal (default: 50)
  • org.eclipse.rdf4j.client.http.connectionTimeout (default: 30 000 ms)
  • org.eclipse.rdf4j.client.http.connectionRequestTimeout

If you need a minimal-footprint deployment without Apache HC5, exclude rdf4j-http-client-apache5 and ensure rdf4j-http-client-jdk is on the classpath.

Developer-facing changes

Removed public API: Apache HC4 types

The following methods previously exposed org.apache.http.client.HttpClient (AHC4) in the public API and have been replaced (GH-5723):

Old methodReplacement
HttpClientDependent#getHttpClient() returns org.apache.http.client.HttpClientReturns org.eclipse.rdf4j.http.client.spi.RDF4JHttpClient
HttpClientDependent#setHttpClient(HttpClient)Accepts org.eclipse.rdf4j.http.client.spi.RDF4JHttpClient
HttpClientSessionManager#getHttpClient() returns org.apache.http.client.HttpClientReturns org.eclipse.rdf4j.http.client.spi.RDF4JHttpClient

If your code calls setHttpClient() with a custom Apache HC4 client, you must migrate to the new API (see below).

New HTTP client SPI (rdf4j-http-client-api)

A new module, rdf4j-http-client-api, defines the HTTP client facade with no third-party HTTP dependencies. The key types are:

  • RDF4JHttpClientFactory — SPI interface discovered via java.util.ServiceLoader. Implement this to plug in a custom HTTP backend.
  • RDF4JHttpClient — the HTTP client interface used internally by SPARQLProtocolSession and RDF4JProtocolSession.
  • RDF4JHttpClientConfig — immutable configuration object (timeouts, connection pooling, SSL, default headers), constructed via a builder.
  • RDF4JHttpClients — utility class for obtaining the default factory or creating clients.

Configuring the HTTP client programmatically

Use RDF4JHttpClientConfig and RDF4JHttpClients to create a configured client and pass it to a repository or session:

RDF4JHttpClientConfig config = RDF4JHttpClientConfig.newBuilder()
        .connectTimeoutMs(5_000)
        .socketTimeoutMs(30_000)
        .maxConnectionsPerRoute(10)
        .build();

RDF4JHttpClient client = RDF4JHttpClients.newDefaultClient(config);

HTTPRepository repo = new HTTPRepository("http://localhost:8080/rdf4j-server/repositories/myrepo");
repo.setHttpClient(client);

SSL configuration

The previous HttpClientBuilders.getSSLTrustAllHttpClientBuilder() helper (which returned an AHC4 builder) has been replaced by HttpClientBuilders.getSslTrustAllConfig(), which returns an RDF4JHttpClientConfig:

// Old (AHC4, removed):
// HttpClient client = HttpClientBuilders.getSSLTrustAllHttpClientBuilder().build();

// New:
RDF4JHttpClientConfig config = HttpClientBuilders.getSslTrustAllConfig();
RDF4JHttpClient client = RDF4JHttpClients.newDefaultClient(config);
repo.setHttpClient(client);

Authentication

Authentication is now handled via the AuthenticationHandler SPI rather than Apache HC4 credential stores. Two built-in implementations are provided:

  • BasicAuthenticationHandler — adds an Authorization: Basic <base64> header to every request.
  • BearerTokenAuthenticationHandler — adds an Authorization: Bearer <token> header, with optional support for a dynamic token producer to handle short-lived tokens (e.g. OAuth).
// Basic auth
session.setAuthenticationHandler(new BasicAuthenticationHandler("user", "secret"));

// Bearer token (static)
session.setAuthenticationHandler(new BearerTokenAuthenticationHandler("my-token"));

// Bearer token (dynamic, e.g. refreshing OAuth token)
session.setAuthenticationHandler(new BearerTokenAuthenticationHandler(tokenStore::currentToken));

Custom HTTP client backend

To provide a fully custom HTTP backend, implement RDF4JHttpClientFactory and register it as a java.util.ServiceLoader service in META-INF/services/org.eclipse.rdf4j.http.client.spi.RDF4JHttpClientFactory.

To extend the Apache HC5 backend with additional configuration (e.g. custom interceptors or connection managers), subclass ApacheHC5RDF4JHttpClientFactory and override buildHttpClient(HttpClientBuilder, RDF4JHttpClientConfig):

public class MyFactory extends ApacheHC5RDF4JHttpClientFactory {
    @Override
    protected CloseableHttpClient buildHttpClient(HttpClientBuilder builder, RDF4JHttpClientConfig config) {
        builder.addRequestInterceptorFirst(myInterceptor);
        return super.buildHttpClient(builder, config);
    }
}

Back to the top