sacha
sacha

Reputation: 23

java NoClassDefFoundError with maven dependency (log4j)

I'm trying to make a little program using maven. I'm using a template from a prof at my university and I'd like to use log4j for logging. When I run the program in eclipse it works fine. However when I create the jar with "mvn install" and try to run the program in cmd I get a NoClassDefFoundError

C:\eclipse_workspace_buchhaltung\Buchhaltung\target>c:\jdk-11.0.4\bin\java.exe -jar Buchhaltung-1.0.0-SNAPSHOT.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
        at ch.hslu.demo.DemoKlasse.<clinit>(DemoKlasse.java:11)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 1 more

The DemoKlasse I'm using to try out things looks like the following:

package ch.hslu.demo;

import java.time.LocalDateTime;
import java.util.Scanner;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class DemoKlasse {

    private static final Logger logger = LogManager.getLogger(DemoKlasse.class); // that's line 11

    public static void main(String[] args) {

        logger.info("DemoKlasse gestartet: " + LocalDateTime.now());

        System.out.println("Dies ist eine Testklasse!");
        String eingabe = "";
        Scanner sc = new Scanner(System.in);

        while(true) {

            System.out.println("Bitte geben Sie etwas ein. Beenden mit \"exit\"");

            eingabe = sc.nextLine();

            logger.info("Eingabe lautet: " + eingabe);

            if(eingabe.equalsIgnoreCase("exit")) {
                System.out.println("Das Programm wird beendet");
                logger.info("Exit wurde eingegeben: " + LocalDateTime.now());
                sc.close();
                System.exit(1);
            }

        }

    }

}

My pom with the log4j part looks like this:

    <properties>
        ...
        <log4j2.version>2.12.1</log4j2.version>
        <junit5.version>5.5.1</junit5.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>${log4j2.version}</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>${log4j2.version}</version>
                <scope>runtime</scope>
            </dependency>
            ...

I've also found this here: NoClassDefFoundError on Maven dependency I tried using the maven-shade-plugin and the maven-assembly-plugin but I still can't make it work.

Has anyone an idea why I can't make such a simple program work?

Upvotes: 2

Views: 3501

Answers (1)

dan1st
dan1st

Reputation: 16348

What are you doing?

You are creating a JAR file containing your code (and a Manifest file that points to your main class).

What is the problem?

You are exporting your code to a JAR file but the dependencies are not exported. Obviously, your program needs the dependencies to run(logging libriaries are not essention but other libs are).

How to solve it?

You said, you tried the shadow and the assembly plugin. You can add the dependencies with both. I think you just configured it incorrectly.

With the maven-assembly-plugin, you need to create a jar-with-dependencies and you shouldn't forget about your main class.

For example, you could use the following configuration(replace fully-qualified-main-class with the package name of your main class followed by the name of the main class(seperated by dots):

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>fully.qualified.MainClass</mainClass>
            </manifest> 
        </archive> 
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

After that, you can create the JAR with the command mvn package.

Make sure to execute the jar-with-dependencies and not the JAR created by the maven-jar-plugin.

other possible problems

It is possible that your program declares log4j with the scope provided. In that case, log4j is not included in your jar-with-dependencies.

See https://stackoverflow.com/a/574650/10871900

Upvotes: 2

Related Questions