Maven多模块项目中的NoClassDefFoundError

huangapple go评论54阅读模式
英文:

NoClassDefFoundError in Maven multi-module project

问题

我已将应用程序分割,以防止在各个子模块中出现代码重复。因此,所有模块都使用名为“core”的子模块,其中包含一些DAO和Util类。
当我现在执行一个模块并调用core的Util类时,会抛出NoClassDefFoundError错误。

以下是一个重现错误的简单示例:

父POM.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>multimodule</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>core</module>
        <module>submodule1</module>
    </modules>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

core子模块的POM.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>multimodule</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>core</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

core模块的Util类:

package org.example;

import com.google.gson.Gson;

public class Util {
    public static void test() {
        Gson gson = new Gson();
    }
}

submodule1的POM.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>multimodule</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>submodule1</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>core</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

submodule1的Main类:

package org.example;

public class Main {
    public static void main(String[] args) {
        Util.test();
    }
}

当我执行主函数时,出现以下错误:

/usr/lib/jvm/java-17-openjdk/bin/java -javaagent:/usr/share/idea/lib/idea_rt.jar=43299:/usr/share/idea/bin -Dfile.encoding=UTF-8 -classpath /tmp/multimodule/submodule1/target/classes:/tmp/multimodule/core/target/classes org.example.Main
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
    at org.example.Util.test(Util.java:7)
    at org.example.Main.main(Main.java:5)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 2 more

Process finished with exit code 1

缺少什么,以便submodule1可以成功调用core模块中的静态函数?

英文:

I have splitted an application to prevent code duplicates in various submodules.
So all modules are using the submodule "core" which contain some DAOs and Util-Classes.
When I now execute a module and it is calling the Util-Class of core, a NoClassDefFoundError is thrown.

Here is a small example to reproduce the error:

Parent pom.xml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;groupId&gt;org.example&lt;/groupId&gt;
    &lt;artifactId&gt;multimodule&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;
    &lt;modules&gt;
        &lt;module&gt;core&lt;/module&gt;
        &lt;module&gt;submodule1&lt;/module&gt;
    &lt;/modules&gt;

    &lt;properties&gt;
        &lt;maven.compiler.source&gt;17&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;17&lt;/maven.compiler.target&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;/properties&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.google.code.gson&lt;/groupId&gt;
            &lt;artifactId&gt;gson&lt;/artifactId&gt;
            &lt;version&gt;2.10.1&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/project&gt;

Pom.xml of core submodule:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.example&lt;/groupId&gt;
        &lt;artifactId&gt;multimodule&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;core&lt;/artifactId&gt;

    &lt;properties&gt;
        &lt;maven.compiler.source&gt;17&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;17&lt;/maven.compiler.target&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;/properties&gt;
&lt;/project&gt;

Util class of core module:

package org.example;

import com.google.gson.Gson;

public class Util {
    public static void test() {
        Gson gson = new Gson();
    }
}

Pom.xml of submodule1:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.example&lt;/groupId&gt;
        &lt;artifactId&gt;multimodule&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/parent&gt;

    &lt;artifactId&gt;submodule1&lt;/artifactId&gt;

    &lt;properties&gt;
        &lt;maven.compiler.source&gt;17&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;17&lt;/maven.compiler.target&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;/properties&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.example&lt;/groupId&gt;
            &lt;artifactId&gt;core&lt;/artifactId&gt;
            &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
            &lt;scope&gt;compile&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/project&gt;

Main class of submodule1:

package org.example;

public class Main {
    public static void main(String[] args) {
        Util.test();
    }
}

When I execute the main function, I am getting the following error:

/usr/lib/jvm/java-17-openjdk/bin/java -javaagent:/usr/share/idea/lib/idea_rt.jar=43299:/usr/share/idea/bin -Dfile.encoding=UTF-8 -classpath /tmp/multimodule/submodule1/target/classes:/tmp/multimodule/core/target/classes org.example.Main
Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: com/google/gson/Gson
	at org.example.Util.test(Util.java:7)
	at org.example.Main.main(Main.java:5)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 2 more

Process finished with exit code 1

What is missing that submodule1 can call the static function in the core module successfully?

答案1

得分: 1

The parent of "multimodule" defined the "gson" scope as provided. You should remove it to make it work. Because both the "core" and "test" modules inherit from "multimodule," it means that inside the "test" module, the gson scope is also provided, which is why it throws a ClassNotFound error.

In your case, you should move the gson dependency to your "core" module and set the scope to provided. Then, introduce "gson" within the "test" module and set the scope to "compile." Alternatively, you can simply remove the "provided" scope from "multimodule."

英文:

The parent of "multimodule" defind "gson" scope is provide, removed it should be work. Becase both of modules "core" and "test" was inherit from "multimodule", that mean inside the "test" module gson scope also is provide, that why it thrown ClassNotFoud.

In your case, you should move gson denpendency in you "core" module and set scope to provide, and introduce "gson" within "test" and set scope to "compile". Or you just removed the "provide" scope from "multimodule".

huangapple
  • 本文由 发表于 2023年6月6日 13:43:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定