You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vert.x应用在Eclipse中可正常关闭,Jar包运行后无法自动退出

Vert.x程序Jar包运行后无法自动退出的解决方案

问题描述

本地Eclipse环境运行时,程序可正常执行并自动关闭;但通过Maven打包为Jar包后,执行java -jar application.jar命令,程序完成请求并输出响应后,无法自动终止,需手动中断。已尝试在onSuccess、onFailure、部署回调及stop()方法中调用System.exit(0),问题仍未解决。

涉及代码

Main类代码

public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    vertx.deployVerticle(new MainVerticle(), whenDeployed -> {
            vertx.close();
//          System.exit(0);
        });
}

MainVerticle类代码

public class MainVerticle extends AbstractVerticle {

    private static final ObjectMapper mapper = new ObjectMapper();
    private static final Logger log = LoggerFactory.getLogger(MainVerticle.class);
    
    @Override
    public void start(Promise<Void> startPromise) throws Exception {
        
        Configuration config = null;
        
        try(FileInputStream fin = new FileInputStream("/opt/vertex-proxy/config.json")){
            config = mapper.readValue(fin, Configuration.class);
            
        } catch(Exception e) {
            log.error("Invalid configuration\n{}", e.getCause());
        }
        
        log.info("Started application\n");
        
        ProxyOptions proxyOptions = new ProxyOptions()
                .setHost(config.getProxy().getIp())
                .setPort(config.getProxy().getPort());
                
        WebClientOptions options = new WebClientOptions().setUserAgent("Yash client")
                .setProtocolVersion(HttpVersion.HTTP_2).setHttp2ClearTextUpgrade(false)
                .setConnectTimeout(config.getTarget().getConnectionTimeout())
                .setProxyOptions(proxyOptions);
        
        WebClient client = WebClient.create(vertx, options);

        
        HttpRequest<Buffer> req = client.get(config.getTarget().getPort(), config.getTarget().getIp(), config.getTarget().getUri());
        
        req.send().onSuccess(response -> {
            log.info("Received response with status code: " + response.statusCode());
            log.info("Response:\n" + response.bodyAsString());
            startPromise.complete();
            
        }).onFailure(err -> {
            log.error("Something went wrong\n" + err.getCause());
            startPromise.complete();
        });
        
    }
    
    @Override
    public void stop() throws Exception {
        System.out.println("\nStopping application");
    }

}

解决思路与方案

核心问题分析

  1. Vert.x的vertx.close()是异步操作,原代码未等待关闭完成就结束主线程,导致事件循环线程仍在运行。
  2. WebClient未显式关闭,持有底层连接资源,阻止JVM退出。
  3. 配置读取失败时未正确处理Promise,导致Verticle启动流程未完成,Vertx无法触发关闭逻辑。

具体调整步骤

  • 等待Vertx关闭完成再退出
    修改Main类的部署回调,监听vertx.close()的完成事件,确保完全关闭后再调用System.exit():

    vertx.deployVerticle(new MainVerticle(), whenDeployed -> {
        vertx.close(closeResult -> {
            System.exit(closeResult.succeeded() ? 0 : 1);
        });
    });
    
  • 显式关闭WebClient释放资源
    在请求成功或失败的回调中,关闭WebClient避免资源泄漏:

    req.send().onSuccess(response -> {
        log.info("Received response with status code: " + response.statusCode());
        log.info("Response:\n" + response.bodyAsString());
        client.close();
        startPromise.complete();
    }).onFailure(err -> {
        log.error("Something went wrong\n" + err.getCause());
        client.close();
        startPromise.complete();
    });
    
  • 修复配置读取异常的Promise处理
    配置读取失败时,标记startPromise为失败并触发Vertx关闭,避免流程阻塞:

    catch(Exception e) {
        log.error("Invalid configuration\n{}", e.getCause());
        startPromise.fail(e);
        vertx.close();
        return;
    }
    
  • 添加Vertx退出钩子兜底
    在Main类中设置退出处理器,确保事件循环全部结束后触发JVM退出:

    Vertx vertx = Vertx.vertx();
    vertx.setExitHandler(exitCode -> {
        System.exit(exitCode);
    });
    

优化后的完整逻辑建议

将Vertx关闭逻辑移至Verticle的请求完成回调中,确保任务结束后才触发关闭,避免提前终止:

// MainVerticle的start方法中,请求完成后
req.send().onSuccess(response -> {
    // ... 日志输出 ...
    client.close();
    startPromise.complete();
    vertx.close(); // 任务完成后主动关闭Vertx
}).onFailure(err -> {
    // ... 日志输出 ...
    client.close();
    startPromise.complete();
    vertx.close();
});

内容的提问来源于stack exchange,提问作者Dominator_007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:35:58