SpringBoot单次执行任务,退出异常NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy

发布时间 2023-08-14 11:22:32作者: bigbigtree

背景

  • 使用SpringBoot 运行一次性作业,用于初始化
  • 问题:直接使用System.exit退出时,遇到异常:NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy

异常信息

Exception in thread "Thread-10" java.lang.NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
	at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
	at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
	at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
	at ch.qos.logback.classic.Logger.log(Logger.java:765)
	at org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog.warn(LogAdapter.java:447)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1013)
	at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:946)
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.spi.ThrowableProxy
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 7 more

解决办法

  • Spring 退出需要清理环境,使用SpringApplication.exit
  • 参考代码
@Slf4j
@SpringBootApplication(exclude = {FreeMarkerAutoConfiguration.class, JacksonConverterAutoConfigurer.class})
@ComponentScan(value = {"XXXX"},
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JacksonConverterAutoConfigurer.class})
)
@MapperScan(basePackages = "XXXX.**.dao")
public class XXX {
    public static void main(String[] args) {
        try (ConfigurableApplicationContext context = SpringApplication.run(XXX.class, args)) {
            XXX xxx = context.getBean(XXX.class);
            xxx.init();
            log.info("Init Over");
            //System.exit(0);
            exitApplication(context);
        } catch (Exception e) {
            log.error(ExceptionUtil.exceptionTrace(e));
            System.exit(1);
        }
    }
    private static void exitApplication(ConfigurableApplicationContext context) {
        int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
        System.exit(exitCode);
    }
}

任务启动方式

java -Dloader.main=XXXTask -cp ./target/xxx.jar  org.springframework.boot.loader.PropertiesLauncher --spring.config.location=xxx.properties