iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
自我挑戰組

探索 Spring Boot Doc系列 第 14

Doc 6.8.1 Diagnosing Classloading Issues(二)

  • 分享至 

  • xImage
  •  

官方原文

To diagnose whether the classloading issues are indeed caused by devtools and its two classloaders, try disabling restart. If this solves your problems, customize the restart classloader to include your entire project.

去診斷出是不是開發工具(devtools)和他兩個類別載入(classloaders)引起的類別載入議題(classloading issues),透過關掉 restart 功能來確認。假設真的就是 restart 所造成的問題,那客製化 classloader 來將載入整個專案來解決這個問題。

上文之中所提到的 classloading issues 有哪些 ?
下方為一些例外是 Red Hat 條列關於 JBoss 的一些 classloading issues,整理為表格形式

  • ClassNotFoundException
  • NoClassDefFoundError
  • ClassCastException
  • NoSuchMethodError
    上方條列的Exception或是Error都來自同一個package java.lang

在前一天的文中有提到,Spring Boot 是透過 RestartClassLoader(一個 URLClassLoader的子類) 以及另一個ClassLoader(SystemAppClassLoader) 來處理第三方 jar 之中的類別。

如何關閉devtool restart 功能?
Doc 6.8.3 Automatic Restart: Disabling Restart
在application.yml 之中加上 spring.devtools.restart.enable=fasle 或者
在 Application 入口之處透過 System property 加上同樣的設定 。

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }
}

上方兩者disable restart 的方法,前者寫在application.yml 的檔案,仍會初始化 restart classloader,但這個 classloader 不會去監控檔案的變化(原文 watch for file changes)。
如果想完整移除 restart 功能,就得採用後者。

在停用上方restart classloader 之後,如果classloading issues 問題可以解決的話,
可以採用客製化 restart classloader 來試圖解決 restart classloader 引起的 issue 。

Intellij 可以透過下方順序,可以產生 JVM Heap 的快照, Eclipse 可以下載 Memory Analyzer (MAT) 也能產生如此的快照,這個快照是用來檢視類別產生物件的數量以及佔用空間。

我們在此處用這個工具,是想觀察 disable restart 的設定方法差異,從官方文檔那邊可以看到似乎在 SpringBootApplication.run 之前完成環境變數的設置這一方式,可以讓 Restart 完全不啟動,而寫在外掛註冊(application.yml) 的方式會有關於 restart 物件的產生,雖然沒有作用。

下方為寫進環境變數的 disable restart
https://ithelp.ithome.com.tw/upload/images/20230929/20161770E2gBPNBdVl.png
https://ithelp.ithome.com.tw/upload/images/20230929/20161770P883MsacJY.png
可以看到上方 RestartClassLoader 沒有實體的產生

透過外掛註冊 disable restart,光是類別數量就超過寫在環境變數的 disable
https://ithelp.ithome.com.tw/upload/images/20230929/20161770L49sJrWj87.png

最重要的是會產生.....RestartClassLoader ,而這會吃資源啊~~~
https://ithelp.ithome.com.tw/upload/images/20230929/20161770G1BXkLAtXf.png

參考資料
{官方 issue} Spring Boot:Devtools: Same class with different classloader causing NoSuchBeanDefinitionException
https://github.com/spring-projects/spring-boot/issues/3316

{Red Hat 官方}How to diagnose ClassNotFoundException / NoClassDefFoundError and other classloading issues in JBoss EAP 6 / 7 with Tattletale
https://access.redhat.com/solutions/800073


上一篇
ClassLoader
下一篇
Doc 6.8.2 Property Defaults
系列文
探索 Spring Boot Doc30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言