我有一個 Spring Boot 應用程式,當使用嵌入式 tomcat 運行時,它可以按預期作業,但我注意到,如果我嘗試從與以前的專案一起使用的現有 tomcat 實體運行它,那么它會失敗,并出現 NoClassDefFoundError 的類我不在我的應用程式中的任何地方使用。
我注意到在 /lib 目錄中我有一個包含一些 Spring 注釋類的 jar,因此作為測驗,我清除了解決問題的 /lib 目錄。我的假設是 Spring 看到類路徑上的一些配置/beans/匯入,因為它們存在于 /lib 目錄中,并且要么嘗試自行自動配置某些內容,要么實際上嘗試實體化其中一些類。
那么我的問題是 - 假設我不能總是完全控制類路徑上所有內容的內容,我該如何防止發生這樣的錯誤?
編輯
更詳細一點 - 找不到的類是 DefaultCookieSerializer,它是 spring-session-implementation 依賴項的一部分。它被拉入位于 /lib 的 jar 中的一個類,但它不是我的應用程式的任何部分。
uj5u.com熱心網友回復:
檢查由@EnableAutoConfiguration. 您可以為您的應用程式顯式配置一組自動配置類。本教程可以是一個很好的起點。
uj5u.com熱心網友回復:
您可以@SpringBootApplication從主類中洗掉注釋,并將其替換為一個@ComponentScan注釋和一個@Import僅顯式列出您要加載的配置類的注釋。例如,在使用指標、Web 客戶端、rest 模板、Jackson 等的 Spring boot MVC 應用程式中,我能夠@SpringBootApplication使用以下代碼替換注釋并使其完全按照以前的方式作業,并且所有功能測驗都通過了:
@Import({ MetricsAutoConfiguration.class,
InfluxMetricsExportAutoConfiguration.class,
ServletWebServerFactoryAutoConfiguration.class,
DispatcherServletAutoConfiguration.class,
WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class,
WebClientAutoConfiguration.class,
RestTemplateAutoConfiguration.class,
RefreshAutoConfiguration.class,
ValidationAutoConfiguration.class
})
@ComponentScan
uj5u.com熱心網友回復:
提到例外的可能罪魁禍首是類路徑上的不兼容 jar。
由于我們不知道您遇到了哪個庫的問題,因此我們無法告訴您確切的原因,但情況如下所示:
- Spring-Boot 自動配置類之一是由類路徑上存在的類觸發的
- Trigerred 配置嘗試創建一些在您擁有的 jar 中不存在的類 bean(但它在 Spring BOM 中提到的特定版本中)
版本不兼容也可能導致MethodNotFound例外。
這就是為什么最好不要在容器內運行 Spring Boot 應用程式的原因之一(使 jar 不是 war),而是作為具有嵌入式容器的可運行 jar。
甚至在 Spring Boot 之前,最好考慮到運行時類路徑中存在的庫并將它們標記為在您的專案中提供。在類路徑上擁有不同版本的庫可能會導致ClassCastExceptions兩端名稱匹配的奇怪情況,但其余的則不會。
您可以通過禁用導致問題的自動配置來解決特定情況。您可以通過添加exclude到您的@SpringBootApplication或使用屬性檔案來做到這一點。
編輯:如果您在 Spring Boot 應用程式中不使用非常廣泛的包掃描(或在包掃描中使用專案外部的包名稱),則 Spring Boot 不太可能簡單地從類路徑匯入配置。正如我之前提到的,它是由類路徑中存在的類觸發的一些自動配置。
理論解決方案:您可以使用 maven shade 插件將所有包重新定位到您自己的包空間:請參閱 docs。問題是你會面臨:
- 定義非常廣泛的重定位模式,將排除需要使用的 JEE 類,以便容器知道如何運行您的應用程式。
- 重定位很可能不會影響在 Spring Boot 注釋(如注釋
@PackageScan或@ConditionalOnClass)中用作字串的包名稱。據我所知,它還沒有實施。您必須自己實作它 - 也許作為某種陰影插件資源處理器。 - 重定位類時,您必須替換 jar 中所有相關配置中的包名稱。也可能合并其中的一些。
- 您還必須考慮您使用的庫或 spring 使用包名稱或檔案的方式。
這絕對不是一項簡單的任務,前面有許多陷阱。但是如果做得對,那么它可能會讓您忽略容器類路徑上的內容。Spring Boot 還會在重定位的包中查找類,而普通 jar 中不會有這些類。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/321976.html
下一篇:MVC中的正確結構與spring
