---
# System prepended metadata

title: '[踩雷] Spring Boot 啟動失敗：StackOverflowError 與循環變數問題紀錄'
tags: [踩雷, yml, spring, StackOverflowError]

---

# 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`