Spring Boot 如何为命令行应用程序返回退出代码

6
我有一个使用CommandLineRunner实现的Spring Boot应用程序。如果发生任何错误/异常,我希望返回-1作为退出代码,并在没有异常时返回0。
public class MyApplication implements CommandLineRunner{
private static Logger logger = LoggerFactory.getLogger(MyApplication.class);

@Override
public void run(String... args) throws Exception {
    // to do stuff. exception may happen here.
}

public static void main(String[] args) {
    try{
        readSetting(args);
        SpringApplication.run(MyApplication.class, args).close();
    }catch(Exception e){
        logger.error("######## main ########");
        java.util.Date end_time = new java.util.Date();                                         
        logger.error(e.getMessage(), e);
        logger.error(SystemConfig.AppName + " System issue end at " + end_time);
        System.exit(-1);
    }
    System.exit(0);
}
...
}

我已经尝试了System.exit(),SpringApplication.exit(MyApplication.context, exitCodeGenerator)等方法。但是当我抛出异常时,它仍然返回0!
我已经尝试了这里的解决方案:

https://sdqali.in/blog/2016/04/17/programmable-exit-codes-for-spring-command-line-applications/

http://www.programcreek.com/java-api-examples/index.php?class=org.springframework.boot.SpringApplication&method=exit

请帮忙!


也许你应该将 System.exit(-1) 移动到 public void run 中,而不是在主函数中使用它。 - Patrick
谢谢@Patrick,我也试过了,仍然返回0。 - terencefung
你的第一个来源提到了ExitCodeGenerator。你唯一缺少的就是调用SpringApplication.exit方法,详见下面我的回答。 - Maddin
1个回答

13

关于您的问题,这里有一篇很好的文章:https://www.baeldung.com/spring-boot-exit-codes。以下是要点:

@SpringBootApplication
public class CLI implements CommandLineRunner, ExitCodeGenerator {

    private int exitCode; // initialized with 0

    public static void main(String... args) {
        System.exit(SpringApplication.exit(SpringApplication.run(CLI.class, args)));
    }

    /**
     * This is overridden from CommandLineRunner
     */
    @Override
    public void run(String... args) {
        // Do what you have to do, but don't call System.exit in your code
        this.exitCode = 1;
    }

    /**
     * This is overridden from ExitCodeGenerator
     */
    @Override
    public int getExitCode() {
        return this.exitCode;
    }
}

如果你有多个运行程序,这是否是一个有效的解决方案?因为这不会强制退出吗? - Wolsie
@Wolsie 所有的 ExitCodeGenerator 的 getExitCode 函数都被调用,然后由 SpringApplication.exit 返回结果退出码,并传递给 System.exit,从而终止 VM。也就是说,只要没有其他地方有 System.exit,VM 将在所有 ExitGenerators 执行其 getExitCode 函数后终止。 - Maddin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接