web-dev-qa-db-fra.com

NoClassDefFoundError sur la dépendance Maven

Ma première utilisation de Maven et je suis coincé avec des dépendances.

J'ai créé un projet Maven avec Eclipse et ajouté des dépendances. Il fonctionnait sans problème.

Mais quand j'essaye de l'exécuter via la ligne de commande:

$ 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

Il télécharge les dépendances, construit avec succès, mais lorsque j'essaie de l'exécuter, j'obtiens 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

Mon pom.xml est comme ça:

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

Quelqu'un peut-il m'aider?

58
utdemir

quand j'essaye de l'exécuter, j'obtiens NoClassDefFoundError

Exécuter comment? Vous essayez probablement de l'exécuter avec Eclipse sans avoir correctement importé votre classpath Maven. Voir le plugin m2Eclipse pour intégrer maven avec Eclipse.

Pour vérifier que votre configuration de maven est correcte, vous pouvez exécuter votre application avec le plugin exec en utilisant:

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

Mise à jour: Tout d'abord, en ce qui concerne votre erreur lors de l'exécution de exec:Java, votre classe principale est tr.edu.hacettepe.cs.b21127113.bil138_4.App. Quand on parle de noms de classe, ils sont (presque) toujours séparés par des points. Le nom de classe simple n'est que la dernière partie: App dans votre cas. Le nom complet est le package complet plus le nom de classe simple, et c'est ce que vous donnez à maven ou Java lorsque vous voulez exécuter quelque chose. Ce que vous tentiez d'utiliser était un système de fichiers Le chemin d'accès à un fichier source est une bête tout à fait différente. Un nom de classe est généralement traduit directement en un fichier de classe se trouvant dans le chemin de classe, par rapport à un fichier source dans le système de fichiers. Dans votre cas spécifique, le fichier de classe en question serait probablement à target/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.class parce que maven compile pour target/classes, et Java crée traditionnellement un répertoire pour chaque niveau de conditionnement.

Votre problème initial est simplement que vous n'avez pas placé les pots de Jackson sur votre chemin de classe. Lorsque vous exécutez un programme Java à partir de la ligne de commande, vous devez définir le chemin d'accès aux classes afin de lui indiquer où il peut charger les classes. Vous avez ajouté votre propre fichier jar, mais pas l'autre Votre commentaire me fait penser que vous ne comprenez pas comment créer manuellement un chemin de classe. En bref, le chemin de classe peut avoir deux choses: des répertoires contenant des fichiers de classe et des fichiers JAR contenant des fichiers de classe. Les répertoires contenant des fichiers JAR ne fonctionneront pas. Pour plus de détails sur la construction d'un chemin de classe, voir " Définition du chemin de classe " et la documentation de l'outil Java et javac .

Votre chemin de classe doit être au minimum, et sans les sauts de ligne:

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

Notez que le séparateur sur Windows est un point-virgule (;).

Je m'excuse de ne pas l'avoir remarqué plus tôt. Le problème était assis dans votre message d'origine, mais je l'ai raté.

21
Ryan Stewart

Par défaut, Maven ne regroupe pas les dépendances dans le fichier JAR qu'il crée, et vous ne les fournissez pas dans le chemin d'accès aux classes lorsque vous essayez d'exécuter votre fichier JAR à l'aide de la ligne de commande. C’est pourquoi Java VM ne peut pas trouver les fichiers de classe de la bibliothèque lorsqu’il tente d’exécuter votre code.

Vous pouvez spécifier manuellement les bibliothèques sur le chemin de classe avec le -cp paramètre, mais cela devient vite fastidieux.

Une meilleure solution consiste à "masquer" le code de la bibliothèque dans votre fichier JAR de sortie. Il existe un plugin Maven appelé le maven-shade-plugin pour le faire. Vous devez l'enregistrer dans votre POM, et il créera automatiquement un "uber-JAR" contenant vos classes et les classes de votre code de bibliothèque aussi lorsque vous exécutez mvn package.

Pour regrouper simplement toutes les bibliothèques requises, ajoutez ce qui suit à votre POM:

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

Une fois que cela est fait, vous pouvez réexécuter les commandes que vous avez utilisées ci-dessus:

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

Si vous souhaitez configurer davantage le plug-in shade en termes de choix des JAR, en spécifiant une classe principale pour un fichier JAR exécutable, etc., reportez-vous à la section "Exemples" du maven-shade). -plugin site .

103
Matt Ryall

Ceci est dû au fait que Morphia ne fait pas partie de votre production war/jar. Eclipse ou une construction locale les inclut dans le chemin de classe, mais les versions distantes ou automatique/programmée ne les considèrent pas comme faisant partie du chemin de classe.

Vous pouvez inclure des jars dépendants à l'aide d'un plugin.

Ajoutez l'extrait ci-dessous dans la section des plugins de votre pom

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

Vous devez faire classpath dans un fichier pom pour votre dépendance. Par conséquent, vous devez copier toutes les dépendances en un seul endroit.

Consultez mon blog .

<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