我使用 gradle 作为 JavaFX 插件。即使在 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'
}
}
}
如果您需要更多信息,请发表评论。谢谢。
原文由 jntme 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是一个很好的问题,我刚才在研究 Java 开发人员可以通过类路径获得乐趣的多种方式的示例时遇到了这个问题:-)
我从您的 build.gradle 的最小版本开始(仅包括直接相关的内容),具体而言:
在这种情况下,我的“主”类使用您的代码示例,即:
在这个阶段,我可以运行
gradle clean build
然后运行 ---java -jar build/libs/33106520.jar
(我的项目以这个 StackOverflow 问题命名),我看到了这个:这与您的错误略有不同,但在我们挖掘和重现之前,让我强调一些事情:这个错误和您看到的错误都是在运行时类加载器无法找到它需要的类时引起的。 这里 有一篇相当不错的博客文章,其中详细介绍了编译时类路径和运行时类路径之间的区别。
如果我运行
gradle dependencies
我可以看到我的项目的运行时依赖项:我将它们逐一手动添加到我的运行时类路径中。 (为了记录,这通常不被认为是好的做法;但为了实验,我将这些罐子复制到我的
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 库的一部分_,这是非常确实可疑。我怀疑您的运行时类路径包含 不同版本 的 Apache httpclient 库。由于那里有很多版本,我不会测试每一个组合,所以我会给你以下建议。
compile fileTree(dir: 'lib', include: ['*.jar'])
的方式使用依赖项。基于存储库(如 Maven 或 JCenter)的托管依赖项比随机目录中的依赖项更容易一致地使用。如果这些是您不想发布到开源工件存储库的内部库,那么可能值得设置一个本地 Nexus 实例或类似实例。build.gradle
中安装它,并运行gradle clean shadow
,我能够运行java -jar
很好,不需要手动添加任何东西到我的类路径。