到目前为止,我通过Eclipse"Export ..."功能创建了可运行的JAR文件,但现在我切换到IntelliJ IDEA和Gradle进行构建自动化.
这里的一些文章提出了"应用程序"插件,但这并不完全导致我期望的结果(只是一个JAR,没有启动脚本或类似的东西).
如何通过Eclipse"Export ..."对话框实现相同的结果?
JB *_*zet 147
可执行jar文件只是一个jar文件,其清单中包含Main-Class条目.所以你只需要配置jar任务就可以在它的清单中添加这个条目:
jar {
manifest {
attributes 'Main-Class': 'com.foo.bar.MainClass'
}
}
Run Code Online (Sandbox Code Playgroud)
您可能还需要在清单中添加类路径条目,但这将以相同的方式完成.
请参阅http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
dav*_*c24 90
JB Nizet和Jorge_B的答案都是正确的.
在最简单的形式中,使用Gradle创建可执行JAR只需要向清单添加适当的条目.但是,在类路径中包含需要包含的依赖项更为常见,这使得这种方法在实践中变得棘手.
的应用的插件提供了一种替代方法; 它不是创建可执行的JAR,而是提供:
run
任务,便于直接从构建中轻松运行应用程序installDist
生成目录结构的任务,包括构建的JAR,它依赖的所有JAR,以及将它们全部集成到您可以运行的程序中的启动脚本distZip
和distTar
创建包含完整应用程序分发(启动脚本和JAR)的归档的任务第三种方法是创建一个所谓的"胖JAR",它是一个可执行的JAR,不仅包括组件的代码,还包括它的所有依赖项.有一些不同的插件使用这种方法.我已经包含了一些我所知道的链接; 我相信还有更多.
Mar*_*son 31
正如其他人所指出的,为了使jar文件可执行,必须Main-Class
在清单文件的属性中设置应用程序的入口点.如果依赖类类文件未并置,则需要Class-Path
在清单文件的条目中设置它们.
我已经尝试了各种插件组合,而不是创建可执行jar的简单任务,不知怎的,包括依赖项.所有插件似乎都缺乏这种或那种方式,但最后我得到了它就像我想要的那样.没有神秘的脚本,没有一百万个不同的迷你文件污染构建目录,一个非常干净的构建脚本文件,最重要的是:没有一百万个外国第三方类文件合并到我的jar存档中.
以下是从复制粘贴在这里为您提供方便..
[如何]在子目录中创建具有依赖项jars的分发zip文件,/lib
并将所有依赖Class-Path
项添加到清单文件中的条目:
apply plugin: 'java'
apply plugin: 'java-library-distribution'
repositories {
mavenCentral()
}
dependencies {
compile 'org.apache.commons:commons-lang3:3.3.2'
}
// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)
jar {
// Keep jar clean:
exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'
manifest {
attributes 'Main-Class': 'com.somepackage.MainClass',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
}
// How-to add class path:
// https://stackoverflow.com/questions/22659463/add-classpath-in-manifest-using-gradle
// https://gist.github.com/simon04/6865179
}
Run Code Online (Sandbox Code Playgroud)
在这里担任要点.
结果可以找到build/distributions
,解压缩的内容如下所示:
lib/commons-lang3-3.3.2.jar
MyJarFile.jar
内容MyJarFile.jar#META-INF/MANIFEST.mf
:
清单 - 版本:1.0
Main-Class:com.somepackage.MainClass
Class-Path:lib/commons-lang3-3.3.2.jar
Ost*_*tan 23
对我来说最小的解决方案是使用gradle-shadow-plugin
除了应用插件之外,还需要做的是:
配置jar任务以将Main类放入清单
jar {manifest {attributes'Main-Class':'com.my.app.Main'}}
运行gradle任务./gradlew shadowJar
从build/libs /获取app-version-all.jar
最后通过以下方式执行:
jar {
manifest {
attributes 'Main-Class': 'com.my.app.Main'
}
}
Run Code Online (Sandbox Code Playgroud)
Mah*_*zad 16
这是针对Kotlin DSL (build.gradle.kts )。
application
或其他插件)tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
// OR another notation
// manifest {
// attributes["Main-Class"] = "com.example.MyMainClass"
// }
}
Run Code Online (Sandbox Code Playgroud)
如果您使用任何外部库,请使用以下代码。将库 JAR 复制到放置结果 JAR 的libs子目录中。确保您的库 JAR 文件的文件名中不包含空格。
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
manifest.attributes["Class-Path"] = configurations
.runtimeClasspath
.get()
.joinToString(separator = " ") { file ->
"libs/${file.name}"
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Java 要求我们对属性使用相对 URL Class-Path
。所以,我们不能使用Gradle依赖的绝对路径(这也容易被改变并且在其他系统上不可用)。如果您想使用绝对路径,也许这个解决方法会起作用。
使用以下命令创建 JAR:
./gradlew jar
Run Code Online (Sandbox Code Playgroud)
默认情况下,结果 JAR 将在build/libs/目录中创建。
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
val dependencies = configurations
.runtimeClasspath
.get()
.map(::zipTree) // OR .map { zipTree(it) }
from(dependencies)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Run Code Online (Sandbox Code Playgroud)
创建 JAR 与之前的方法完全相同。
plugins {
id("com.github.johnrengelman.shadow") version "6.0.0"
}
// Shadow task depends on Jar task, so these will be reflected for Shadow as well
tasks.jar {
manifest.attributes["Main-Class"] = "org.example.MainKt"
}
Run Code Online (Sandbox Code Playgroud)
使用以下命令创建 JAR:
./gradlew shadowJar
Run Code Online (Sandbox Code Playgroud)
有关配置插件的更多信息,请参阅Shadow 文档。
java -jar my-artifact.jar
Run Code Online (Sandbox Code Playgroud)
上述解决方案经过以下测试:
有关创建 uber (fat) JAR 的信息,请参阅官方Gradle 文档。
有关清单的更多信息,请参阅Oracle Java 文档:使用清单文件。
请注意,您的资源文件将自动包含在 JAR 文件中(假设它们放置在/src/main/resources/目录中或在构建文件中设置为资源根目录的任何自定义目录中)。要访问应用程序中的资源文件,请使用以下代码(请注意/
名称开头的 ):
val vegetables = MyClass::class.java.getResource("/vegetables.txt").readText()
// Alternative ways:
// val vegetables = object{}.javaClass.getResource("/vegetables.txt").readText()
// val vegetables = MyClass::class.java.getResourceAsStream("/vegetables.txt").reader().readText()
// val vegetables = object{}.javaClass.getResourceAsStream("/vegetables.txt").reader().readText()
Run Code Online (Sandbox Code Playgroud)
var stream = MyClass.class.getResource("/vegetables.txt").openStream();
// OR var stream = MyClass.class.getResourceAsStream("/vegetables.txt");
var reader = new BufferedReader(new InputStreamReader(stream));
var vegetables = reader.lines().collect(Collectors.joining("\n"));
Run Code Online (Sandbox Code Playgroud)
你试过'installApp'任务吗?它是否不使用一组启动脚本创建完整目录?
http://www.gradle.org/docs/current/userguide/application_plugin.html
小智 5
谢谢康斯坦丁,它就像一个魅力,没有什么细微差别。由于某种原因,将主类指定为 jar 清单的一部分不太有效,它需要 mainClassName 属性。以下是 build.gradle 的一个片段,其中包含使其工作的所有内容:
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
baseName = 'myapp'
}
Run Code Online (Sandbox Code Playgroud)
运行 gradle ShadowJar 后,您会在构建文件夹中获得 myapp-{version}-all.jar,它可以作为 java -jar myapp-{version}-all.jar 运行。
您可以使用 SpringBoot 插件:
plugins {
id "org.springframework.boot" version "2.2.2.RELEASE"
}
Run Code Online (Sandbox Code Playgroud)
创建罐子
gradle assemble
Run Code Online (Sandbox Code Playgroud)
然后运行它
java -jar build/libs/*.jar
Run Code Online (Sandbox Code Playgroud)
注意:您的项目不需要是 SpringBoot 项目即可使用此插件。
归档时间: |
|
查看次数: |
150041 次 |
最近记录: |