68

デプロイを簡単にするために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クラスがあります。そして最後に、私の瓶のマニフェストの内容:

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を作成することです(したがって、クラスパスは開発環境とデプロイメント環境で異なる場合があります)。この謎への手がかりは大歓迎です!

4

6 に答える 6

63

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

-jar

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

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

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

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

-Xbootclasspath / a:パス

デフォルトのブートストラップクラスパスに追加するdirectires、JARアーカイブ、およびZIPアーカイブのコロンで区切られたパスを指定します。

ただし、@ Danが正しく言っているように、正しい解決策は、JARマニフェストに必要なすべてのJARのクラスパスが含まれていることを確認することです。

于 2008-10-30T13:29:27.740 に答える
37

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

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

于 2012-01-12T16:18:34.667 に答える
20

これが発生している問題であり、

JAR ファイルが "C:\java\apps\appli.jar" からロードされ、マニフェスト ファイルに Class-Path: reference "lib/other.jar" がある場合、クラス ローダーは "C:\java" を検索します。 「other.jar」の「\apps\lib\」。JAR ファイルのエントリ "lib/other.jar" は調べません。

解決:-

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

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

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

    ここで何が起こるかというと、クラス ローダーは、参照されている JARS の正しいフォルダーを検索します。これは、アプリの JAR が含まれているフォルダーと同じフォルダーに存在するためです。現在、「java.lang.NoClassDefFoundError」例外はスローされません。

これは私にとってはうまくいきました...あなたにもうまくいくことを願っています!!!

于 2012-09-05T13:46:51.510 に答える
3

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

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

于 2008-10-30T14:11:28.997 に答える
3

私は私のjarファイルで同じ問題を抱えていました

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

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

封印:本当

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

メインクラス: com.MainClass

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

チェックしたプロジェクトのすべての出力フォルダーをエクスポートするを選択します

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

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

于 2015-11-19T10:16:17.473 に答える
0

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

于 2012-01-12T21:55:36.537 に答える