Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ concurrency:
${{ github.repository }}-${{ github.workflow }}-${{ github.event.number || github.head_ref || github.run_id || github.sha }}
cancel-in-progress: true
env:
JAVA_VERSION: 21
JAVA_VERSION: 25
jobs:
build:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-central.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ concurrency:
${{ github.repository }}-${{ github.workflow }}-${{ github.event.number || github.head_ref || github.run_id || github.sha }}
cancel-in-progress: true
env:
JAVA_VERSION: 21
JAVA_VERSION: 25
jobs:
publish-central:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-github-packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ concurrency:
${{ github.repository }}-${{ github.workflow }}-${{ github.event.number || github.head_ref || github.run_id || github.sha }}
cancel-in-progress: true
env:
JAVA_VERSION: 21
JAVA_VERSION: 25
jobs:
publish-gh-packages:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
java adoptopenjdk-21.0.2+13.0.LTS
java adoptopenjdk-25.0.4+101.0.LTS
maven 3.9.16
50 changes: 50 additions & 0 deletions changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,65 @@ Changes log

- 3.0 Milestone 2 (??-??-2026)
- Breaking changes
- Java 25 is now the minimum version (compiled with `--release 25`).
- The HTTP/HTTPS server and client connectors of the core now rely on Netty 4.2 instead of
Jetty 12. The connector class names are unchanged
(`org.restlet.engine.connector.HttpServerHelper`, `HttpsServerHelper`,
`HttpClientHelper`), and the Jetty dependencies are removed. No Netty type is exposed by
the public API: the module requires the Netty modules without `requires transitive`.
- Server calls run by default on virtual threads, one per call ("threadPool.virtual"
parameter, `true` by default). Set it to `false` to use a pool of platform threads
configured by the existing "threadPool.*" parameters.
- Server connector parameters: added "threadPool.virtual", "server.maxConcurrentCalls",
"eventLoop.bossThreads", "eventLoop.workerThreads". Kept "threadPool.minThreads",
"threadPool.maxThreads", "threadPool.threadsPriority", "threadPool.idleTimeout",
"connector.acceptQueueSize", "connector.idleTimeout", "http.requestHeaderSize",
"http.outputBufferSize", "server.maxConnections", "shutdown.gracefully",
"shutdown.timeout", "http.transport.protocol(s)". The other Jetty-specific parameters
("connector.acceptors", "connector.selectors", "lowResource.*", "http.*CacheSize", ...)
are removed and ignored.
- HTTP/3 is now **experimental**, on Netty's QUIC and HTTP/3 codecs. It is off by default,
and enabled with HTTP3 in "http.transport.protocols" (server, combined with HTTP1_1 or
HTTP2) or "httpClientTransportMode" (client). It requires the optional
`io.netty:netty-codec-http3` dependency and the native QUIC library of the platform
(`io.netty:netty-codec-native-quic` with the platform classifier: Linux, macOS, Windows
x86_64). The server serves HTTP/3 on the UDP port having the same number as the TCP port
and advertises it with the "Alt-Svc" response header; the client doesn't discover it
with "Alt-Svc" and only uses it when asked to. TLS comes from the key and trust stores
of the `DefaultSslContextFactory` (custom `SslContextFactory` implementations and the
cipher suite and protocol settings are not supported). The Jetty "http3PemWorkDir" and
"http3.pem.workdir" parameters are removed. See `org.restlet.engine.netty.Http3Support`
for the documented limits.
- Client connector: removed `getHttpClient()`, `createHttpClient()`, the Jetty
authentication and cookie stores (`get/setAuthenticationStore`, `get/setCookieStore`),
`get/setExecutor`, `getScheduler` and the "cookieSupported", "addressResolutionTimeout",
"connectBlocking", "destinationIdleTimeout", "httpComplianceMode",
"maxRequestsQueuedPerDestination", "responseBufferSize", "strictEventOrdering" and
"http3PemWorkDir" parameters. Added "hostnameVerification" (`true` by default) and
"eventLoop.workerThreads". "maxResponseHeadersSize" is renamed "maxResponseHeaderSize"
(8192 by default). Redirects ("followRedirects", "maxRedirects") are now followed by
the connector for synchronous calls, without leaking credentials to other origins.
- Removed `JettyServerHelper`, `JettyServerCall`, `JettyClientCall`, `JettyHandler`,
`RestletSslContextFactoryClient` and `RestletSslContextFactoryServer`.
- `MultiPartRepresentation` no longer exposes Jetty types: parts are instances of the new
`MultiPartRepresentation.Part` class (name, file name, headers, content
representation), parsing takes an optional storage directory instead of a Jetty
`MultiPartConfig`, and generation streams the parts.
- Removed the OSGi support: the `Activator`, the `osgi.core` dependency and the bundle
packaging (Maven artifacts are now plain JARs, without `Bundle-*` manifest headers).
`XmlFactoryProvider` of the Jackson extension now relies on the plain `ServiceLoader`.
OSGi users should stay on 2.x.
- Removed the `Protocol.WAR` constant ("war" scheme, Web Archive Access Protocol), a
leftover of the Servlet mode, which is no longer supported. `Protocol.valueOf("war")`
now returns a new, unknown protocol. Use CLAP or FILE references instead.
- Bugs fixed
- Slf4j bridge reports wrong line number and caller class in log4j. Issue #233.
- When GET is an allowed method of a server resource, HEAD is now also listed (e.g. in the Allow header of a 405 response). Issue #266.
- Misc
- Pinned the Maven Deploy plugin to version 3.2.0 (avoids resolving incompatible Maven 4 beta versions).
- Added Netty 4.2.19 (imported with the `netty-bom`). CI builds with Java 25.
- The `dangling-doc-comments` lint, new in Java 23, is disabled because license headers
use Javadoc-style comments.

