javamavenmaven-modulemaven-multi-module

NoClassDefFoundError in Maven multi-module project


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:

<?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>

Pom.xml of core submodule:

<?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>

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:

<?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>

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 "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

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


Solution

  • 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".