JavaFXプラグインとしてgradleを使用しています。 1つのクラスを除いて、distribution /で実行可能ファイルを構築して実行した後でも、すべてが完全に機能します:CloseableHttpClient
いくつかの目的で、次のようなオブジェクトを作成します。
CloseableHttpClient client = HttpClients.createDefault();
IDEでプログラムを実行しても問題ありません。すべて正常に動作します。しかし、.exeファイルをビルドして実行しようとすると、次のThrowable
- StackTraceが取得されます。
Java.lang.NoClassDefFoundError: Could not initialize class org.Apache.http.conn.ssl.SSLConnectionSocketFactory
at org.Apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.Java:955)
at org.Apache.http.impl.client.HttpClients.createDefault(HttpClients.Java:58)
at ch.itcb.tools.lom.util.JsonSimpleUtil.http(JsonSimpleUtil.Java:29)...
私は本当にそれを理解していません。このクラスだけが見つからないのに、他のすべてのクラスが見つかるのはどうしてですか?
私のbuild.gradleファイル:
apply plugin: 'Java'
apply plugin: 'Eclipse'
apply from: 'javafx.plugin'
sourceCompatibility = 1.8
version = '0.1'
jar {
manifest {
attributes 'Implementation-Title': 'LogoffManager',
'Implementation-Version': version
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'lib', include: ['*.jar'])
compile 'ch.qos.logback:logback-classic:1.1.3'
compile 'org.Apache.httpcomponents:httpclient:4.5.1'
compile 'com.googlecode.json-simple:json-simple:1.1'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
test {
systemProperties 'property': 'value'
}
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
さらに情報が必要な場合は、コメントを書いてください。 THX。
それは良い質問です。多くの方法の例を研究しているときに私がたった今遭遇しましたJava開発者はクラスパスの楽しみで終わる可能性があります:-)
具体的には、build.gradleの最小バージョン(直接関連するもののみを含む)から始めました。
_plugins {
id 'Java'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
jar {
manifest {
attributes 'Main-Class': 'com.oliverlockwood.Main'
}
}
dependencies {
compile 'org.Apache.httpcomponents:httpclient:4.5.1'
}
_
このコンテキストでの私の「メイン」クラスは、コード例を使用します。
_package com.oliverlockwood;
import org.Apache.http.impl.client.CloseableHttpClient;
import org.Apache.http.impl.client.HttpClients;
public class Main {
public static void main(String[] args) {
CloseableHttpClient client = HttpClients.createDefault();
}
}
_
この段階で、_gradle clean build
_に続いて_Java -jar build/libs/33106520.jar
_を実行できます(私のプロジェクトはこのStackOverflowの質問にちなんで命名されました)。
_Exception in thread "main" Java.lang.NoClassDefFoundError: org/Apache/http/impl/client/HttpClients
at com.oliverlockwood.Main.main(Main.Java:8)
Caused by: Java.lang.ClassNotFoundException: org.Apache.http.impl.client.HttpClients
at Java.net.URLClassLoader.findClass(URLClassLoader.Java:381)
at Java.lang.ClassLoader.loadClass(ClassLoader.Java:424)
at Sun.misc.Launcher$AppClassLoader.loadClass(Launcher.Java:331)
at Java.lang.ClassLoader.loadClass(ClassLoader.Java:357)
_
これはエラーとは微妙に異なりますが、それを掘り下げて再現する前に、強調してみましょう:このエラーと表示されているエラーの両方は、クラスローダーが必要なクラスを見つけることができないときに実行時に発生します。かなり良いブログ投稿があります here コンパイル時のクラスパスと実行時のクラスパスの違いについての詳細があります。
_gradle dependencies
_を実行すると、プロジェクトのランタイム依存関係を確認できます。
_runtime - Runtime classpath for source set 'main'.
\--- org.Apache.httpcomponents:httpclient:4.5.1
+--- org.Apache.httpcomponents:httpcore:4.4.3
+--- commons-logging:commons-logging:1.2
\--- commons-codec:commons-codec:1.9
_
これらをランタイムクラスパスに1つずつ手動で追加しました。 (記録的には、これは一般的に良い習慣とは見なされませんが、実験のために、これらのjarを_build/libs
_フォルダーにコピーし、_Java -cp build/libs/33106520.jar:build/libs/* com.oliverlockwood.Main
_で実行しました。興味深いことに、これはそうではありませんでしたあなたの正確な問題を再現することができます。
org.Apache.httpcomponents:httpclient
_を使用できない場合、HttpClients
jarが見つからないため失敗します。org.Apache.httpcomponents:httpclient:4.5.1
_を使用できる場合、問題は顕在化しません-そして、ビルドが見つけられないクラス(_org.Apache.http.conn.ssl.SSLConnectionSocketFactory
_)は、この同じApacheの部分ですlibrary、これは非常に疑わしいものです。私の疑いは、ランタイムクラスパスに異なるバージョンのApache httpclientライブラリが含まれていることです。たくさんのバージョンがあるので、すべての組み合わせをテストするつもりはありません。そのため、代わりに次のアドバイスをお伝えします。
compile fileTree(dir: 'lib', include: ['*.jar'])
の方法で依存関係を使用しないでください。 MavenやJCenterなどのリポジトリに基づく管理された依存関係は、ランダムなディレクトリにある依存関係よりも一貫して作業しやすいです。これらがオープンソースのアーティファクトリポジトリに公開したくない内部ライブラリである場合、ローカルNexusインスタンスなどをセットアップする価値があります。build.gradle
_に配置し、_gradle clean shadow
_を実行すると、_Java -jar
_を実行できました手動でクラスパスに何かを追加する必要なく、問題ありません。