1. 程式人生 > >java.lang.NoClassDefFoundError錯誤產生的原因及解決方案(一種方案)

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包, 不夠完美。其他的解決方法以後再說吧。