- 3.0 Milestone 1 (10-11-2026)
- Breaking changes
Expand Down
7 changes: 7 additions & 0 deletions org.restlet.ext.slf4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,12 @@
<version>${lib-junit-version}</version>
<scope>test</scope>
</dependency>
<!-- SLF4J provider for the tests (previously brought by Jetty's jetty-slf4j-impl) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${lib-slf4j-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2 changes: 1 addition & 1 deletion org.restlet.ext.slf4j/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@SuppressWarnings({"module", "requires-automatic", "requires-transitive-automatic"})
module org.restlet.ext.slf4j {
requires transitive org.restlet;
requires org.slf4j;
requires transitive org.slf4j;

exports org.restlet.ext.slf4j;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
*
* <pre>
* SpringContext springContext = new SpringContext(getContext());
* springContext.getPropertyConfigRefs().add(&quot;war://config/database.properties&quot;);
* springContext.getXmlConfigRefs().add(&quot;war://config/applicationContext.xml&quot;);
* springContext.getPropertyConfigRefs().add(&quot;clap://thread/config/database.properties&quot;);
* springContext.getXmlConfigRefs().add(
* &quot;file:///C/myApp/config/applicationContext.xml&quot;);
* springContext.getXmlConfigRefs().add(
Expand Down
133 changes: 65 additions & 68 deletions org.restlet/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,88 +16,46 @@
<properties>
<!-- Known high-priority SpotBugs findings, to be fixed (see Engine, Resource, ...) -->
<spotbugs.max.violations>9</spotbugs.max.violations>
<!-- Native QUIC library for the HTTP/3 tests, overridden per platform by the profiles
below. On other platforms, the HTTP/3 tests are skipped. -->
<netty.quic.classifier>linux-x86_64</netty.quic.classifier>
</properties>

<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>jetty-http2-server</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-server</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
</dependency>
<!-- Experimental HTTP/3: optional, applications add it (with its native QUIC library for
their platform) to enable HTTP/3. The native libraries are test dependencies here. -->
<dependency>
<groupId>org.eclipse.jetty.http3</groupId>
<artifactId>jetty-http3-server</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http3</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-codec-native-quic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.quic</groupId>
<artifactId>jetty-quic-server</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>jetty-http2-client</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>jetty-http2-client-transport</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http3</groupId>
<artifactId>jetty-http3-client</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http3</groupId>
<artifactId>jetty-http3-client-transport</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${lib-jetty-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.quic</groupId>
<artifactId>jetty-quic-client</artifactId>
<version>${lib-jetty-version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-codec-native-quic</artifactId>
<classifier>${netty.quic.classifier}</classifier>
<scope>test</scope>
</dependency>

<dependency>
Expand Down Expand Up @@ -175,4 +133,43 @@
</plugin>
</plugins>
</build>

<!-- Native QUIC library of the build platform, used by the experimental HTTP/3 tests. -->
<profiles>
<profile>
<id>quic-linux-x86_64</id>
<activation>
<os><family>unix</family><name>Linux</name><arch>amd64</arch></os>
</activation>
<properties><netty.quic.classifier>linux-x86_64</netty.quic.classifier></properties>
</profile>
<profile>
<id>quic-linux-aarch_64</id>
<activation>
<os><family>unix</family><name>Linux</name><arch>aarch64</arch></os>
</activation>
<properties><netty.quic.classifier>linux-aarch_64</netty.quic.classifier></properties>
</profile>
<profile>
<id>quic-osx-x86_64</id>
<activation>
<os><family>mac</family><arch>x86_64</arch></os>
</activation>
<properties><netty.quic.classifier>osx-x86_64</netty.quic.classifier></properties>
</profile>
<profile>
<id>quic-osx-aarch_64</id>
<activation>
<os><family>mac</family><arch>aarch64</arch></os>
</activation>
<properties><netty.quic.classifier>osx-aarch_64</netty.quic.classifier></properties>
</profile>
<profile>
<id>quic-windows-x86_64</id>
<activation>
<os><family>windows</family><arch>amd64</arch></os>
</activation>
<properties><netty.quic.classifier>windows-x86_64</netty.quic.classifier></properties>
</profile>
</profiles>
</project>
34 changes: 19 additions & 15 deletions org.restlet/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,28 @@
* <p>Restlet is a registered trademark of QlikTech International AB.
*/
/** Restlet Framework core: API, engine and connectors. */
@SuppressWarnings({"module", "requires-automatic", "requires-transitive-automatic"})
module org.restlet {
requires transitive java.desktop;
requires transitive java.logging;
requires transitive java.xml;
requires transitive org.eclipse.jetty.http2.client;
requires transitive org.eclipse.jetty.http2.client.transport;
requires transitive org.eclipse.jetty.http2.server;
requires transitive org.eclipse.jetty.http3.client;
requires transitive org.eclipse.jetty.http3.client.transport;
requires transitive org.eclipse.jetty.http3.server;
requires transitive org.eclipse.jetty.alpn.server;
requires transitive org.eclipse.jetty.client;
requires transitive org.eclipse.jetty.http;
requires transitive org.eclipse.jetty.io;
requires transitive org.eclipse.jetty.server;
requires transitive org.eclipse.jetty.util;
requires transitive org.eclipse.jetty.quic.client;
requires transitive org.eclipse.jetty.quic.server;

// Netty is an implementation detail of the HTTP connectors: required, not re-exported.
requires io.netty.buffer;
requires io.netty.codec;
// Needed by the HTTP content decompressor; netty-codec-http only requires it statically, so
// it would not be resolved on the module path otherwise.
requires io.netty.codec.compression;
requires io.netty.codec.http;
requires io.netty.codec.http2;
requires io.netty.common;
requires io.netty.handler;
requires io.netty.handler.proxy;
requires io.netty.resolver;
requires io.netty.transport;

// Experimental HTTP/3: optional at runtime, see org.restlet.engine.netty.Http3Support.
requires static io.netty.codec.http3;
requires static io.netty.codec.classes.quic;

exports org.restlet;
exports org.restlet.data;
Expand All @@ -39,6 +42,7 @@
exports org.restlet.engine.io;
exports org.restlet.engine.local;
exports org.restlet.engine.log;
exports org.restlet.engine.netty;
exports org.restlet.engine.resource;
exports org.restlet.engine.security;
exports org.restlet.engine.ssl;
Expand Down
6 changes: 0 additions & 6 deletions org.restlet/src/main/java/org/restlet/data/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,6 @@ public final class Protocol {
public static final Protocol RIAP =
new Protocol("riap", "RIAP", "Restlet Internal Access Protocol", UNKNOWN_PORT, true);

/** Local Web Archive access protocol. */
public static final Protocol WAR =
new Protocol("war", "WAR", "Web Archive Access Protocol", UNKNOWN_PORT, true);

/**
* ZIP is a special scheme to access to representations inside Zip archive files. Example URI:
* "zip:file:///tmp/test.zip!/test.txt".
Expand Down Expand Up @@ -131,8 +127,6 @@ public static Protocol valueOf(String name) {
result = JDBC;
} else if (name.equalsIgnoreCase(RIAP.getSchemeName())) {
result = RIAP;
} else if (name.equalsIgnoreCase(WAR.getSchemeName())) {
result = WAR;
} else if (name.equalsIgnoreCase(ZIP.getSchemeName())) {
result = ZIP;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@ public abstract class Call {
public static boolean isBroken(Throwable exception) {
boolean result = false;

// detect Tomcat and Jetty exceptions
// detect client abort exceptions
if (exception instanceof IOException) {
String exceptionName = exception.getClass().getName();
result =
(exceptionName.endsWith("ClientAbortException")
|| exceptionName.endsWith("jetty.io.EofException"));
result = exceptionName.endsWith("ClientAbortException");
}

// check for known exception messages
Expand Down
Loading
Loading