官方原文
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,整理為表格形式
在前一天的文中有提到,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
可以看到上方 RestartClassLoader 沒有實體的產生
透過外掛註冊 disable restart,光是類別數量就超過寫在環境變數的 disable
最重要的是會產生.....RestartClassLoader ,而這會吃資源啊~~~
參考資料
{官方 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