spring Boot Jar包瘦身引發(fā)的IllegalAccessError:類加載器沖突排查與修復(fù)
為減小spring boot應(yīng)用的Jar包體積,開發(fā)者常采用Jar包瘦身策略,將依賴庫移至Jar包外部。然而,此操作可能導(dǎo)致意想不到的IllegalAccessError錯誤,本文將詳細分析此問題。
問題描述:
一個Spring Boot應(yīng)用(版本2.3.2.RELEASE,spring cloud版本Hoxton.SR9,Spring Cloud Alibaba版本2.2.6.RELEASE)在瘦身操作后,使用Java -jar命令啟動時報錯:
Caused by: java.lang.IllegalAccessError: class org.springframework.cloud.openfeign.hystrixtargeter$$EnhancerBySpringCGLIB$$7e887a8a cannot access its superclass org.springframework.cloud.openfeign.hystrixtargeter at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_333] ...
該錯誤表明Spring CGLIB生成的代理類org.springframework.cloud.openfeign.hystrixtargeter$$EnhancerBySpringCGLIB$$7e887a8a無法訪問其父類,通常由類加載器沖突引起。開發(fā)者嘗試自定義BeanPostProcessor調(diào)整類加載器,但問題依舊存在。瘦身策略是使用maven Dependency Plugin將依賴庫復(fù)制到Jar包外部的lib目錄,并在MANIFEST.MF文件中添加指向該目錄的Class-Path。
問題根源分析:
雖然開發(fā)者懷疑MANIFEST.MF中的Class-Path配置導(dǎo)致類加載器不一致,但根本原因在于缺少Spring Boot Maven Plugin以及Maven Jar Plugin配置不完整。 Spring Boot Maven Plugin在打包時會自動處理類加載器問題,確保應(yīng)用正常運行。瘦身操作中移除該插件,僅依賴Maven Jar Plugin和Maven Dependency Plugin,導(dǎo)致問題出現(xiàn)。Maven Jar Plugin能創(chuàng)建Jar包并設(shè)置Class-Path,但缺乏Spring Boot的類加載器管理機制,從而引發(fā)IllegalAccessError。
解決方案:
通過完善Maven Jar Plugin配置解決此問題。關(guān)鍵在于正確配置主類(mainClass)和輸出目錄(outputDirectory),同時保留addClasspath、classpathPrefix等配置,并移除Spring Boot Maven Plugin。完整的Maven Jar Plugin配置如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <useUniqueVersions>false</useUniqueVersions> <mainClass>com.bdip.cost.CostApplication</mainClass> </manifest> </archive> <outputDirectory>${boot-jar-output}</outputDirectory> </configuration> </plugin>
此配置確保Maven Jar Plugin正確設(shè)置主類和輸出目錄,Maven Dependency Plugin繼續(xù)負責(zé)將依賴庫復(fù)制到lib目錄,避免類加載器沖突,從而解決IllegalAccessError問題。