Spring Boot启动前设置系统属性触发ExceptionInInitializerError问题
Spring Boot启动前设置系统属性触发ExceptionInInitializerError的解决方法
问题现象
在基础Spring Boot应用中,调用SpringApplication.run()前通过System.setProperties()设置自定义系统属性时,应用启动失败并抛出ExceptionInInitializerError;移除该设置代码后,应用可正常启动。
代码示例
@SpringBootApplication public class Application { public static void main(String[] args) { // 加入此代码块后应用启动失败 Properties props = new Properties(); props.setProperty("testProperty", "5"); System.setProperties(props); // ======================================== SpringApplication.run(Application.class, args); } }
错误信息
10:56:51.753 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed java.lang.ExceptionInInitializerError: null at org.springframework.boot.context.config.AnsiOutputApplicationListener.onApplicationEvent(AnsiOutputApplicationListener.java:46) at org.springframework.boot.context.config.AnsiOutputApplicationListener.onApplicationEvent(AnsiOutputApplicationListener.java:37) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81) at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64) at java.base/java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:356) at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) at com.demo.test.Application.main(Application.java:35) Caused by: java.lang.NullPointerException: Cannot invoke "String.toLowerCase(java.util.Locale)" because the return value of "java.lang.System.getProperty(String)" is null at org.springframework.boot.ansi.AnsiOutput.<clinit>(AnsiOutput.java:40) ... 18 common frames omitted
原因分析
从错误堆栈可以看到,根源是AnsiOutput初始化时调用System.getProperty()返回null,触发了NullPointerException。问题出在System.setProperties(props)这个方法:它会完全替换JVM原有的系统属性集合,而你新创建的Properties对象只包含自定义的testProperty,丢失了JVM默认的系统属性(比如Spring Boot用于控制Ansi输出的相关属性),导致框架初始化时找不到必要的配置。
解决方法
方法1:单独设置单个属性(推荐)
不要替换整个系统属性集合,直接用System.setProperty()添加或修改单个属性,这种方式会保留原有所有系统属性:
@SpringBootApplication public class Application { public static void main(String[] args) { System.setProperty("testProperty", "5"); SpringApplication.run(Application.class, args); } }
方法2:基于原有属性批量设置
如果需要批量设置多个属性,先获取当前系统属性,再添加自定义属性,最后重新设置:
@SpringBootApplication public class Application { public static void main(String[] args) { Properties props = System.getProperties(); props.setProperty("testProperty", "5"); // 可添加更多属性 // props.setProperty("anotherProperty", "value"); System.setProperties(props); SpringApplication.run(Application.class, args); } }
内容的提问来源于stack exchange,提问作者IceTea
相关产品推荐
相关产品推荐

