wake-up-neo.com

NoClassDefFoundError bei Maven-Abhängigkeit

Meine erste Verwendung von Maven und ich bin mit Abhängigkeiten fest.

Ich habe ein Maven-Projekt mit Eclipse erstellt und Abhängigkeiten hinzugefügt, und es funktionierte ohne Probleme.

Aber wenn ich versuche, es über die Kommandozeile auszuführen:

$ mvn package  # successfully completes
$ Java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App # NoClassDefFoundError for dependencies

Es lädt Abhängigkeiten herunter, erstellt sie erfolgreich, aber wenn ich versuche, sie auszuführen, erhalte ich NoClassDefFoundError:

Exception in thread "main" Java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonParseException
        at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.Java:16)
        at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.Java:22)
        at tr.edu.hacettepe.cs.b21127113.bil138_4.App.main(App.Java:10)
Caused by: Java.lang.ClassNotFoundException: org.codehaus.jackson.JsonParseException
        at Java.net.URLClassLoader$1.run(URLClassLoader.Java:217)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(URLClassLoader.Java:205)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:321)
        at Sun.misc.Launcher$AppClassLoader.loadClass(Launcher.Java:294)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:266)
        ... 3 more

Meine pom.xml sieht so aus:

<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>tr.edu.hacettepe.cs.b21127113</groupId>
  <artifactId>bil138_4</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>bil138_4</name>
  <url>http://maven.Apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>        
    <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>           
    </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>             
        </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.6</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.6</version>
    </dependency>
    </dependencies>
  </dependencyManagement>
</project>

Kann mir jemand helfen?

58
utdemir

wenn ich versuche, es auszuführen, erhalte ich NoClassDefFoundError

Führen Sie es wie? Sie versuchen wahrscheinlich, es mit Eclipse auszuführen, ohne Ihren Maven-Klassenpfad korrekt importiert zu haben. Siehe dazu das m2Eclipse Plugin zur Integration von maven in Eclipse.

Um zu überprüfen, ob Ihre Maven-Konfiguration korrekt ist, können Sie Ihre App mit dem exec-Plugin ausführen:

mvn exec:Java -D exec.mainClass=<your main class>

Update: Zunächst zu Ihrem Fehler beim Ausführen von exec:Java, deine Hauptklasse ist tr.edu.hacettepe.cs.b21127113.bil138_4.App. Wenn es um Klassennamen geht, werden sie (fast) immer durch Punkte getrennt. Der einfache Klassenname ist nur der letzte Teil: App in Ihrem Fall. Der vollständig qualifizierte Name ist das vollständige Paket und der einfache Klassenname. Dies geben Sie maven oder Java, wenn Sie etwas ausführen möchten. Sie haben versucht, ein Dateisystem zu verwenden Pfad zu einer Quelldatei Das ist ein ganz anderes Biest. Ein Klassenname wird im Allgemeinen direkt in eine Klassendatei übersetzt, die sich im Klassenpfad befindet, im Vergleich zu einer Quelldatei im Dateisystem. In Ihrem speziellen Fall handelt es sich um die betreffende Klassendatei wäre wahrscheinlich bei target/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.class weil maven kompiliert zu target/classes und Java erstellt traditionell ein Verzeichnis für jede Ebene der Verpackung.

Ihr ursprüngliches Problem ist einfach, dass Sie die Jackson-Gläser nicht auf Ihren Klassenpfad gesetzt haben. Wenn Sie ein Java von der Befehlszeile aus ausführen, müssen Sie den Klassenpfad festlegen, um zu erfahren, woher es Klassen laden kann. Sie haben Ihre eigene JAR-Datei hinzugefügt, die andere jedoch nicht Ihr Kommentar lässt mich glauben, dass Sie nicht verstehen, wie man einen Klassenpfad manuell erstellt. Kurz gesagt, der Klassenpfad kann zwei Dinge haben: Verzeichnisse mit Klassendateien und JARs mit Klassendateien. Verzeichnisse mit JARs funktionieren nicht. Weitere Informationen zum Erstellen eines Klassenpfads finden Sie unter " Festlegen des Klassenpfads " und in der Dokumentation zum Tool Java und javac .

Ihr Klassenpfad müsste mindestens und ohne die Zeilenvorschübe sein:

target/bil138_4-0.0.1-SNAPSHOT.jar:
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.6/jackson-core-asl-1.9.6.jar:
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.9.6/jackson-mapper-asl-1.9.6.jar

Beachten Sie, dass das Trennzeichen unter Windows ein Semikolon (;) ist.

Ich entschuldige mich dafür, dass ich es nicht früher bemerkt habe. Das Problem saß dort in Ihrem ursprünglichen Beitrag, aber ich habe es verpasst.

21
Ryan Stewart

Standardmäßig bündelt Maven keine Abhängigkeiten in der JAR-Datei, die es erstellt, und Sie geben sie nicht im Klassenpfad an, wenn Sie versuchen, Ihre JAR-Datei über die Befehlszeile auszuführen. Aus diesem Grund kann Java VM beim Versuch, Ihren Code auszuführen, die Bibliotheksklassendateien nicht finden.

Sie können die Bibliotheken im Klassenpfad manuell mit dem Parameter -cp Angeben, was jedoch schnell ermüdend wird.

Eine bessere Lösung besteht darin, den Bibliothekscode in Ihre Ausgabe-JAR-Datei zu "schattieren". Es gibt ein Maven-Plugin namens maven-shade-plugin , um dies zu tun. Sie müssen es in Ihrem POM registrieren, und es wird automatisch ein "Uber-JAR" erstellen, das Ihre Klassen und die Klassen für Ihren Bibliothekscode enthält, wenn Sie mvn package Ausführen.

Fügen Sie Ihrem POM Folgendes hinzu, um einfach alle erforderlichen Bibliotheken zu bündeln:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.6</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Sobald dies erledigt ist, können Sie die oben verwendeten Befehle erneut ausführen:

$ mvn package
$ Java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App

Wenn Sie das Shade-Plugin weiter konfigurieren möchten, um festzustellen, welche JARs enthalten sein sollen, und eine Hauptklasse für eine ausführbare JAR-Datei angeben möchten, lesen Sie den Abschnitt "Beispiele" im Abschnitt maven-shade -plugin site .

103
Matt Ryall

Dies liegt daran, dass das Morphia-Glas nicht Teil Ihres Output-War/Jar ist. Eclipse oder lokale Builds enthalten sie als Teil des Klassenpfads, aber Remote-Builds oder automatische/geplante Builds berücksichtigen sie nicht als Teil des Klassenpfads.

Sie können abhängige Gläser mit dem Plugin einbinden.

Füge das folgende Snippet in den Plugins-Bereich deines Poms ein

    <plugin>
        <artifactId>maven-Assembly-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
4
Satya

Sie müssen classpath in pom file für Ihre Abhängigkeit angeben. Daher müssen Sie alle Abhängigkeiten an einer Stelle kopieren.

Schau in meinem Blog nach .

<build>
  <plugins>
    <plugin>
      <groupId>org.Apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.1</version>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <phase>package</phase>
          <goals>
            <goal>copy-dependencies</goal>
          </goals>
          <configuration>
            <outputdirectory>${project.build.directory}/lib</outputdirectory>
            <overwritereleases>false</overwritereleases>
            <overwritesnapshots>false</overwritesnapshots>
            <overwriteifnewer>true</overwriteifnewer>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.Apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.4</version>
      <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>$fullqualified path to your main Class</mainClass>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>
3
madhawa