public interface HttpClient {
// Future version
Future<HttpClientRequest> request(RequestOptions request);
// Callback version
void request(RequestOptions request, Handler<AsyncResult<HttpClientRequest>> callback);
...
}
从 Vert.x 4 迁移到 5
本指南介绍了 Eclipse Vert.x 5 版本中的更新。您可以使用此信息将 Vert.x 4.x 应用程序升级到 Vert.x 5。它提供了有关此版本中新增、已弃用和不受支持功能的信息。
根据您的应用程序中使用的模块,您可以阅读相关章节以了解 Vert.x 5 中的更改。
关于 Vert.x
Vert.x 是一个工具包,用于创建运行在 Java 虚拟机(JVM)上的响应式、非阻塞和异步应用程序。它包含多个组件,可帮助您创建响应式应用程序。它被设计为云原生。
由于 Vert.x 支持异步应用程序,因此可用于创建具有大量消息、大型事件处理、HTTP 交互等功能的应用程序。
Vert.x 5 有哪些变化
本节解释了 Vert.x 5 和 4.x 版本之间的根本区别。
处理弃用和移除
Vert.x 5 中已弃用或移除了某些特性和功能。在将应用程序迁移到 Vert.x 5 之前,请检查弃用和移除情况。
-
在 Vert.x 4.x 版本中,某些 API 已被弃用,并在该版本中提供了新的等效 API。
-
已弃用的 API 已在 Vert.x 5 中移除。
如果您的应用程序使用已弃用的 API,您应该更新您的应用程序以使用新的 API。这有助于将应用程序迁移到产品的最新版本。
当使用已弃用的 API 时,Java 编译器会生成警告。在将应用程序迁移到 Vert.x 5 时,您可以使用编译器检查已弃用的方法。
组件的逐渐淘汰和移除
一些组件在 5.x 系列中逐渐淘汰,这意味着它们在 5.x 系列的生命周期内仍受支持,但我们不再鼓励使用它们,因为我们提供了替代方案。这些组件计划在下一个主要版本(Vert.x 6)中移除。
以下是 5.x 版本中逐渐淘汰的组件列表
组件 | 替代方案 |
---|---|
gRPC Netty | Vert.x gRPC 客户端和服务器 |
JDBC API | JDBC 的 SQL 客户端 API 实现 |
服务发现 | Vert.x 服务解析器 |
RxJava 2 | Mutiny 或 RxJava 3 |
OpenTracing | OpenTelemetry |
Vert.x Unit | Vert.x JUnit 5 |
以下是 Vert.x 5 中移除的组件列表,这些组件在 4.x 系列中已逐渐淘汰。
组件 | 替代方案 |
---|---|
Vert.x Sync | Vert.x 虚拟线程 |
服务工厂 | 无 |
Maven 服务工厂 | 无 |
HTTP 服务工厂 | 无 |
Vert.x Web OpenAPI |
拥抱未来模型
Vert.x 4 将 3.x 的回调异步模型扩展为未来/回调混合模型,以方便从 Vert.x 3 迁移。
每个回调方法都有一个匹配的未来方法
Vert.x 5 只保留未来模型,因此回调模型已消失,取而代之的是
public interface HttpClient {
// Future version
Future<HttpClientRequest> request(RequestOptions request);
...
}
Vert.x 4.x 中的回调方法不是已弃用的方法,但在 Vert.x 5 发布后,回调方法将弃用,以方便迁移到 Vert.x 5。
Vert.x 构建器
Vert.x 5 引入了构建器模式的使用,该模式方便了组件与对象实例的配置。
直到 Vert.x 5,这种定制通常通过选项来支持。
Future<Vertx> future = Vertx.clusteredVertx(options.setClusterManager(clusterManager));
构建器模式提供了一种清晰简单的替代方案,用于分离配置和定制。
Future<Vertx> f = Vertx
.builder()
.with(options)
.withClusterManager(clusterManager)
.buildClustered();
在 Vert.x 5 中,此模式已尽可能地被采纳,并将按组件详细说明。
Vert.x 命令行工具移除
vertx
命令行工具已在 Vert.x 5 中移除。
我们希望专注于典型的 Vert.x 应用程序用例:编译并可选择打包为可执行的 uber-jar。
您可以使用 Maven 和 Vert.x Maven 插件来完成此操作。该插件可以在您的仓库中创建新的 Maven 项目或更新现有项目。
除了将应用程序打包为可执行的 uber-jar 之外,它还可以在开发模式下启动您的应用程序(当检测到文件更改时重新部署主 verticle)。
如果您是 Gradle 用户,Vert.x Gradle 插件提供了类似的功能。
CLI 框架弃用
CLI 框架在 Vert.x 5 中已被弃用。这包括基于它的 io.vertx.core.Launcher
类。
如果您的应用程序是命令行工具或需要一个,请查看 Picocli 等替代方案。事实上,在许多方面,Picocli 比 Vert.x CLI 框架更灵活、更强大。
Vert.x 旧版 CLI
如果在评估替代方案时,您需要保留 CLI 框架功能,可以通过将此依赖项添加到您的项目(Maven)中来实现:
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-launcher-legacy-cli</artifactId>
<version>5.0.0</version>
</dependency>
这个新项目包含旧版 CLI 框架,包括 io.vertx.core.Launcher
类。
请注意,不能保证在 Vert.x 5 的整个生命周期内都能保持向后兼容性。
Vert.x 应用程序启动器
在 Vert.x 5 中,一个新的模块,即 Vert.x 应用程序启动器,取代了 Vert.x 4.x 的 io.vertx.core.Launcher
类。
首先,您必须将其添加到项目的依赖项中(Maven)
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-launcher-application</artifactId>
<version>5.0.0</version>
</dependency>
要启动应用程序,请使用 io.vertx.launcher.application.VertxApplication
作为主类。
# 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
如果您的应用程序打包为可执行 JAR,并且在 META-INF/MANIFEST.MF
文件中将 Main-Class
属性设置为 io.vertx.launcher.application.VertxApplication
,则命令可以简化。
java -jar myapp.jar my.app.MainVerticle
Vert.x 5 应用程序启动器不支持文件更改时 verticle 的实时重新部署。如果您在开发阶段需要此功能,并且您的项目是使用 Maven 构建的,请查看 Vert.x Maven 插件。
Vert.x 核心
Vert.x 实例定制
Vertx
实例可以通过一些可变部分进行定制
-
集群管理器
-
指标工厂
-
跟踪工厂
在 Vert.x 5 中,通过 VertxBuilder
实现定制。
// 4.x
Future<Vertx> f = Vertx.clusteredVertx(
new VertxOptions().setClusterManager(clusterManager)
);
// 5.0
Future<Vertx> f = Vertx
.builder()
.withClusterManager(clusterManager)
.buildClustered();
同样,指标和跟踪工厂的配置方式也类似
// 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();
Vert.x 的跟踪实现已相应更新,以支持为此目的使用跟踪器实现进行定制
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
.setTracingOptions(
new OpenTelemetryOptions(openTelemetry)
)
);
// 5.0
Vertx vertx = Vertx.builder()
.withTracer(new OpenTelemetryTracingFactory(openTelemetry))
.build();
Vert.x 的指标实现已相应更新,以支持为此目的使用指标实现进行定制
// 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 相关更改
HTTP/2 连接关闭处理程序
HTTP/2 连接关闭处理程序在连接开始关闭时通知处理程序,以前是所有连接流关闭后才通知处理程序。旧的行为可以通过连接关闭处理程序获得。
这使得可以感知连接关闭并采取适当措施停止正在处理中的流。它也与其它关闭处理程序的行为保持一致。
移除不带时间单位的 HTTP 连接关闭变体
HttpConnection#shutdown(long)
变体已被移除,取而代之的是 HttpConnection#shutdown(long, TimeUnit)
。
// 4.x
connection.shutdown(5 * 1000); // 5 seconds
// 5.0
connection.shutdown(5, TimeUnit.SECONDS); // 5 seconds
移除带有字符串 authority 的 HTTP 服务器响应推送方法
带有字符串 authority 的 HttpServerResponse#push
方法已被移除,取而代之的是使用 HostAndPort
类型作为 authority 的相同方法。
// 4.x
response.push(httpMethod, authorityAsString path);
// 5.0
response.push(httpMethod, HostAndPort.parse(authorityAsString) path);
移除 HTTP 服务器请求 cookie 映射方法
已弃用的 HttpServerRequest#cookieMap
方法已被移除,应使用 HttpServerRequest#cookies
方法。
// 4.x
Map<String, Cookie> cookieMap = request.cookieMap();
// 5.0
Set<Cookie> cookies = request.cookies();
HTTP/2 流使用统一字节分发器
默认的流字节分发器使用流优先级来确定每个流要发送的字节量,此更改允许使用不使用流优先级且性能更好的策略,因为它消耗更少的 CPU。
默认实现现在是 UniformStreamByteDistributor
而不是 WeightedFairQueueByteDistributor
。
将 HttpClientRequest setTimeout 重命名为 setIdleTimeout
请求超时实际上是空闲超时,为了避免混淆,已将其重命名。
// 4.x
request.setTimeout(timeout);
// 5.0
request.setIdleTimeout(timeout);
移除 HttpClient WebSocket 方法
HttpClient
WebSocket 方法已移至新的 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 客户端定制
HttpClient
定制方法已移至新的 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 清理
在 Vert.x 4.x 中,HttpClient
API 暴露了两个不同的 API
-
HTTP 交互,如
request
方法。 -
HTTP 客户端操作,如
updateSSLOptions
自 Vert.x 5 起,HttpClient
只保留 HTTP 交互,一个新的 HttpClientAgent
API 扩展了 HttpClient
并暴露了这些方法
// 4.x
HttpClient client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);
// 5.0
HttpClientAgent client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);
HttpClient 连接池配置
在 Vert.x 4.x 中,HttpClientOptions
配置 HTTP/1.x 和 HTTP/2 连接池。
自 Vert.x 5 起,此配置通过 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)
);
移除 HttpServerResponse close 方法
HttpServerResponse
的 close 方法会关闭 HTTP 连接,这可能会引起误解,因为有更好的 API 可以与当前请求/连接生命周期进行交互,即 HttpServerResponse#reset
和 HttpConnection#close
。
当必须关闭实际 HTTP 连接时
// 4.x
response.close();
// 5.0
request.connection().close();
当必须处理当前请求/响应时
// 4.x
response.close();
// 5.0
response.reset();
HTTP 流异步方法现在返回 Future 而不是流式接口
为了指示完成结果,一些方法的流式返回类型已更改为 Future 类型
-
writeCustomFrame
-
writeContinue
-
reset
// 4.x
response.writeCustomFrame(12, 134, expectedRecv).end();
// 5.0
response.writeCustomFrame(12, 134, expectedRecv);
response.end();
新的 authority 属性取代 host/port
HttpClientRequest
和 HttpServerRequest
使用客户端请求的 host/port 组合和服务器的单个 host 头来暴露请求的 authority。此外,此术语与实际的服务器 host 和 port 也容易混淆。
这些被新的 authority 属性取代
// 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 请求和 WebSocket 流移除
HttpServer#requestStream()
和 HttpServer#timeoutStream()
已被移除。这些流是为类似 Rx 的语言设计的,但实际上并未提供任何好处。
// 4.x
server.requestStream().handler(request -> ...);
// 5.0
server.requestHandler(request -> ...).listen();
移除服务器 WebSocket 握手方法
服务器 WebSocket API 可以隐式(例如,发送消息)或显式(接受或任何 WebSocket 交互)控制握手。这导致了比此类 API 应有的更复杂的实现。
这两个步骤现在是分开的
-
WebSocket 握手处理程序根据应用程序特定的标准接受或拒绝服务器 WebSocket 连接
-
WebSocket 处理程序配置 WebSocket 并照常执行交互
// 4.x
server.webSocketHandler(ws -> {
ws.handler(msg -> ...);
ws.accept();
ws.write();
};
// 5.0
server.webSocketHandshakeHandler(handshake -> {
handshake.accept();
});
server.webSocketHandler(ws -> {
ws.handler(msg -> ...);
ws.write();
};
// 4.x
server.webSocketHandler(ws -> {
ws.reject();
};
// 5.0
server.webSocketHandshakeHandler(handshake -> {
handshake.reject();
});
Future
CompositeFuture 原始 Future 类型移除
CompositeFuture
方法声明了原始的 Future
类型,例如 all(Future,Future)
或 all(List<Future>>)
,这种声明在使用 List<Future<Something>>
时强制用户进行类型转换。这些方法已使用通配符类型完全泛化。
List<Future<User>> users = ...
// 4.x
CompositeFuture cf = CompositeFuture.all((List<Future>)users);
// 5.0
CompositeFuture cf = Future.all(users);
移除以函数作为参数的 Future eventually 方法
Future#eventually
方法以 Function<Void, Future<T>>
作为参数,这是为不支持 Supplier
的代码生成而开发的。自 Vert.x 4.x 以来,Future
对象不再进行代码生成,因此我们可以使用更合适的 Supplier
。
// 4.x
future.eventually(v -> someFuture());
// 5.0
future.eventually(() -> someFuture());
日志
Vert.x 4 中 Vert.x 日志 API 的使用已减少到仅供 Vert.x 组件内部使用,换句话说,该 API 已成为 Vert.x 的内部 API。
io.vertx.core.logging.Logger
和 io.vertx.core.logging.LoggerFactory
已被弃用,以劝阻使用此 API。相反,应使用 Log4j 2 或 SLF4J 等日志 API。
当然,Vert.x 日志后端的配置仍然像往常一样完全支持,例如 vertx.logger-delegate-factory-class-name
系统属性。
系统属性
Vert.x 5 中移除了一些系统属性。
名称 | 注释 |
---|---|
| Vert.x 3.x Json 支持 RFC-7493,但 JSON 编码器/解码器格式不正确。需要与 Vert.x 3.x 应用程序互操作的用户应将系统属性 |
| 未使用,既未文档化也未测试。 |
| 未使用,既未文档化也未测试。 |
| Vert.x HTTP/1.1 服务器包含一个隐藏选项,用于检测 Adobe Flash 客户端并返回策略文件响应。此选项仅由源文件中引用的系统属性 |
| 此系统属性未被文档化,并且仅在 |
| 应使用 |
工作 Verticle
移除部署 worker 属性
自引入新的 ThreadingModel
以来,DeploymentOptions#setWorker
和 DeploymentOptions#getWorker
方法已被移除。
// 4.x
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setWorker(true, ...)
// 5.0
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setThreadingModel(ThreadingModel.WORKER, ...)
工作线程事件循环分配
自 Vert.x 5 起,工作线程部署为所有工作 verticle 使用单个事件循环,而不是每个工作实例一个事件循环。
以前,这是遵循事件循环部署的,为可伸缩性目的,每个 verticle 实例使用一个事件循环。
事件总线变化
消息消费者动态最大缓冲消息移除
事件总线消息消费者具有动态最大缓冲消息上限。相反,这应该在创建消费者时进行配置。
// 4.x
eventBus.consumer(ADDRESS, msg -> ...).setMaxBufferedMessages(2000);
// 5.0
eventBus.consumer(new MessageConsumerOptions()
.setAddress(ADDRESS)
.setMaxBufferedMessages(2000)
, msg -> ...);
文件系统
文件系统删除方法中的 recursive 布尔值移除
FileSystem#deleteRecursive(…)
方法声明了一个 recursive
布尔值,它与调用 FileSystem#delete
几乎相同,因此用户应直接调用 delete
或 deleteRecursive
// 4.x
stream.deleteRecusrive(path, false);
// 5.0
stream.delete(path);
同样,
// 4.x
stream.deleteRecursive(path, true);
// 5.0
stream.deleteRecursive(path);
杂项
NetServer 连接流移除
NetServer#connectStream()
已被移除。此流是为类似 Rx 的语言设计的,但实际上并未以 API 为代价提供任何好处。
// 4.x
server.connectStream().handler(socket -> ...);
// 5.0
server.connectHandler(socket -> ...).listen();
NoStackTraceThrowable 更改
`Future#fail(String msg)` fail the future with a `NoStackTraceThrowable` wrapping the error message.
当虚拟线程等待 Future 的结果时,如果发生故障,会重新抛出 NoStackTraceThrowable
,这会强制虚拟线程捕获 Throwable
实例。
自 Vert.x 5 起,NoStackTraceThrowable
的超类是 VertxException
。
// 4.x
try {
future.await();
} catch(Throwable t) {
...
}
// 5.0
try {
future.await();
} catch(Exception t) {
...
}
这影响了 Vert.x 虚拟线程和 Kotlin 协程的使用。
TimeoutStream 移除
TimeoutStream
已被移除。此流是为类似 Rx 的语言设计的,但实际上并没有以牺牲 API 为代价提供任何好处。相反,应使用框架调度器和 Vert.x 上下文。
// 4.x
vertx.periodicStream(1L).handler(timerID -> ...);
// 5.0
server.setPeriodic(1L, timerID -> ...);
对于 RxJava 类似集成
// 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);
上下文本地存储更改
旧版上下文本地存储 API 已从公共 API 中移除。
以下方法已移至 io.vertx.core.internal.ContextInternal
接口,并可能随时在 Vert.x 5 中移除。
上下文本地存储与以前的 API 非常相似
// 4.x
context.putLocal("custom", new CustomLocal());
// 5.0
context.putLocal(CustomLocal.KEY, new CustomLocal());
必须进行适当的自定义本地声明
public class CustomLocal implements VertxServiceProvider {
public static final ContextLocal<CustomLocal> KEY = ContextLocal.registerLocal(CustomLocal.class);
/*
Holds some state
*/
}
此类提供者必须在 META/INF/services/io.vertx.core.spi.VertxServiceProvider
中声明为 Java 服务提供者,并可选择在 module-info.java
中声明。
keyCertOptions 密钥管理器映射器移除
KeyCertOptions#keyManagerMapper()
方法已在 Vert.x 5 中移除,实现者必须转而实现 keyManagerFactoryMapper
方法,该方法提供了将 KeyManagerFactory
缓存到控制密钥管理器生命周期的实现者的机会。
移除带 Promise 处理程序的阻塞执行方法
用于执行阻塞操作的 API 使用带处理程序完成或失败 Promise 的模式,这可以替换为返回相同值或抛出异常的 java.util.concurrent.Callable
。
// 4.x
Future<String> fut = vertx.executeBlocking(promise -> promise.complete("result"));
// 5.0
Future<String> fut = vertx.executeBlocking(() -> "result");
processArgs 方法已弃用
io.vertx.core.Context#processArgs
和 io.vertx.core.AbstractVerticle#processArgs
已弃用。
自版本 5 起,Vert.x 不再与 CLI 紧密耦合。
Netty 类型使用移除
Vert.x API 在其公共 API 中暴露了 Netty API,允许与 Netty API 进行交互。由于 Netty 正在向 Netty 5 发展,我们应该在 Vert.x 5 中从 Vert.x 公共 API 中移除 Netty API,以便有机会更改 Vert.x 使用的底层 Netty 版本,而不必担心 Netty 版本。
此类 API 在 Vert.x 5 中仍然存在,但已移至内部 API,不具有契约性,因此使用此 API 的有经验的用户可以继续使用它,前提是 Vert.x 5 版本使用 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 剪枝
io.vertx.ext.auth.AuthProvider
已在 Vert.x 4.0 中弃用,取而代之的是 io.vertx.ext.auth.authentication.AuthenticationProvider
。
// 4.x
AuthProvider authProvider = ...
// 5.0
AuthenticationProvider authProvider = ...
Vert.x for Kotlin
移除 await 扩展方法生成
Vert.x 4.x for Kotlin 生成挂起扩展方法,以方便调用 Vert.x 异步方法。
suspend fun HttpServer.listenAwait(port: Int, host: String): HttpServer {
return awaitResult {
this.listen(port, host, it)
}
}
此类方法已弃用,因为可以使用 Vert.x Future 实例实现相同效果,并在 Vert.x 5 中移除。
// 4.x
server.listenAwait(port, host)
// 5.0
server.listen(host, port).coAwait()
Vert.x gRPC
移除 GrpcReadStream#collecting,取而代之的是 ReadStream#collect
// 4.x
stream.collecting(collector);
// 5.0
stream.collect(collector);
移除声明方法描述符的方法
声明 MethodDescriptor
的 GrpcClient
/GrpcServer
方法已被移除。
相反,这些方法现在在扩展 GrpcClient
/GrpcServer
接口的 GrpcIoClient
/GrpcIoServer
接口中可用。
// 4.x
GrpcServer server = GrpcServer.create(vertx);
// 5.0
GrpcIoServer server = GrpcIoServer.create(vertx);
server.callHandler(methodDescriptor, request -> ...);
Vert.x Web
RoutingContext 用户 API
用户相关操作已移至可从 RoutingContext
访问的单个上下文 API 下
注销
// 4.x
routingContext.clearUser();
// 5.0
UserContext userContext = routingContext.userContext();
userContext.logout();
设置用户
RoutingContext#setUser
方法已被移除,此操作应由身份验证处理程序执行。
静态处理程序配置
StaticHandler
方法 setAllowRootFileSystemAccess
和 setWebRoot
在 Vert.x 4.x 中弃用后已移除。
相反,处理程序必须在创建时配置
// 4.x
StaticHandler handler = StaticHandler.create().setAllowRootFileSystemAccess(true).setWebRoot(root);
// 5.0
StaticHandler handler = StaticHandler.create(FileSystemAccess.ROOT, root);
解包模板引擎
模板引擎获取底层引擎实例的方法在弃用后已移除
-
HandlebarsTemplateEngine#getHandlebars
-
ThymeleafTemplateEngine#getThymeleafTemplateEngine
应使用 TemplateEngine#unwrap
。
// 4.x
Handlebars handlebarsUnwrapped = handlebarsTemplateEngine.getHandlebars();
TemplateEngine thymeleafUnwrapped = thymeleafTemplateEngine.getThymeleafTemplateEngine();
// 5.0
handlebarsUnwrapped = handlebarsTemplateEngine.unwrap();
thymeleafUnwrapped = thymeleafTemplateEngine.unwrap();
CORS 正则表达式来源
基于正则表达式来源的方法的命名已更改,以与框架的其余部分保持一致
-
CorsHandler#addRelativeOrigin
-
CorsHandler#addRelativeOrigins
应使用 addOriginWithRegex
或 addOriginsWithRegex
。
// 4.x
CorsHandler.addRelativeOrigin(".*");
CorsHandler.addRelativeOrigins(List.of(".*", "https?://.*"));
// 5.0
CorsHandler.addOriginWithRegex(".*");
CorsHandler.addOriginsWithRegex(List.of(".*", "https?://.*"));
Vert.x Web 客户端
响应预期替换
Vert.x Core 引入了一个新的 API,用于实现受 Web 客户端响应预期功能启发的预期检查。
Vert.x HTTP 客户端附带与 Web 客户端响应预期相同的预定义预期集,更重要的是 HTTP 客户端响应预期可由 Web 客户端重复使用。
HTTP 响应预期利用了新的 Future#expecting
操作与 HttpResponseExpectation
实现的组合。
// 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
升级到 GraphQL-Java 23
Vert.x Web GraphQL 已从 GraphQL-Java 20 升级到 GraphQL-Java 23。
GraphQL-Java 22 和 23 是重大变更版本
Vert.x Web 验证
替换已弃用的 SchemaParser
Vert.x Web Validation 曾基于已弃用的 JSON Schema API,该 API 在 Vert.x 5 中不再可用。
// 4.x
ValidationHandlerBuilder.create(schemaParser)
// 5.0
SchemaRepository schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7));
ValidationHandlerBuilder.create(schemaRepo);
为了提高安全性,新的 SchemaRepository 不会自动加载外部引用。如果您的模式包含外部引用,您必须预先提供并解引用它们。 |
Vert.x SQL 客户端
客户端构建器
Pool
子类型并没有真正的用处,因为它们不携带任何额外的方法,主要用于静态构建池。
此外,由于重载,这些静态方法不够灵活且数量众多。
我们正在用新的客户端构建器 API 替换这些方法。
// 4.x
PgPool client = PgPool.pool(vertx, connectOptions, poolOptions);
//5.0
Pool client = PgBuilder.pool()
.with(poolOptions)
.connectingTo(connectOptions)
.using(vertx)
.build();
连接选项
SqlConnectOptions
类不再继承 NetClientOptions
类。
SqlConnectOptions
TLS 配置仍在此类上进行。
// 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))
);
通过 ClientBuilder
,仍然可以在构建客户端时传递 NetClientOptions
。
// 5.0
Pool pool = PgBuilder.pool()
.connectingTo(connectOptions)
.with(tcpOptions)
.build();
池连接处理程序
Pool#connectHandler
方法已移至新的 ClientBuilder
,处理程序在构建时设置一次,而不是作为池实现的 mutable 字段。
// 4.x
pool.connectHandler(connectHandler);
// 5.0
builder.connectHandler(connectHandler);
池连接提供者
Pool#connectionProvider
方法被 Supplier<Future<SqlConnectOptions>>
构建器方法取代。
// 4.x
pool.connectionProvider(ctx -> futureOfSqlConnection(ctx));
// 5.0
builder.connectingTo(() -> futureOfSqlConnectOptions());
Vert.x Mongo 客户端
升级到 MongoDB Java Driver 5
MongoDB Java Driver 5.x 是一个重大变更版本。
在 IndexOptions
中,bucketSize
已被移除。
此外,StreamFactoryFactory
已被 TransportSettings
取代,并且 Netty 是唯一可用的传输方式。
Vert.x Redis 客户端
移除请求空参数
Redis 不接受请求中的 null
值。因此,Request#nullArg()
方法将 null
编码为 4 个字符的 "null"
字符串。
此方法在 4.x 中已弃用,现已移除。所有以前用于编码 null
值的地方现在都会抛出 IllegalArgumentException
。
如果您在 Redis 请求中使用 null
值,则应停止这样做。要恢复以前的行为,您应手动将 null
值编码为 "null"
。这适用于
-
Request.arg(String)
-
Request.arg(Buffer)
-
Request.arg(JsonArray)
:数组本身和单个元素 -
Request.arg(JsonObject)
:对象本身和单个元素
Redis 订阅自动转发到 Vert.x 事件总线
在 Vert.x 4.x 中,Redis 订阅会自动转发到事件总线,除非明确设置了消息处理程序(使用 RedisConnection.handler()
)。
现在情况不再如此。自 Vert.x 5 起,您始终必须注册消息处理程序。如果您仍希望将订阅消息转发到事件总线,则必须手动创建 EventBusHandler
实例并使用 RedisConnection.handler()
进行注册。
RedisConnection conn = ...;
conn.handler(EventBusHandler.create(vertx));
conn.send(Request.cmd(Command.SUBSCRIBE).arg("news"));
此外,EventBusHandler
不仅转发消息([p]message
);它还转发订阅和取消订阅([p]subscribe
和 [p]unsubscribe
)。
RedisCluster.groupByNodes() 返回类型更改 + 代码生成更改
RedisCluster#groupByNodes()
方法过去返回 Future<List<List<Request>>>
。由于此返回类型,RedisCluster
未标记为 @VertxGen
。
这在 Vert.x 5 中发生了变化。groupByNodes()
方法现在返回 Future<RequestGrouping>
,并且整个接口都标记为 @VertxGen
。
此外,Request
、Response
和 Command
接口不再标记为 @VertxGen
,而是标记为 @DataObject
。这意味着代码生成 API(如 Vert.x Rx)的用户将不再使用生成的包装器;他们将使用核心 Vert.x Redis 接口。
RedisOptions 的 JSON 序列化/反序列化
RedisOptions
类有多种方法来配置 Redis 端点。这些方法仍然可用,但此类的 JSON 格式已更改,只包含一个规范字段:endpoints
。
如果您依赖 RedisOptions
对象的 JSON 格式,请注意 JSON 对象的 endpoint
、connectionString
和 connectionStrings
成员不再被反序列化器识别,也不再被序列化器生成。请确保必要的信息存在于 endpoints
成员中。
Options addEndpoint/setEndpoint 替换
RedisOptions#addEndpoint
和 RedisOptions#setEndpoint
被 RedisOptions#addConnectionString
和 RedisOptions#setConnectionString
替换。
// 4.x
options.setEndpoint(location);
// 4.x
options.setConnectionString(location);
Vert.x RabbitMQ 客户端
4.x RabbitMQ 客户端库提供了 RabbitMQ API 的高级抽象,但不幸的是,这使得一些 RabbitMQ 用法变得不可能。这意味着 5.0 RabbitMQ 客户端库是完全重写的,具有非常不同的 API。
建立连接
4.x RabbitMQ 客户端库使用单个 RabbitMQClient 封装连接和通道,而 5.0 客户端库则将这两者分开处理,并且每个连接可以有多个通道。
5.0 RabbitMQChannel 的 API 与 4.x RabbitMQClient 最接近。
// 4.x
RabbitMQOptions config = new RabbitMQOptions();
// full amqp uri
config.setUri("amqp://xvjvsrrc:VbuL1atClKt7zVNQha0bnnScbNvGiqgb@brokerhost/vhost");
RabbitMQClient client = RabbitMQClient.create(vertx, config);
// Connect
client.start(asyncResult -> {
if (asyncResult.succeeded()) {
logger.info("RabbitMQ successfully connected!");
} else {
logger.warning("Failed to connect to RabbitMQ: {0}", asyncResult.cause().getMessage());
}
});
// 5.0
RabbitMQOptions config = new RabbitMQOptions();
config.setUri("amqp://brokerhost/vhost");
config.setConnectionName(this.getClass().getSimpleName());
config.setUser("guest");
config.setPassword("guest");
RabbitMQClient.connect(vertx, config)
.compose(connection -> {
RabbitMQChannelBuilder builder = connection.createChannelBuilder();
return builder.openChannel();
})
.onSuccess(channel -> logger.info("Channel opened: {0}", channel.getChannelId()))
.onFailure(ex -> logger.warning("Failed to connect to RabbitMQ: {0}", ex))
;
连接建立回调
一个具有自动重连功能的异步 RabbitMQ 客户端必须提供一种在通道可用之前创建交换机和队列的方法。在 4.x 库中,这是通过添加到 RabbitMQClient 的单个 connectionEstablishedCallback 完成的;对于 5.0 库,这是通过 channelOpenHandler 完成的,该处理程序必须在通道打开之前声明。
4.x 的 connectionEstablishedCallback 传入 RabbitMQClient,而 5.0 库在调用 channelOpenHandler 时 RabbitMQChannel 尚未建立,因此它传入原始的 com.rabbitmq.client.Channel。channelOpenHandler 在阻塞处理程序内部调用。
// 4.x
RabbitMQClient client = RabbitMQClient.create(vertx, config);
client.addConnectionEstablishedCallback(promise -> {
client.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, EXCHANGE_DURABLE, EXCHANGE_AUTO_DELETE)
.compose(v -> {
return client.queueDeclare(QUEUE_NAME, QUEUE_DURABLE, QUEUE_EXCLUSIVE, QUEUE_AUTO_DELETE);
})
.compose(declareOk -> {
return client.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
})
.onComplete(promise);
});
// 5.0
RabbitMQClient.connect(vertx, config)
.compose(connection -> {
return connection.createChannelBuilder()
.withChannelOpenHandler(chann -> {
chann.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, EXCHANGE_DURABLE, EXCHANGE_AUTO_DELETE, null);
chann.queueDeclare(QUEUE_NAME, QUEUE_DURABLE, QUEUE_EXCLUSIVE, QUEUE_AUTO_DELETE, null);
chann.queueBind(QUEUE_NAME, EXCHANGE_NAME, "", null);
})
.openChannel();
})
;
消费
5.0 库的 RabbitMQChannel 对象暴露了 basicConsume 方法,但建议使用 RabbitMQConsumer 以 Vert.x ReadStream 的形式提供消息。
除非每条消息都能同步处理而没有任何阻塞调用,否则消费者中可能会同时有多个消息在处理中。使用 RabbitMQ QOS 限制客户端接收的消息数量非常重要。
注意使用 STRING_MESSAGE_CODEC 在调用回调之前将消息体转换为字符串。
// 4.x
client.basicConsumer(QUEUE_NAME, rabbitMQConsumerAsyncResult -> {
if (rabbitMQConsumerAsyncResult.succeeded()) {
RabbitMQConsumer mqConsumer = rabbitMQConsumerAsyncResult.result();
mqConsumer.handler(message -> {
System.out.println("Got message: " + message.body().toString());
});
}
});
// 5.0
connection.createChannelBuilder()
.withQos(0, 10)
.createConsumer(RabbitMQChannelBuilder.STRING_MESSAGE_CODEC
, QUEUE_NAME
, null
, new RabbitMQConsumerOptions()
, (consumer, message) -> {
System.out.println("Got message: " + message.body());
return message.basicAck();
});
发布
RabbitMQ 为消息提供两个选项:它可以保证消费者最多接收一次消息,或者它可以保证消费者至少接收一次消息。前者是默认选项,除了调用 basicPublish 之外不需要任何操作,但已发布的消息可能会丢失且根本不会传递。
为了保证消息被接收,发布者必须等待 RabbitMQ 的确认——如果该确认在与代理的连接断开之前没有到达,发布者必须在代理返回时重新发送消息。
Vert.x RabbitMQ 库提供了一个 RabbitMQPublisher,以简化确认的异步处理。
// 4.x
Map<String, JsonObject> messages = ...
RabbitMQPublisher publisher = RabbitMQPublisher.create(vertx, client, options);
publisher.getConfirmationStream().handler(conf -> {
if (conf.isSucceeded()) {
messages.remove(conf.getMessageId());
}
});
messages.forEach((k,v) -> {
com.rabbitmq.client.BasicProperties properties = new AMQP.BasicProperties.Builder()
.messageId(k)
.build();
publisher.publish(EXCHANGE_NAME, ROUTING_KEY, properties, v.toBuffer());
});
// Wait for messages to be empty
// 5.0
Map<String, JsonObject> messages = ...
RabbitMQClient.connect(vertx, config)
.compose(connection -> {
return connection.createChannelBuilder()
.createPublisher(EXCHANGE_NAME
, RabbitMQChannelBuilder.JSON_OBJECT_MESSAGE_CODEC
, new RabbitMQPublisherOptions().setResendOnReconnect(true)
);
})
.compose(publisher -> {
List<Future<Void>> futures = new ArrayList<>(messages.size());
messages.forEach((k,v) -> {
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
.messageId(k)
.build();
futures.add(publisher.publish(ROUTING_KEY, properties, v));
});
return Future.all(futures);
})
.onSuccess(v -> logger.info("All message sent and confirmed"))
.onFailure(ex -> logger.log(Level.SEVERE, "Failed: {0}", ex))
;
Vert.x Consul 客户端
io.vertx.ext.consul.AclToken
已被移除,应使用 io.vertx.ext.consul.token.AclToken
。
这些已弃用的 API 方法已被移除
-
Check#getNodeName()
,应使用Check#getNode()
。 -
ConsulClient#createAclToken(io.vertx.ext.consul.AclToken)
,应使用createAclToken(io.vertx.ext.consul.token.AclToken)
-
ConsulClient#updateAclToken(io.vertx.ext.consul.AclToken)
,应使用updateAclToken(String, io.vertx.ext.consul.token.AclToken)
-
ConsulClient#cloneAclToken(String)
,应使用cloneAclToken(String, CloneAclTokenOptions)
-
ConsulClient#infoAclToken(String)
,应使用readAclToken(String)
-
ConsulClient#destroyAclToken(String)
,应使用deleteAclToken(String)
-
ConsulClient#listAclTokens()
,应使用getAclTokens()
Vert.x 健康检查
健康检查依赖项改进
以前,Vert.x 健康检查依赖于 Vert.x Web 和 Vert.x Auth。它现在只定义健康检查 API,健康检查路由处理程序已移至 Vert.x Web。
这导致导入声明中的包更改。
// 4.x
import io.vertx.ext.healthchecks.HealthCheckHandler;
// 5.0
import io.vertx.ext.web.healthchecks.HealthCheckHandler;
Vert.x 断路器
移除已弃用并计划移除的重试策略
带有 Java 函数参数的断路器重试策略在 4.x 中弃用后已移除。
应使用 RetryPolicy
函数式接口。
// 4.x
breaker.retryPolicy(retryCount -> 5);
// 5.0
breaker.retryPolicy((failure, retryCount) -> 5);
Vert.x MQTT
客户端选项将消息字符串 getter/setter 弃用移除
客户端选项的 will 消息 string getter/setter 已在 4.x 中弃用后移除。
应使用 Buffer
版本。
// 4.x
options.setWillMessage(str);
// 5.0
options.setWillMessageBytes(Buffer.buffer(str));
Vert.x 邮件客户端
移除已弃用的 MailConfig setKeyStore/setKeyStorePassword
移除已弃用的 MailConfig#setKeyStore
和 MailConfig#setKeyStorePassword
属性。
应使用 MailConfig#setTrustOptions。
// 4.x
options.setKeyStore(trustStorePath);
options.setKeyStorePassword(trustStorePassword);
// 5.0
options.setTrustOptions(new JksOptions().setPath(trustStorePath).setPassword(trustStorePassword));
Vert.x JUnit 5
移除已弃用的测试上下文 succeeding
应使用 succeedingThenComplete()
或 succeeding(Handler)
。
// 4.x
someFuture.onComplete(testContext.succeeding());
// 5.0
someFuture.onComplete(testContex.succeedingThenComplete());
Vert.x 服务代理
ServiceAuthInterceptor 移除
应使用 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 函数式拦截器
ServiceBinder#addInterceptor(Function)
和 ServiceBinder#addInterceptor(String, Function)
已被移除,取而代之的是带有 ServiceInterceptor
函数式接口的变体。
// 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));
移除 ProxyHelper 工具类
ProxyHelper
工具类已被移除,取而代之的是 ServiceProxyBuilder
/ ServiceBinder
等效类。
// 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 响应式扩展
数据对象更改
Vert.x 中一些历史上被 @VertxGen
注解并因此被认为是异步类型的类已被转换为数据对象。
因此,类似生成器的响应流将不再需要包装/解包此类型,从而避免不必要的分配。
这意味着这些对象不再被 Vert.x RX 包装,并且其类型包名将发生更改。
以下类已升级为数据对象
-
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
在上述所有类型中,Vert.x buffer 类型可能是影响最大的更改。
io.vertx.core.buffer.Buffer
历史上一直作为异步生成类型的一部分存在于 API 中,并用 @VertxGen
注解。它一直被响应流生成器包装/解包。
// 4.x
io.vertx.reactivex.core.buffer.Buffer buffer = rxApi.getBuffer();
// 5.0
io.vertx.core.buffer.Buffer buffer = rxApi.getBuffer();
或
// 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"));
同样适用于其他提到的类型。
Vert.x Micrometer 指标
升级到 Micrometer 1.14
Micrometer 1.14 紧随 1.13 之后发布,如果您在代码中使用了 PrometheusMeterRegistry API,1.13 是一个重大变更版本。
请查看 Micrometer 的迁移指南。
HTTP 客户端连接池指标
HTTP 客户端连接池指标现在以池类型 http 的通用连接池指标形式公开
-
vertx_http_client_queue_pending
→vertx_pool_queue_pending
-
vertx_http_client_queue_time_seconds
→vertx_pool_queue_time_seconds
移除选项上的注册表设置
用于 MeterRegistry
的 micrometer 选项设置器已移除,取而代之的是新的 VertxBuilder
和 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();
移除 InfluxDB 选项线程数
VertxInfluxDbOptions#getNumThreads
和 VertxInfluxDbOptions#setNumThreads
不再使用。
// 4.x
influxDbOptions.setNumThreads(numThreads);
// 5.0
重命名指标选项请求标签提供者
VertxMicrometerMetricsOptions#setRequestTagsProvider
和 VertxMicrometerMetricsOptions#getRequestTagsProvider
已移除,取而代之的是 VertxMicrometerMetricsOptions#setServerRequestTagsProvider
和 VertxMicrometerMetricsOptions#getServerRequestTagsProvider
。
// 4.x
options.setRequestsTagsProvider(provider);
// 5.0
options.setServerRequestsTagsProvider(provider);
默认启用的指标标签变化
由于高基数风险,HTTP ROUTE
标签不再默认启用。
要启用它,您必须在启动时修改指标选项
options.addLabels(Label.HTTP_ROUTE);
POOL NAME
标签现在默认启用。
Vert.x Dropwizard 指标
HTTP 客户端连接池指标
HTTP 客户端连接池指标现在以通用连接池指标形式公开,池类型为 http
,并以端点套接字地址命名。
-
endpoint.<host:port>.queue-delay
→queue-delay
-
endpoint.<host:port>.queue-size
→queue-size
移除度量选项中设置度量注册表
用于 MetricsRegistry
的 dropwizard 选项设置器已被移除,取而代之的是新的 VertxBuilder
和 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
弃用 API 移除
在 Vert.x 5 中,已弃用的 JSON Schema API 已被移除。以前,每个 Draft 都有自己的 SchemaParser
。现在您有一个 SchemaRepository
,并且可以在选项中设置 Draft。
// 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
}
额外的错误类型
在 Vert.x 5 中,已为输出单元添加了额外的基本错误类型。
如果您正在构建自己的 OutputUnits
,您现在还需要包含 OutputErrorType
。这有助于确定失败的原因。
// 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);
移除 SchemaType INT 常量
应使用 SchemaType#INTEGER
。
移除 ValidationException createException 方法
应使用具有相同签名的 ValidationException#create
替代方法。
Vert.x Hazelcast
升级到 Hazelcast 5.3
此版本包含了自 Hazelcast 4.2.8 以来许多安全修复。它需要 JDK 11 才能运行,这是 Vert.x 5 中最低要求的版本。
集群管理器也已使用 Hazelcast 5.4 和 Hazelcast 5.5 进行测试。但这些版本分别至少需要 JDK 17 和 JDK 21。因此,我们不能默认使用它们。