public interface HttpClient {
// Future version
Future<HttpClientRequest> request(RequestOptions request);
// Callback version
void request(RequestOptions request, Handler<AsyncResult<HttpClientRequest>> callback);
...
}
Migrate from Vert.x 4 to 5
This guide describes the updates in Eclipse Vert.x 5 release. Use the information to upgrade your Vert.x 4.x applications to Vert.x 5. It provides information about the new, deprecated and unsupported features in this release.
Depending on the modules used in your application, you can read the relevant section to know more about the changes in Vert.x 5.
About Vert.x
Vert.x is a toolkit used for creating reactive, non-blocking, and asynchronous applications that run on Java Virtual Machine. (JVM). It contains several components that help you create reactive applications. It is designed to be cloud-native.
Since Vert.x supports asynchronous applications it can be used to create applications with high volume of messages, large event processing, HTTP interactions, and so on.
What’s changed in Vert.x 5
This section explains the fundamental differences between Vert.x 5 and 4.x releases.
Handling deprecations and removals
Some features and functions have been deprecated or removed in Vert.x 5. Before you migrate your applications to Vert.x 5, check for deprecations and removals.
-
Some APIs were deprecated in an Vert.x 4.x release and new equivalent APIs were provided in that release.
-
The deprecated APIs have been removed in Vert.x 5.
If your application uses a deprecated API, you should update your application to use the new API. This helps in migrating applications to the latest version of the product.
The Java compiler generates warnings when deprecated APIs are used. You can use the compiler to check for deprecated methods while migrating applications to Vert.x 5.
Components sunsets and removals
A few components are sunsetting in 5, that means they are still supported for the lifetime of the 5.x series, but we don’t encourage using them anymore since we provide replacements for them. Such components are scheduled to go away in the next major release (Vert.x 6).
Here is the list of components sunsetting in 5:
Component | Replacement |
---|---|
gRPC Netty | Vert.x gRPC client and server |
JDBC API | SQL client API implementation for JDBC |
Service Discovery | Vert.x Service Resolver |
RxJava 2 | Mutiny or RxJava 3 |
OpenTracing | OpenTelemetry |
Vert.x Unit | Vert.x JUnit 5 |
Here is the list of components removed in 5, that were sunset in the 4.x series.
Component | Replacement |
---|---|
Vert.x Sync | Vert.x virtual threads |
Service Factories | None |
Maven Service Factory | None |
HTTP Service Factory | None |
Vert.x Web OpenAPI |
Embracing the future model
Vert.x 4 extended the 3.x callback asynchronous model to a future/callback hybrid model, to facilitate migration from Vert.x 3.
Every callback method has a matching future method:
Vert.x 5 only retains the future model and thus the callback model is gone, instead you get:
public interface HttpClient {
// Future version
Future<HttpClientRequest> request(RequestOptions request);
...
}
Callback methods Vert.x 4.x are not deprecated methods, however after the release of Vert.x 5, the callback methods shall be deprecated in order to facilitate the migration to Vert.x 5.
Vert.x builders
Vert.x 5 has introduced the usage of the builder pattern that facilitate component configuration with instances of objects.
Until 5, such customisation was usually supported by options.
Future<Vertx> future = Vertx.clusteredVertx(options.setClusterManager(clusterManager));
The builder pattern provide a clean and simple alternative to separate configuration and customization.
Future<Vertx> f = Vertx
.builder()
.with(options)
.withClusterManager(clusterManager)
.buildClustered();
This pattern has been adopted whenever possible in Vert.x 5 and will be detailed on a per component basis.
Vert.x command-line tool removal
The vertx
command-line tool has been removed in Vert.x 5.
We want to focus on the use case of the typical Vert.x application: compiled and optionally packaged as an executable uber-jar.
You can do this with Maven and the Vert.x Maven Plugin. The plugin can create a new Maven project in your repository or update an existing one.
In addition to packaging the application as an executable uber-jar, it can also start your application in development mode (redeploying the main verticle when file changes are detected).
If you’re a Gradle user, the Vert.x Gradle Plugin provides similar features.
CLI framework deprecation
The CLI framework is deprecated in Vert.x 5. This includes the io.vertx.core.Launcher
class, which is based on it.
If your application is a command-line tool or needs one, checkout alternatives like Picocli. In fact, in various aspects, Picocli is more flexible and more powerful than the Vert.x CLI framework.
Vert.x Legacy CLI
If, while evaluating alternatives, you need to preserve the CLI framework functionality, you may do so by adding this dependency to your project (Maven):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-launcher-legacy-cli</artifactId>
<version>5.0.0</version>
</dependency>
This new project contains the legacy CLI framework, including the io.vertx.core.Launcher
class.
Beware it is not guaranteed that backward compatibility can be maintained for the whole Vert.x 5 lifetime.
Vert.x Application Launcher
In Vert.x 5, a new module, the Vert.x Application Launcher replaces the Vert.x 4.x io.vertx.core.Launcher
class.
First, you must add it to your project’s dependencies (Maven):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-launcher-application</artifactId>
<version>5.0.0</version>
</dependency>
To start your application, use io.vertx.launcher.application.VertxApplication
as the main class.
# Assuming the command is executed on a Unix-like system which has the classpath configured in the CLASSPATH environment variable.
java -cp $CLASSPATH io.vertx.launcher.application.VertxApplication my.app.MainVerticle
If your application is packaged as an executable JAR, having the Main-Class
attribute set to io.vertx.launcher.application.VertxApplication
in the META-INF/MANIFEST.MF
file, the command can be simplified.
java -jar myapp.jar my.app.MainVerticle
Vert.x Core
Vert.x instance customization
An instance of Vertx
can be customized with a few moving parts:
-
cluster manager
-
metrics factory
-
tracing factory
In Vert.x 5 customization is achieved by the VertxBuilder
.
// 4.x
Future<Vertx> f = Vertx.clusteredVertx(
new VertxOptions().setClusterManager(clusterManager)
);
// 5.0
Future<Vertx> f = Vertx
.builder()
.withClusterManager(clusterManager)
.buildClustered();
Likewise, metrics and tracing factories are configured similarly
// 4.x
Vertx vertx = Vertx.vertx(
new VertxOptions()
.setMetricsOptions(new MetricsOptions().setEnabled(true).setFactory(factory))
.setTracingOptions(new TracingOptions().setFactory(factory))
);
// 5.0
Vertx vertx = Vertx
.builder()
.withMetrics(factory)
.withTracer(factory)
.build();
The tracing implementations of Vert.x have been updated accordingly to support customizing with a tracer implementation for this purpose:
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
.setTracingOptions(
new OpenTelemetryOptions(openTelemetry)
)
);
// 5.0
Vertx vertx = Vertx.builder()
.withTracer(new OpenTelemetryTracingFactory(openTelemetry))
.build();
The metrics implementations of Vert.x have been updated accordingly to support customizing with a metrics implementation for this purpose:
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
.setMetricsOptions(new DropwizardMetricsOptions()
.setMetricsRegistry(myRegistry)
.setEnabled(true)));
// 5.0
Vertx vertx = Vertx.builder()
.with(new VertxOptions()
.setMetricsOptions(new DropwizardMetricsOptions()
.setEnabled(true)))
.withMetrics(new DropwizardMetricsFactory(myRegistry))
.build();
HTTP related changes
HTTP/2 connection shutdown handler
The HTTP/2 connection shutdown handler notifies the handler when the connection shutdown begins, previously the handler was notified when after all the connection streams have been closed. The previous behavior can be obtained with the connection close handler.
This allows to be aware of a connection shutdown and take appropriate measures to stop the inflight streams being processed. It also aligns with the behaviour of other shutdown handlers.
Removal of HTTP connection shutdown variant without a timeunit
The HttpConnection#shutdown(long)
variant is removed in favor of HttpConnection#shutdown(long, TimeUnit)
.
// 4.x
connection.shutdown(5 * 1000); // 5 seconds
// 5.0
connection.shutdown(5, TimeUnit.SECONDS); // 5 seconds
Removal of HTTP server response push with a string authority
HttpServerResponse#push
methods with a string authority have been removed in favour of the same method with an HostAndPort
type instead.
// 4.x
response.push(httpMethod, authorityAsString path);
// 5.0
response.push(httpMethod, HostAndPort.parse(authorityAsString) path);
Removal of HTTP server request cookie map method
The deprecated HttpServerRequest#cookieMap
method has been removed, instead the HttpServerRequest#cookies
method should be used.
// 4.x
Map<String, Cookie> cookieMap = request.cookieMap();
// 5.0
Set<Cookie> cookies = request.cookies();
Use of uniform byte distributor for HTTP/2 streams
The default stream byte distributor use stream priorities to determine the amount of bytes to be sent for each stream, this change allows to use a strategy that does not use stream priorities and yields better performance since it consumes less CPU.
The default implementation is now UniformStreamByteDistributor
instead of WeightedFairQueueByteDistributor
.
Rename HttpClientRequest setTimeout to setIdleTimeout
The request timeout is actually an idle timeout, it has been renamed to avoid confusion.
// 4.x
request.setTimeout(timeout);
// 5.0
request.setIdleTimeout(timeout);
Removal of HttpClient WebSocket methods
HttpClient
WebSocket methods are moved to a new WebSocketClient
API.
// 4.x
HttpClient httpClient = vertx.createHttpClient();
Future<WebSocket> f = httpClient.webSocket(connectOptions);
// 5.0
WebSocketClient wsClient = vertx.createWebSocketClient();
Future<WebSocket> f = wsClient.connect(connectOptions);
HTTP client customization
HttpClient
customization methods have been moved to a new HttpClientBuilder
:
-
redirectHandler
-
connectionHandler
// 4.x
HttpClient client = vertx.createHttpClient();
client.connectionHandler(conn -> ...);
client.redirectHandler(request -> ...);
// 5.0
HttpClient client = vertx.httpClientBuilder()
.withConnectHandler(conn -> ...)
.withRedirectHandler(request -> ...)
.build();
HttpClient API cleanup
In Vert.x 4.x, HttpClient
API exposes two distincts API:
-
HTTP interactions, like
request
method. -
HTTP client operations, like
updateSSLOptions
Since Vert.x 5, HttpClient
only retains HTTP interactions, a new HttpClientAgent
API extends HttpClient
and exposes these methods:
// 4.x
HttpClient client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);
// 5.0
HttpClientAgent client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);
HttpClient pool configuration
In Vert.x 4.x, HttpClientOptions
configures the HTTP/1.x and HTTP/2 pool.
Since Vert.x 5, this configuration is done through PoolOptions
.
// 4.x
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setMaxPoolSize(http1MaxPoolSize)
.setHttp2MaxPoolSize(http2MaxPoolSize)
);
// 5.0
HttpClient client = vertx.createHttpClient(new PoolOptions()
.setHttp1MaxSize(http1MaxPoolSize)
.setHttp2MaxSize(http2MaxPoolSize)
);
Removal of HttpServerResponse close method
The HttpServerResponse
close method closes the HTTP connection, it can be misleading as there are better API to interact with the current request/connection lifecycle which are HttpServerResponse#reset
and HttpConnection#close
.
When the actual HTTP connection must be closed:
// 4.x
response.close();
// 5.0
request.connection().close();
When the current request/response must be disposed:
// 4.x
response.close();
// 5.0
response.reset();
HTTP stream async methods returns now a future instead of being fluent
A few methods have seen their fluent return type to be changed to a future type instead in order to signal the completion result:
-
writeCustomFrame
-
writeContinue
-
reset
// 4.x
response.writeCustomFrame(12, 134, expectedRecv).end();
// 5.0
response.writeCustomFrame(12, 134, expectedRecv);
response.end();
New authority property replacing host/port
HttpClientRequest
and HttpServerRequest
expose the request authority using a host/port combination for the client request and a single host header for the server. In addition, this terminology is also confusing with the actual server host and port.
Those are replaced by a new authority property:
// 4.x
request.setHost(host).setPort(port);
// 5.0
request.authority(HostAndPort.create(host, port));
// 4.x
String host = request.host(); // host:port string
// 5.0
HostAndPort authority = request.authority();
HttpServer request and WebSocket streams removal
HttpServer#requestStream()
and HttpServer#timeoutStream()
have been removed. These streams were designed for Rx like languages and the actually don’t provide any benefits.
// 4.x
server.requestStream().handler(request -> ...);
// 5.0
server.requestHandler(request -> ...).listen();
Removal of server WebSocket handshake methods
The server WebSocket API can control handshake implicitly (e.g. sending a message) or explicitly (accept or any WebSocket interaction). This result in a more complex implementation than it should be for such API.
// 4.x
server.webSocketHandler(ws -> {
ws.accept();
ws.write();
};
// 5.0
server.webSocketHandshakeHandler(handshake -> {
handshake.accept();
});
server.webSocketHandler(ws -> {
ws.write();
};
// 4.x
server.webSocketHandler(ws -> {
ws.reject();
};
// 5.0
server.webSocketHandshakeHandler(handshake -> {
handshake.reject();
});
Future
CompositeFuture raw Future type removal
CompositeFuture
methods declare raw Future
types, e.g. all(Future,Future) or all(List<Future>>)
, such declarations force the user to cast when using a List<Future<Something>>
. These methods have been made fully generic, using the wildcard type.
List<Future<User>> users = ...
// 4.x
CompositeFuture cf = CompositeFuture.all((List<Future>)users);
// 5.0
CompositeFuture cf = Future.all(users);
Removal of Future eventually method that takes a function as argument
Future#eventually
method takes as parameter a Function<Void, Future<T>>
, this was developed for codegen which does not support Supplier
. The Future
object is not code generated anymore since Vert.x 4.x, we can therefore use Supplier
which is more suitable.
// 4.x
future.eventually(v -> someFuture());
// 5.0
future.eventually(() -> someFuture());
Logging
Vert.x Logging API usage has been reduced in Vert.x 4 to be used by Vert.x components, in other words the API has become internal to Vert.x:
io.vertx.core.logging.Logger
and io.vertx.core.logging.LoggerFactory
have been deprecated to discourage usage of this API. Instead, a logging API should be used such as Log4j 2 or SLF4J.
Of course, configuration of the Vert.x logging back-end remains fully supported as usual, like the vertx.logger-delegate-factory-class-name
system property.
System properties
A few system properties have been removed in Vert.x 5.
Name | Comment |
---|---|
| Vert.x 3.x Json supports RFC-7493, however the JSON encoder/decoder format was incorrect. Users who needed to interop with Vert.x 3.x applications should have set the system property |
| Not used, neither documented nor tested. |
| Not used, neither documented nor tested. |
| Vert.x HTTP/1.1 server contains a hidden option to detect Adobe Flash clients and return a policy file response. This option is activated by a system property |
| This system property was not documented and only used in the |
| Instead, |
Worker verticles
Removal of deployment worker property
DeploymentOptions#setWorker
and DeploymentOptions#getWorker
methods are removed since the introduction of the new ThreadingModel
.
// 4.x
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setWorker(true, ...)
// 5.0
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setThreadingModel(ThreadingModel.WORKER, ...)
Worker event-loop assignment
Since Vert.x 5 worker deployment uses a single event-loop for all worker verticles instead of an event-loop per worker instance.
Previously, this was following event-loop deployments which use an event-loop per verticle instance for scalability purpose.
Miscellaneous
NetServer connect stream removals
NetServer#connectStream()
has been removed. This stream was designed for Rx like languages and the actually don’t provide any benefits at the expense of the API.
// 4.x
server.connectStream().handler(socket -> ...);
// 5.0
server.connectHandler(socket -> ...).listen();
TimeoutStream removal
TimeoutStream
has been removed. This stream was designed for Rx like languages and the actually don’t provide any benefits at the expense of the API. Instead, the framework scheduler should be used instead along with a Vert.x context.
// 4.x
vertx.periodicStream(1L).handler(timerID -> ...);
// 5.0
server.setPeriodic(1L, timerID -> ...);
For RxJava like integrations
// 4.x
Observable<Long> timer = vertx.periodicStream(1000).toObservable();
// 5.0
Scheduler scheduler = RxHelper.scheduler(vertx);
Observable<Long> timer = Observable.interval(100, 100, TimeUnit.MILLISECONDS, scheduler);
keyCertOptions key manager mapper removal
KeyCertOptions#keyManagerMapper()
method has been removed in Vert.x 5, implementors must instead implement keyManagerFactoryMappermethod
that provides the opportunity to cache the KeyManagerFactory
to the implementor that controls the lifecycle of the key manager.
Removal of execute blocking methods with a handler of promise
The API for executing blocking actions uses a pattern with handler completing or failing a promise, instead this can be replaced with java.util.concurrent.Callable
that returns the same value or throws an exception.
// 4.x
Future<String> fut = vertx.executeBlocking(promise -> promise.complete("result"));
// 5.0
Future<String> fut = vertx.executeBlocking(() -> "result");
processArgs methods deprecated
io.vertx.core.Context#processArgs
and io.vertx.core.AbstractVerticle#processArgs
are deprecated.
As of version 5, Vert.x is no longer tightly coupled to the CLI.
Netty type usage removals
The Vert.x API exposes the Netty API in its public API, allowing interactions with the Netty API. Since Netty is evolving toward Netty 5, we should remove Netty API from the Vert.x public API in Vert.x 5 to have the opportunity to change the underlying Netty version used by Vert.x without worrying about the version of the Netty version.
Such API continues to exist in Vert.x 5 but is moved to internal API which is not contractual, therefore experimented users of this API can continue to use it granted that the version of Vert.x 5 uses Netty 4.
// 4.x
ByteBuf bb = buff.getByteBuf();
Buffer buf = Buffer.buffer(bb);
EventLoopGroup group = vertx.nettyEventLoopGroup();
// 5.0
ByteBuf bb = ((BufferInternal)buff).getByteBuf();
buf = BufferInternal.buffer(bb);
group = ((VertxInternal)vertx).nettyEventLoopGroup();
Vert.x Auth
AuthProvider pruning
io.vertx.ext.auth.AuthProvider` has been deprecated in Vert.x 4.0 in favour of io.vertx.ext.auth.authentication.AuthenticationProvider
.
// 4.x
AuthProvider authProvider = ...
// 5.0
AuthenticationProvider authProvider = ...
Vert.x for Kotlin
Removal of await extension methods generation
Vert.x 4.x for Kotlin generates suspending extension methods to facilitate the invocation of Vert.x asynchronous method.
suspend fun HttpServer.listenAwait(port: Int, host: String): HttpServer {
return awaitResult {
this.listen(port, host, it)
}
}
Such methods have been deprecated since the equivalent can be achieved using a Vert.x future instance and removed in Vert.x 5.
// 4.x
server.listenAwait(port, host)
// 5.0
server.listen(host, port).coAwait()
Vert.x gRPC
Removal of GrpcReadStream#collecting in favour of ReadStream#collect
// 4.x
stream.collecting(collector);
// 5.0
stream.collect(collector);
Removal of methods declaring a method descriptor
GrpcClient
/GrpcServer
methods declaring a MethodDescriptor
have been removed.
Instead, these methods are now available in GrpcIoClient
/GrpcIoServer
interfaces which extend GrpcClient
/GrpcServer
interfaces.
// 4.x
GrpcServer server = GrpcServer.create(vertx);
// 5.0
GrpcIoServer server = GrpcIoServer.create(vertx);
server.callHandler(methodDescriptor, request -> ...);
Vert.x Web
RoutingContext user API
User related operations have been moved under a single context API accessible from RoutingContext
Logout
// 4.x
routingContext.clearUser();
// 5.0
UserContext userContext = routingContext.userContext();
userContext.logout();
Setting a user
The RoutingContext#setUser
method has been removed, this operation should be performed by authentication handlers instead.
Static handler configuration
StaticHandler
methods setAllowRootFileSystemAccess
and setWebRoot
are removed after deprecation in Vert.x 4.x.
Instead, the handler must be configured at creation time:
// 4.x
StaticHandler handler = StaticHandler.create().setAllowRootFileSystemAccess(true).setWebRoot(root);
// 5.0
StaticHandler handler = StaticHandler.create(FileSystemAccess.ROOT, root);
Vert.x Web Client
Response expectation replacement
Vert.x Core introduces a new API to implement expectation checks inspired from the Web Client response expectation feature.
The Vert.x HTTP Client comes with the same set of predefined expectations than the Web Client response expectations, more importantly HTTP client response expectations can be re-used by Web Client.
HTTP response expectations leverages the new Future#expecting
operation combined with the HttpResponseExpectation
implementation.
// 4.x
client
.get(8080, "myserver.mycompany.com", "/some-uri")
.expect(ResponsePredicate.SC_SUCCESS)
.send()
.onSuccess(res -> {
// ....
});
// 5.0
client
.get(8080, "myserver.mycompany.com", "/some-uri")
.send()
.expecting(HttpResponseExpectation.SC_SUCCESS)
.onSuccess(res -> {
// ....
});
Vert.x Web GraphQL
Upgrade to GraphQL-Java 22
GraphQL-Java 22 is a breaking change release.
Vert.x Web Validation
Replacement of deprecated SchemaParser
Vert.x Web Validation was based on a deprecated JSON Schema API, which is no longer available in Vert.x 5.
// 4.x
ValidationHandlerBuilder.create(schemaParser)
// 5.0
SchemaRepository schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7));
ValidationHandlerBuilder.create(schemaRepo);
To improve security, the new SchemaRepository is not automatically loading external references. In case your schema contains an external references you must provide and dereference them upfront. |
Vert.x SQL Client
Client builder
The Pool
subtypes are not really useful as they don’t carry any extra method and are use mainly for statically building pool.
In addition, those static methods are not flexible and are numerous due to overloading.
We are replacing these methods with a new client builder API.
// 4.x
PgPool client = PgPool.pool(vertx, connectOptions, poolOptions);
//5.0
Pool client = PgBuilder.pool()
.with(poolOptions)
.connectingTo(connectOptions)
.using(vertx)
.build();
Connect options
The SqlConnectOptions
class does not extend anymore NetClientOptions
class.
SqlConnectOptions
TLS configuration still happens on this class.
// 4.x
// 5.0
PgConnectOptions options = new PgConnectOptions()
.setPort(port)
.setHost(host)
.setDatabase(database)
.setUser(user)
.setPassword(password)
.setSslOptions(new ClientSSLOptions()
.setTrustOptions(new PemTrustOptions().addCertPath(pathToCert))
);
NetClientOptions
can still be passed when building a client thanks to the ClientBuilder
.
// 5.0
Pool pool = PgBuilder.pool()
.connectingTo(connectOptions)
.with(tcpOptions)
.build();
Pool connect handler
Pool#connectHandler
method is moved to the new ClientBuilder
, the handler is set once at build time instead of being a mutable field of the pool implementations.
// 4.x
pool.connectHandler(connectHandler);
// 5.0
builder.connectHandler(connectHandler);
Pool connection provider
Pool#connectionProvider
method is replaced by a Supplier<Future<SqlConnectOptions>>
builder method.
// 4.x
pool.connectionProvider(ctx -> futureOfSqlConnection(ctx));
// 5.0
builder.connectingTo(() -> futureOfSqlConnectOptions());
Vert.x Mongo Client
Upgrade to MongoDB Java Driver 5
MongoDB Java Driver 5.x is a breaking change release.
In IndexOptions
, bucketSize
has been removed.
Besides, StreamFactoryFactory
has been replaced by TransportSettings
, and Netty is the only available transport.
Vert.x Redis Client
Removal of request null argument
Redis does not accept null
values in the request. The Request#nullArg()
method therefore encoded null
as the 4-character "null"
string.
This method, which was deprecated in 4.x, is removed. All places that used it to encode the null
value now throw an IllegalArgumentException
.
If you use null
values in Redis requests, you should stop doing that. To restore previous behavior, you should encode null
values as "null"
manually. This applies to:
-
Request.arg(String)
-
Request.arg(Buffer)
-
Request.arg(JsonArray)
: both the array itself, and individual elements -
Request.arg(JsonObject)
: both the object itself, and individual elements
Automatic forwarding of Redis subscriptions to the Vert.x event bus
In Vert.x 4.x, the Redis subscriptions were automatically forwarded to the event bus, unless the message handler was set explicitly (using RedisConnection.handler()
).
This is no longer the case. Since Vert.x 5, you always have to register a message handler. If you still want the subscription messages forwarded to the event bus, you have to manually create an instance of EventBusHandler
and register it using RedisConnection.handler()
:
RedisConnection conn = ...;
conn.handler(EventBusHandler.create(vertx));
conn.send(Request.cmd(Command.SUBSCRIBE).arg("news"));
In addition, the EventBusHandler
does not forward only messages ([p]message
); it also forwards subscriptions and un-subscriptions ([p]subscribe
and [p]unsubscribe
).
RedisCluster.groupByNodes() changed return type + code generation changes
The RedisCluster#groupByNodes()
method used to return Future<List<List<Request>>>
. Due to this return type, the RedisCluster
wasn’t @VertxGen
.
This has changed in Vert.x 5. The groupByNodes()
method now returns Future<RequestGrouping>
and the entire interface is @VertxGen
.
Further, the Request
, Response
and Command
interfaces are no longer @VertxGen
— instead, they are @DataObject
. This means that users of code-generated APIs (such as Vert.x Rx) will no longer use the generated wrappers; they will use the core Vert.x Redis interfaces.
JSON serialization/deserialization of RedisOptions
The RedisOptions
class has multiple methods to configure the Redis endpoints. These methods are still available, but the JSON format of this class has changed to only include one canonical field: endpoints
.
If you rely on the JSON form of RedisOptions
objects, note that the endpoint
, connectionString
and connectionStrings
members of the JSON object are no longer recognized by the deserializer and are no longer generated by the serializer. Ensure that the necessary information is present in the endpoints
member.
Options addEndpoint/setEndpoint replacements
RedisOptions#addEndpoint
and RedisOptions#setEndpoint
are replaced by RedisOptions#addConnectionString
and RedisOptions#setConnectionString
// 4.x
options.setEndpoint(location);
// 4.x
options.setConnectionString(location);
Vert.x Health Check
Health checks dependencies improvements
Previously, Vert.x Health Check depended on Vert.x Web and Vert.x Auth. It now only defines the health check API, the health check route handler has been moved to Vert.x Web.
This result in a package change in import declarations.
// 4.x
import io.vertx.ext.healthchecks.HealthCheckHandler;
// 5.0
import io.vertx.ext.web.healthchecks.HealthCheckHandler;
Vert.x Circuit Breaker
Remove deprecated for removal retry policy
The circuit breaker retry policy with a Java function argument has been removed after deprecation in 4.x.
Instead, the RetryPolicy
functional interface should be used.
// 4.x
breaker.retryPolicy(retryCount -> 5);
// 5.0
breaker.retryPolicy((failure, retryCount) -> 5);
Vert.x MQTT
Client options will message string getter/setter deprecated removal
Client options will message string getter/setter have been removed after deprecation in 4.x.
Instead, the Buffer
version should be used
// 4.x
options.setWillMessage(str);
// 5.0
options.setWillMessageBytes(Buffer.buffer(str));
Vert.x Mail Client
Remove deprecated MailConfig setKeyStore/setKeyStorePassword
Remove deprecated MailConfig#setKeyStore
and MailConfig#setKeyStorePassword
properties.
Instead, use MailConfig#setTrustOptions.
// 4.x
options.setKeyStore(trustStorePath);
options.setKeyStorePassword(trustStorePassword);
// 5.0
options.setTrustOptions(new JksOptions().setPath(trustStorePath).setPassword(trustStorePassword));
Vert.x JUnit 5
Remove deprecated test context succeeding
Instead, use succeedingThenComplete()
or succeeding(Handler)
.
// 4.x
someFuture.onComplete(testContext.succeeding());
// 5.0
someFuture.onComplete(testContex.succeedingThenComplete());
Vert.x Service Proxy
ServiceAuthInterceptor removal
Instead, use AuthorizationInterceptor
.
// 4.x
new ServiceBinder(vertx)
.addInterceptor(new ServiceAuthInterceptor()...)
.register(SomeService.class, service);
// 5.0
new ServiceBinder(vertx)
.addInterceptor(AuthorizationInterceptor.create(authorizationProvider)...)
.register(SomeService.class, service);
ServiceBinder functionnal interceptor
The ServiceBinder#addInterceptor(Function)
and ServiceBinder#addInterceptor(String, Function)
have been removed in favor of the variant with the ServiceInterceptor
functional interface.
// 4.x
binder.addInterceptor(msg -> vertx.timer(10, TimeUnit.MILLISECONDS).map(msg));
// 5.0
binder.addInterceptor((vertx, interceptorContext, body) -> vertx.timer(10, TimeUnit.MILLISECONDS).map(body));
Removal of ProxyHelper util class
The ProxyHelper
util class is removed in favor of ServiceProxyBuilder
/ ServiceBinder
equivalents.
// 4.x
ProxyHelper.registerService(MyService.class, vertx, service, "the-address");
MyService proxy = ProxyHelper.createProxy(MyService.class, vertx, "the-address");
// 5.0
new ServiceBinder(vertx)
.setAddress("the-address")
.register(MyService.class, service);
MyService proxy = new ServiceProxyBuilder(vertx)
.setAddress("the-address")
.build(MyService.class)
Vert.x Reactive Extensions
Data object changes
A few classes of Vert.x which have been historically annotated with @VertxGen
and thus considered as asynchronous types have been converted to data objects.
As consequence reactive streams like generators will not need anymore to wrap/unwrap this type which avoids un-necessary allocation.
This implies that these objects are not anymore wrapped by Vert.x RX and the type will have their package name changed.
The following classes have been promoted to data objects:
-
io.vertx.core.buffer.Buffer
-
io.vertx.core.net.HostAndPort
-
io.vertx.core.net.SocketAddress
-
io.vertx.core.net.SelfSignedCertificate
-
io.vertx.core.MultiMap
-
io.vertx.core.datagram.DatagramPacket
-
io.vertx.core.dns.MxRecord
-
io.vertx.core.dns.SrvRecord
-
io.vertx.core.file.FileProps
-
io.vertx.core.file.FileSystemProps
-
io.vertx.core.http.Cookie
-
io.vertx.core.http.HttpFrame
-
io.vertx.core.http.WebSocketFrame
-
io.vertx.core.json.JsonEvent
Among all the types above, the Vert.x buffer type is likely the most impacting change.
io.vertx.core.buffer.Buffer
has historically been part of the API as an async generated type, annotated by @VertxGen
. It has always been wrapped/unwrapped with reactive stream based like generators.
// 4.x
io.vertx.reactivex.core.buffer.Buffer buffer = rxApi.getBuffer();
// 5.0
io.vertx.core.buffer.Buffer buffer = rxApi.getBuffer();
or
// 4.x
stream.write(io.vertx.reactivex.core.buffer.Buffer.buffer("the-string"));
// 5.0
stream.write(io.vertx.core.buffer.Buffer.buffer("the-string"));
The same applies to the other types mentioned.
Vert.x Micrometer Metrics
Upgrade to Micrometer 1.14
Micrometer 1.14 comes after 1.13, which is a breaking change release if you are using the PrometheusMeterRegistry API in your code.
Please take a look at Micrometer’s migration guide.
HTTP client pool metrics
HTTP client pool metrics are now exposed as generic pool metrics with pool type http
-
vertx_http_client_queue_pending
→vertx_pool_queue_pending
-
vertx_http_client_queue_time_seconds
→vertx_pool_queue_time_seconds
Remove setting a registry on options
The micrometer options setter for a MeterRegistry
has been removed in favour of the new VertxBuilder
along with the MicrometerMetricsFactory
.
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
.setMetricsOptions(new MicrometerMetricsOptions()
.setMicrometerRegistry(myRegistry)
.setEnabled(true)));
// 5.0
Vertx vertx = Vertx.builder()
.with(new VertxOptions()
.setMetricsOptions(new MicrometerMetricsOptions()
.setEnabled(true)))
.withMetrics(new MicrometerMetricsFactory(myRegistry))
.build();
Remove InfluxDB options number of threads
VertxInfluxDbOptions#getNumThreads
and VertxInfluxDbOptions#setNumThreads
are no longer used.
// 4.x
influxDbOptions.setNumThreads(numThreads);
// 5.0
Rename metrics options request tag provider
VertxMicrometerMetricsOptions#setRequestTagsProvider
and VertxMicrometerMetricsOptions#getRequestTagsProvider
are removed in favour of VertxMicrometerMetricsOptions#setServerRequestTagsProvider
and VertxMicrometerMetricsOptions#getServerRequestTagsProvider
.
// 4.x
options.setRequestsTagsProvider(provider);
// 5.0
options.setServerRequestsTagsProvider(provider);
Vert.x Dropwizard Metrics
HTTP client pool metrics
HTTP client pool metrics are now exposed as generic pool metrics with pool type http
and named after the endpoint socket address
-
endpoint.<host:port>.queue-delay
→queue-delay
-
endpoint.<host:port>.queue-size
→queue-size
Remove setting a metrics registry on metrics options
The drop wizard options setter for a MetricsRegistry
has been removed in favour of the new VertxBuilder
along with the DropwizardMetricsFactory
.
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
.setMetricsOptions(new DropwizardMetricsOptions()
.setMetricsRegistry(myRegistry)
.setEnabled(true)));
// 5.0
Vertx vertx = Vertx.builder()
.with(new VertxOptions()
.setMetricsOptions(new DropwizardMetricsOptions()
.setEnabled(true)))
.withMetrics(new DropwizardMetricsFactory(myRegistry))
.build();
Vert.x Json Schema
Deprecated APIs removal
In Vert.x 5 the deprecated JSON Schema APIs are removed. Previously you had for every Draft an own SchemaParser
. Now you have a SchemaRepository
and can set the Draft in the options.
// 4.x
JsonObject schemaJson = new JsonObject(...);
Schema schema = new Draft7SchemaParser(SchemaRouter.create(vertx, new SchemaRouterOptions())).parse(schemaJson , scope);
JsonObject jsonToValidate = new JsonObject(...);
schema.validateSync(jsonToValidate);
// 5.0
JsonObject schemaJson = new JsonObject(...);
SchemaRepository schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7));
JsonObject jsonToValidate = new JsonObject(...);
OutputUnit result = schemaRepo.validator(JsonSchema.of(schemaJson)).validate(jsonToValidate);
if (result.getValid()) {
// Successful validation
}
Additional Error Types
In Vert.x 5 extra basic error types for output units have been added.
If you are constructing your own OutputUnits
, you will need to include the OutputErrorType
now as well. This helps to determine the cause of the failure.
// 4.x
OutputUnit ou = new OutputUnit("instanceLocation", "absoluteKeywordLocation", "keywordLocation", "error");
// 5.0
// Available error types are current OutputErrorType.NONE, OutputErrorType.INVALID_VALID, OutputErrorType.MISSING_VALUE
OutputUnit ou = new OutputUnit("instanceLocation", "absoluteKeywordLocation", "keywordLocation", "error", OutputErrorType.INVALID_VALUE);
Removal of SchemaType INT constant
Instead, use SchemaType#INTEGER
.
Remove of ValidationException createException methods
Instead, use the same signature ValidationException#create
replacements.
Vert.x Hazelcast
Upgrade to Hazelcast 5.3
This version includes many security fixes since Hazelcast 4.2.8. It requires JDK 11 to run, which is now the minimum required version in Vert.x 5.
The cluster manager is also tested with Hazelcast 5.4 and Hazelcast 5.5. But these versions require JDK 17 and JDK 21 as a minimum, respectively. Therefore, we cannot use them by default.