到现在为止,我通过Eclipse的“Export ...”功能创建了可运行的JAR文件,但现在我切换到了IntelliJ IDEA和Gradle以实现构建自动化。一些文章提出了“应用程序”插件,但这并不完全导致我期望的结果(只是一个JAR,没有启动脚本或类似的东西)。使用Gradle创建可运行的JAR
如何才能达到Eclipse使用“导出...”对话框所做的相同结果?
到现在为止,我通过Eclipse的“Export ...”功能创建了可运行的JAR文件,但现在我切换到了IntelliJ IDEA和Gradle以实现构建自动化。一些文章提出了“应用程序”插件,但这并不完全导致我期望的结果(只是一个JAR,没有启动脚本或类似的东西)。使用Gradle创建可运行的JAR
如何才能达到Eclipse使用“导出...”对话框所做的相同结果?
可执行的JAR文件只是包含在其清单一个主级条目的jar文件。所以,你只需要以在其清单添加此项配置jar task:
jar {
manifest {
attributes 'Main-Class': 'com.foo.bar.MainClass'
}
}
您可能还需要在清单中添加类路径条目,但会做同样的方式。
见http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
您是否尝试过'installApp'任务?它不是用一组启动脚本创建完整目录吗?
据我了解,'installApp'不创建'META-INF/MANIFEST.MF'文件。难道我做错了什么? – advait
两个JB Nizet和Jorge_B的答案是正确的。
以最简单的形式,使用Gradle创建可执行JAR只是将适当的条目添加到manifest。然而,需要在类路径中包含依赖关系更为常见,这使得这种方法在实践中变得棘手。
application plugin提供了一种替代方法;而不是创建一个可执行的JAR,它提供了:
run
任务,以便轻松地直接从构建installDist
任务产生包括内置JAR的目录结构运行的应用程序,所有的JAR文件的这这取决于,而且拉它连成一个程序的启动脚本,你可以运行创建一个包含一个完整的应用程序分发归档(启动脚本和JAR)distZip
和distTar
任务第三种方法是创建一个所谓的“胖JAR”,它是一个可执行JAR,它不仅包含组件的代码,还包含其所有依赖项。有几种不同的插件使用这种方法。我已经包含了一些我知道的链接;我相信还有更多。
只是试过阴影和一个罐子。我会坚持一个jar:它更简单,更易于使用。凉!谢谢 – Jako
您可以定义模块设置(或项目结构)的罐子神器。
制作一个jar就像在Build菜单中点击“Build artifact ...”一样简单。作为奖励,您可以将所有依赖关系打包到一个jar中。
经过IntelliJ IDEA 14 Ultimate测试。
正如其他人已经注意到的,为了使jar文件可执行,必须在清单文件的Main-Class
属性中设置应用程序的入口点。如果依赖关系类文件不搭配,则需要在清单文件的Class-Path
条目中设置它们。
我已经尝试过各种插件组合,并且对于创建可执行jar以及某种方式的简单任务来说,还包括依赖关系。所有插件似乎都缺乏这种或那种,但最终我得到了它,就像我想要的。没有神秘的脚本,没有百万个不同的迷你文件污染了构建目录,一个非常干净的构建脚本文件,最重要的是:没有一百万个外国第三方类文件合并到我的jar文件中。
下面是here为了您的方便复制粘贴..
[操作指南]在子目录/lib
创建依赖罐子分布zip文件,所有的依赖关系添加到清单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
}
作为要点主办here。
结果可以在build/distributions
发现并解压缩后的内容是这样的:
的lib /公地lang3-3.3.2.jar
myJarFile.jar中
内容的MyJarFile.jar#META-INF/MANIFEST.mf
:
Manifest-Version:1.0
主类:com.somepackage.MainClass
类路径:LIB /公地lang3-3.3.2.jar
我
当前的应用程序jar也将位于发行版的'lib'目录中。您必须将其移动到顶部目录或更改此行: 'Class-Path':configurations.runtime.files.collect {“lib/$ it.name”} .join('') } 对此: 'Class-Path':configurations.runtime.files.collect {“$ it.name”} .join('') } –
@MarcNuri Are you sure?我尝试在我的应用程序中使用这种方法,当前的应用程序jar在生成的zip/tar文件的'lib'目录中是** not **,而是在'lib'的父目录中,正如这个答案所暗示的。这个解决方案似乎对我来说非常合适。 – thejonwithnoh
@thejonwithnoh对不起,你是对的。我没有看到提出使用“java-library-distribution”插件的解决方案。就我而言,我只是简单地使用“应用程序”插件来完成相同的工作,主要区别在于所有的jar文件(**包括应用程序jar)都位于“lib”目录中。因此,将''lib/$ it.name'''改为''$ it.name'''即可完成这项工作。 –
最省力的解决办法是使用的gradle-shadow-plugin
除了应用插件,所有需要做的是:
配置jar任务把主类成清单
jar { manifest { attributes'Main-Class':'com.my.app。主 }}
运行gradle这个任务./gradlew shadowJar
采取应用程序版本,all.jar在从编译/库/
最后通过执行它:
java -jar app-version-all.jar
这是[完整的'build.gradle'示例](https://gist.github.com/TurekBot/4a3cd406cb52dfd8bfb8022b982f0f6c)。 –
谢谢康斯坦丁,它的工作方式像一个几乎没有细微差别的魅力。出于某种原因,将main类指定为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'
}
运行gradle这个shadowJar后你会得到myapp- {}版本在-all.jar你的build文件夹可以作为运行Java的罐子myapp- {}版本-all.jar。
我检查了相当一些解决方案的链接,最后做了下面提到的步骤来让它工作。我正在使用Gradle 2.9。
让你构建了以下变化,gradle这个文件:
提到插件:
apply plugin: 'eu.appsatori.fatjar'
提供的Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
提供主要类别:
fatJar {
classifier 'fat'
manifest {
attributes 'Main-Class': 'my.project.core.MyMainClass'
}
exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
}
创建fatjar:
./gradlew clean fatjar
运行从fatjar /建设/库/:
java -jar MyFatJar.jar
这似乎是我正在寻找;但是:我已经在build.gradle中声明了依赖关系,是否真的必须手动添加类路径,还是可以重新使用我的依赖关系声明? – Hannes
您应该能够遍历'runtime'配置中的库,并将它们连接起来以创建Class-Path属性值。 –
“inseid”运行时配置是什么意思?对于愚蠢的问题抱歉,我对Gradle相当陌生... – Hannes