java.lang.NoClassDefFoundError錯誤產生的原因及解決方案(一種方案)
NoClassDefFoundError
最近在使用 Redisson 框架實現分散式鎖的時候,在專案啟動之後,報錯:
類的定義沒有找到, 根本原因是 ClassNotFoundException , 但是在編譯的時候,並沒有報錯,執行本地的測試類來進行建立對應的物件也沒有問題
建立的測試類如下,
import org.junit.Test; import org.redisson.Redisson; import org.redisson.config.Config; public class RedissonTest { @Test public void test1() { //Config 類 和 Redisson類是要進行建立 的類 Config config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6379"); Redisson redisson = (Redisson) Redisson.create(config); System.out.println(config); System.out.println(redisson); } }
在進行測試的時候,輸出正常,沒有報錯,
但是當啟動Tomcat的時候,伺服器丟擲異常
Caused by: java.lang.NoClassDefFoundError: org/redisson/config/Config
at com.mmall.common.RedissonManager.(RedissonManager.java:20)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
… 60 more
Caused by: java.lang.ClassNotFoundException: org.redisson.config.Config
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1292)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1121)
… 66 more
從上明德異常日誌可以看出,是 org/redisson/config/Config 這個類的ClassDefNotFound, 但是編譯的時候是沒有問題的,到了執行,專案部署的時候,丟擲了這個異常,而且通過檢視根異常, 是ClassNotFoundException, 在這個地方困擾了很久。 編譯的時候是可以的,但是到了執行的時候,就丟擲了異常。
方案一(失敗)
刪除了Maven中的依賴配置
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-all</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-avro</artifactId> <version>2.9.0</version> </dependency>
然後刪除本地倉庫中的 jar包, 重新引入依賴,最終還是失敗,沒有解決問題。
方案二(奏效)
既然是使用Maven依賴的問題,編譯的時候是沒有問題的(IDE不報錯),但是到了Spring去初始化Bean的時候發生了ClassNotFoundException,java.lang.NoClassDefFoundError: org/redisson/config/Config;
那麼自然想到的最直接的辦法,就是不使用Maven來管理這個依賴,自己下載對應的jar包,然後在Maven的 build 標籤中 配置編譯的時候加入額外的第三方jar包的編譯,這樣就一定可以找到對應的jar包了, 也就不會發生找不到類的異常。
引入的第三方jar包如圖,為Redisson框架的jar包
然後在配置Maven的 build 標籤下的 plugin 標籤時,新增額外的編譯配置此專案中使用的是 webapp/WEB-INF/lib ,資料夾作為編譯時需要額外進行編譯加入的地方,也就是放第三方jar包的位置
<!-- geelynote maven的核心外掛之-complier外掛預設只支援編譯Java 1.4,因此需要加上支援高版本jre的配置,在pom.xml裡面加上 增加編譯外掛 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
</plugins>
最終這樣配置後,解決了找不到類的問題,但是這樣也導致專案中出現了中央倉庫中已有的jar包, 不夠完美。其他的解決方法以後再說吧。