デプロイを容易にするために、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を作成することです(クラスパスは開発環境とデプロイメント環境で異なる可能性があります)。この謎の手がかりは大歓迎です!
-jarオプションは、-classpathと相互に排他的です。古い説明を参照してください here
-jar
JARファイルにカプセル化されたプログラムを実行します。最初の引数は、スタートアップクラス名ではなく、JARファイルの名前です。このオプションが機能するためには、JARファイルのマニフェストにMain-Class:classnameという形式の行が含まれている必要があります。ここで、classnameは、アプリケーションの開始点として機能するpublic static void main(String [] args)メソッドを持つクラスを識別します。
JarファイルおよびJarファイルマニフェストの操作については、JarツールのリファレンスページとJavaチュートリアルのJarトレイルを参照してください。
このオプションを使用すると、JARファイルはすべてのユーザークラスのソースとなり、他のユーザークラスパス設定は無視されます。
手っ取り早い方法は、クラスパスをbootstrapクラスパスに追加することです:
-Xbootclasspath/a:path
ディレクトリ、JARアーカイブ、Zipアーカイブのコロン区切りのパスを指定して、デフォルトのbootstrapクラスパスに追加します。
ただし、 @ Dan が正しく述べているように、正しい解決策は、JARマニフェストに必要なすべてのJARのクラスパスが含まれるようにすることです。
-jar
オプションを省略して、次のようにjarファイルを開始できます。
Java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
これが発生している問題です。
jARファイルが「C:\ Java\apps\appli.jar」からロードされ、マニフェストファイルにClass-Path:参照「lib/other.jar」がある場合、クラスローダーは「C:\ Java」を検索します。 「other.jar」の場合は\ apps\lib\" JARファイルのエントリ「lib/other.jar」は参照しません。
解決策:-
[[〜#〜] edit [〜#〜] = 3番目のオプションは、jarに加えて2番目のオプション(「必要なライブラリを生成されたJARにパッケージ化する」 ")は、jarファイルがあるときにも使用できます。 ]
ターミナルを開き、jarへの適切なパスを指定し、このコマンドを使用して実行しますJava -jar abc.jar
これで、クラスローダーは、アプリケーションJARを含む同じフォルダーに存在するため、参照されたJARの正しいフォルダーを検索します。「Java.lang.NoClassDefFoundError」例外はスローされません。
これは私のために働いた...それもあなたのために働くことを願っています!!!
プログラムで外部ライブラリを使用し、jarファイルにまとめてパックしようとすると、クラスパスの問題などのため、それほど単純ではありません。
この問題には OneJar を使用したいと思います。
私は私の瓶と同じ問題を抱えていました
マニフェストバージョン:1.0
密閉済み:true
クラスパス:。 lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar
メインクラス:com.MainClass
チェックしたプロジェクトのすべてのoutpoutフォルダーをエクスポートを選択します
これは私のために働いた:)
マニフェストを使用しているときに、クラスパスのjarのリストには、各jarのリストの後にスペースが必要であることがわかりました。 「required_lib/Sun/pop3.jar required_lib/Sun/smtp.jar」。リストの最後であっても。