java.exeでjarを実行しようとしたときにNoClassDefFoundErrorが発生しました-jar…何が問題なのですか?

StackOverflow https://stackoverflow.com/questions/250166

質問

デプロイを容易にするために、jarにラップしようとしているアプリケーションがあります。 CLASSPATHから到達可能なクラスのセットとして実行すると、アプリケーションはコンパイルされ、(Windowsのcmdウィンドウで)正常に実行されます。しかし、クラスをjarし、同じcmdウィンドウでjava 1.6で実行しようとすると、例外が発生し始めます:

C:\dev\myapp\src\common\datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:\myapp\libs\commons -logging-1.1.jar -server -jar DataGen.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    ... 1 more

面白いことに、問題のLogFactoryはcommons-logging-1.1.jarにあり、指定されたクラスパスにあります。 jarファイル(はい、本当にあります):

C:\dev\myapp\src\common\datagen>dir C:\myapp\libs\commons-logging-1.1.jar
 Volume in drive C is Local Disk
 Volume Serial Number is ECCD-A6A7

 Directory of C:\myapp\libs

12/11/2007  11:46 AM            52,915 commons-logging-1.1.jar
           1 File(s)         52,915 bytes
           0 Dir(s)  10,956,947,456 bytes free

commons-logging-1.1.jarファイルの内容:

C:\dev\myapp\src\common\datagen>jar -tf C:\myapp\libs\commons-logging-1.1.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/logging/
org/apache/commons/logging/impl/
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/apache/commons/logging/Log.class
org/apache/commons/logging/LogConfigurationException.class
org/apache/commons/logging/LogFactory$1.class
org/apache/commons/logging/LogFactory$2.class
org/apache/commons/logging/LogFactory$3.class
org/apache/commons/logging/LogFactory$4.class
org/apache/commons/logging/LogFactory$5.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)

はい、commons-loggingにはLogFactoryクラスがあります。そして最後に、私のjarのマニフェストの内容:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
 .jar GroboTestingJUnit-1.2.1-core.jar junit.jar

これは私を困惑させ、私が1日以上も悩んでいた同僚たちを困らせました。少なくとも今のところ、これに対するサードパーティのソリューションは、ライセンスの制限と会社のポリシー(例:exeの作成やjarのパッケージ化のためのツール)が原因である可能性があります。最終的な目標は、開発WindowsボックスからLinuxサーバーに(依存するすべてのjarを使用して)コピーし、データベースを作成するために使用できるjarを作成することです(そのため、クラスパスは開発環境とデプロイメント環境で異なる可能性があります)。この謎の手がかりは大歓迎です!

役に立ちましたか?

解決

-jarオプションは、-classpathと相互に排他的です。古い説明を参照こちら

  

-jar

     

JARファイルにカプセル化されたプログラムを実行します。最初の引数は、起動クラス名ではなく、JARファイルの名前です。このオプションが機能するには、JARファイルのマニフェストにMain-Class:classnameという形式の行が含まれている必要があります。ここで、classnameは、アプリケーションの開始点として機能するpublic static void main(String [] args)メソッドを持つクラスを識別します。

     

JarファイルとJarファイルマニフェストの操作については、JarツールのリファレンスページとJavaチュートリアルのJarトレイルを参照してください。

     

このオプションを使用すると、JARファイルがすべてのユーザークラスのソースとなり、他のユーザークラスパス設定は無視されます。

手っ取り早い方法は、ブートストラップクラスパスにクラスパスを追加することです:

  

-Xbootclasspath / a: パス

     

ディレクトリ、JARアーカイブ、およびZIPアーカイブのコロン区切りのパスを指定して、デフォルトのブートストラップクラスパスに追加します。

ただし、 @Dan が正しく言うように、正しい解決策は、JARマニフェストが必要なすべてのJAR。

他のヒント

-jar オプションを省略して、次のようにjarファイルを開始できます。

java -cp MyJar.jar; C:\ externalJars \ * mainpackage.MyMainClass

これは発生している問題です

JARファイルが&quot; C:\ java \ apps \ appli.jar&quot;からロードされ、マニフェストファイルにClass-Path:参照&quot; lib / other.jar&quot;がある場合、クラスローダーは&quot; C:\ java \ apps \ lib \&quot; 「other.jar」の場合。 JARファイルエントリ&quot; lib / other.jar&quot;は表示されません。

解決策:-

  1. プロジェクトを右クリックし、エクスポートを選択します。
  2. Javaフォルダを選択し、JARファイルの代わりにRunnable JAR Fileを選択します。
  3. 適切なオプションを選択し、「ライブラリ処理」セクションで3番目のオプションを選択します(必要なライブラリを生成されたJARの隣のサブフォルダにコピーします)。

[ EDIT = 3番目のオプションはjarに加えてフォルダーを生成します。2番目のオプション(&quot;生成されたJARに必要なライブラリをパッケージ化する&quot;)もjarがあるので使用できます。 ]

  1. [完了]をクリックすると、指定した場所にJARがマニフェストファイルで言及されているJARを含むフォルダーとともに作成されます。
  2. ターミナルを開き、jarへの適切なパスを指定し、このコマンドjava -jar abc.jarを使用して実行します

    クラスローダーは、参照されたJARがアプリケーションJARを含む同じフォルダーにあるため、参照されたJARの正しいフォルダーを検索します。&quot; java.lang.NoClassDefFoundError&quot;はありません。例外がスローされました。

これは私のために働いた...それもあなたのために働くことを願っています!!!

プログラムで外部ライブラリを使用し、jarファイルにまとめてパックしようとすると、クラスパスの問題などのため、それほど単純ではありません。

この問題には OneJar を使用したいと思います。

iは私のjarで同じ問題を抱えていました ソリューション

  1. MANIFEST.MFファイルを作成します:
  

マニフェストバージョン:1.0

     

密封:true

     

クラスパス:。 lib / jarX1.jar lib / jarX2.jar lib / jarX3.jar

     

メインクラス:com.MainClass

  1. プロジェクトを右クリックし、エクスポートを選択します。
  

選択したプロジェクトのすべてのoutpoutフォルダーをエクスポートを選択

  1. ワークスペースから既存のマニフェストを使用して選択し、MANIFEST.MFファイルを選択します

これは私のために働いた:)

マニフェストを使用しているときに、クラスパスのjarのリストには、各jarのリストの後にスペースが必要であることがわかりました。 &quot; required_lib / sun / pop3.jar required_lib / sun / smtp.jar&quot;。リストの最後であっても。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top