希望这对某人有所帮助(不幸的是,我花了很长时间试图找到解决方案)。这是对我有用的创建可执行 JAR 的解决方案。我将 Jetty 嵌入到主要方法中,具体来说是 Jetty 9 并使用 Gradle 2.1。
将以下代码包含到您的 build.gradle 文件中(如果子项目是需要从中构建 jar 的“主”项目,则将其添加到应该像此项目(':')一样开始的子项目中{插入代码在依赖关系之后的某个地方。}。
此外,您需要添加插件 java 才能工作:apply plugin: 'java' 。
我的 jar 任务如下所示:
apply plugin: 'java'
jar {
archiveName = "yourjar.jar"
from {
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'your.package.name.Mainclassname'
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
然后你可以通过命令行执行 yourjar.jar :
java -jar yourjar.jar
必须排除META-INF/ .RSA、META-INF/ .SF 和 META-INF/*.DSA 才能使其工作。否则会抛出 SecurityException。
问题似乎出在嵌入式 Jetty 上,因为 Jetty 迁移到 Eclipse,现在正在签署他们的 JAR,当其他未签名的 JAR 想要加载已签名的 JAR 时,我读到这会成为问题。如果我在这方面错了,请随时教育我,这就是我读到的。
项目所依赖的 JAR 在依赖项中定义如下:
dependencies {
// add the subprojects / modules that this depends on
compile project(':subproject-1')
compile project(':subproject-2')
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.6.v20141205'
}
编辑:之前,而不仅仅是
configurations.runtime.collect{...}
我有
configurations.runtime.asFileTree.files.collect{...}
这在干净构建的大型项目中导致了奇怪的行为。第一次执行 gradle clean build 后运行 jar (手动清理构建目录后),会抛出 NoClassDefFoundException (在我们有很多子项目的项目中),但在第二次执行 gradle clean build 后运行 jar(没有手动清空构建目录),由于某种原因它具有所有依赖项。如果 asFileTree.files 被忽略,这不会发生。
另外我应该注意,所有编译依赖项都包含在运行时中,但并非所有运行时都包含在编译中。所以如果你只是使用编译
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
然后请务必记住,如果抛出 NoClassDefFoundException,则在运行时找不到某些类,这意味着您还应该包括以下内容:
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}