# Spring Boot 啟動失敗:StackOverflowError 與循環變數問題紀錄 ## 問題描述 在啟動 Spring Boot 專案時,遇到以下錯誤訊息: ``` *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed ... java.lang.StackOverflowError: null ``` 錯誤訊息中可見關鍵堆疊紀錄: ``` at java.util.regex.Pattern.compile at java.lang.String.matches at com.ulisesbocchio.jasyptspringboot.filter.DefaultPropertyFilter.isMatch ``` 這代表在解析設定時進入了無限遞迴,最終導致 JVM 堆疊溢位。 ## 問題原因 在 application.yml 中,我誤用了變數引用: ``` aaa: bbb: ${aaa.ccc} ccc: ${aaa.bbb} ``` 這造成 aaa.bbb 與 aaa.ccc 互相參考對方,形成循環,導致 Spring Boot 在解析時進入無限迴圈,進而拋出 StackOverflowError。 ## 解析變數的注意事項 1. Spring Boot 屬性綁定不區分大小寫 ``` my: config: value ``` 等同於: ``` MY_CONFIG=value ``` 2. ${} 區塊中使用變數名稱時需注意大小寫一致性 雖然 Spring 本身不區分大小寫,但部分函式庫(如 Jasypt)或外部工具在解析時可能會對大小寫敏感,因此建議要有統一規範。 ✅ 解法 解法一:移除循環引用 將其中一個值改為實際值,避免相互依賴: aaa: ccc: actual-value bbb: ${aaa.ccc} # ✅ 單向依賴可行 解法二:環境變數中避免定義循環變數 如果透過環境變數或其他途徑注入屬性,也需避免以下錯誤用法: AAA_BBB=${AAA_CCC} AAA_CCC=${AAA_BBB} # ❌ 會導致循環 解法三:加上跳過 Jasypt 解密機制(用於偵錯) -Djasypt.encryptor.skip=true 這可以讓你確定是不是 Jasypt 的加密屬性處理導致問題。 🧩 延伸建議 多人協作時統一格式規範,避免出現大小寫或命名不一致問題 而綁定環境變數時,就我目前看到的習慣,通常都是使用大寫+底線 但還是要注意是否會造成無限迴圈 例如以下這樣就會造成問題 ```yaml! my: param: ${MY.PARAM} ``` 📝 總結 這次問題主要源自於設定檔中不小心造成變數的循環引用,導致 Spring Boot 啟動失敗。未來應該更謹慎檢查變數依賴關係,並善用工具與設定來避免踩雷。 ###### tags: `踩雷` `spring` `StackOverflowError` `yml`