web-dev-qa-db-ja.com

Maven依存関係のNoClassDefFoundError

初めてMavenを使用すると、依存関係に悩まされます。

EclipseでMavenプロジェクトを作成し、依存関係を追加しましたが、問題なく機能していました。

しかし、コマンドラインから実行しようとすると:

$ 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

依存関係をダウンロードし、正常にビルドしますが、実行しようとすると、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

私のpom.xmlはこのようなものです:

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

誰も私を助けることができますか?

58
utdemir

実行しようとすると、NoClassDefFoundErrorが発生します

どのように実行しますか?おそらく、Mavenクラスパスを正しくインポートせずに、Eclipseで実行しようとしています。そのためには、MavenとEclipseを統合するための m2Eclipse プラグインをご覧ください。

Mavenの設定が正しいことを確認するには、次を使用して exec plugin でアプリを実行できます。

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

更新:最初に、exec:Javaを実行するときのエラーに関して、メインクラスはtr.edu.hacettepe.cs.b21127113.bil138_4.Appです。クラス名について話すとき、それらは(ほとんど)常にドットで区切られています。単純なクラス名は最後の部分です:あなたの場合はAppです。完全修飾名は、完全なパッケージに単純なクラス名を加えたものです。これは、何かを実行したいときにmavenまたはJavaに付けるものです。使用しようとしていたのは、ソースファイルへのファイルシステムパスでした。それはまったく別の獣です。通常、クラス名は、ファイルシステムのソースファイルと比較して、クラスパスで見つかったクラスファイルに直接変換されます。特定のケースでは、mavenはtarget/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.classにコンパイルされ、Javaは従来、パッケージングの各レベルのディレクトリを作成するため、問題のクラスファイルはおそらくtarget/classesにあります。

元の問題は、クラスパスにジャクソンの瓶を入れていないということです。コマンドラインからJavaプログラムを実行するとき、クラスをどこからロードできるかを知らせるためにクラスパスを設定する必要があります。独自のjarを追加しましたが、他の必要なjarは追加していません。あなたのコメントは、クラスパスを手動で構築する方法を理解していないと思わせます。つまり、クラスパスには、クラスファイルを含むディレクトリとクラスファイルを含むjarの2つの要素があります。 jarを含むディレクトリは機能しません。クラスパスの構築の詳細については、「 クラスパスの設定 」および「 Java および javac ツールのドキュメント」を参照してください。

クラスパスは少なくとも、改行なしである必要があります:

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

Windowsの区切り文字はセミコロン(;)であることに注意してください。

早く気づかなかったことをおaびします。問題は元の投稿にありましたが、私はそれを逃しました。

21
Ryan Stewart

デフォルトでは、MavenはビルドするJARファイルに依存関係をバンドルしません。また、コマンドラインでJARファイルを実行しようとすると、クラスパスに依存関係を提供しません。これが、コードを実行しようとしたときにJava VMがライブラリクラスファイルを見つけられない理由です。

-cpパラメーターを使用して、クラスパス上のライブラリーを手動で指定することもできますが、すぐに面倒になります。

より良い解決策は、出力JARファイルにライブラリコードを「シェーディング」することです。これを行うために maven-shade-plugin と呼ばれるMavenプラグインがあります。 POMに登録する必要があり、mvn packageを実行すると、クラスとライブラリコードのクラスを含む「uber-JAR」が自動的に構築されます。

必要なすべてのライブラリを単にバンドルするには、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>

これが完了したら、上記で使用したコマンドを再実行できます。

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

実行するJARファイルのMain-Classを指定するなど、どのJARを含めるべきかに関してシェードプラグインをさらに設定する場合は、 maven-shadeの「例」セクションを参照してください-プラグインサイト

103
Matt Ryall

これは、Morphia jarが出力war/jarの一部ではないためです。 Eclipseまたはローカルビルドにはクラスパスの一部として含まれますが、リモートビルドまたは自動/スケジュールビルドはそれらをクラスパスの一部とは見なしません。

プラグインを使用して、依存するjarを含めることができます。

以下のスニペットをpomのプラグインセクションに追加します

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

依存関係のために、pomファイルにクラスパスを作成する必要があります。したがって、すべての依存関係を1つの場所にコピーする必要があります。

ブログを確認

<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