我希望我的Gradle构建脚本将完整的Classpath添加到构建后创建的JAR文件中包含的清单文件中。
示例:
Manifest-Version: 1.0
Class-Path: MyProject.jar SomeLibrary.jar AnotherLib.jar
我的构建脚本已经以这种方式向清单添加了一些信息:
jar {
manifest {
attributes("Implementation-Title": project.name,
"Implementation-Version": version,
"Main-Class": mainClassName,
}
}
如何获取要添加到清单的依赖项列表?
这个Java教程页面更详细地描述了向清单添加类路径的方式和原因:Adding Classes to the JAR File's Classpath
答案 0 :(得分:64)
在Gradle论坛上找到解决方案:
jar {
manifest {
attributes(
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
}
答案 1 :(得分:10)
在最新版本的gradle中,compile
和runtime
已弃用。相反,请使用runtimeClasspath
,如下所示:
'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')
答案 2 :(得分:5)
将其放在buid.gradle
文件的末尾。将com.example.Main
更改为您自己的主类。
jar {
doFirst {
manifest {
if (!configurations.compile.isEmpty()) {
attributes(
'Class-Path': configurations.compile.collect{it.toURI().toString()}.join(' '),
'Main-Class': 'com.example.Main')
}
}
}
}
答案 3 :(得分:2)
我知道这对于这里的常规人来说可能微不足道,但在我的情况下,我想根据我是否要在生产环境中运行来改变清单文件中Class-Path
的位置。当地环境。我这样做的方法是让build.gradle
的jar部分看起来像这样:
jar {
from configurations.runtime
manifest {
attributes ('Main-Class': 'com.me.Main',
'Class-Path': configurations.runtime.files.collect { jarDir+"/$it.name" }.join(' ')
)
}
}
在这种情况下,gradle build
的参数传递如下:
$ gradle build -PjarDir="/opt/silly/path/"
答案 4 :(得分:2)
她给我的帮助很多。这对我有用:
jar {
manifest {
attributes "Main-Class": "your.package.classWithMain"
attributes "Class-Path": configurations.compile.collect { it.absolutePath }.join(" ")
}
}
因此,我不得不使用absolutePath。这可能适用于您,也可能不适合您。有人建议使用运行时而不是编译。我使用compile,因为我在build.gradle中有依赖项的编译部分。因此,jar步骤从那里获取依赖关系。最好的办法是选择你认为可以工作的东西,做一个gradle构建,然后找到JAR文件并展开它以找到META-INF / MANIFEST.MF文件。您应该能够看到由空格分隔的所有目录。如果没有,你应该尝试不同的东西。 IDE的自动完成功能应该有助于查看配置/编译等下所有可用的方法或字段。所有这些都可以在IntelliJ中轻松完成。
哦..如果您想查看磁带库JAR在磁盘上的实际位置,请右键单击您的项目 - >打开模块设置 - >图库,然后单击任何库。
答案 5 :(得分:0)
我有一个类似但不完全相同的问题。 我在工件中发布了我的lib jar L,后来将它作为模块M的依赖项获取,但是传递依赖项,即L需要用于编译和运行时的依赖项,并没有随之而来。我花了一些时间才意识到我的jar被发布到带有空pom文件的artifactory中,因此gradle无法知道哪些是L的传递依赖性。 缺失的部分是L&#39的build.gradle中的一条指令,用于发布pom。 与gradle一样,insturction的名称及其含义之间的联系完全是:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost/tmp/myRepo/")
}
}
}
答案 6 :(得分:0)
看起来像gradle已经进化了。这是另一个看起来与其他答案相似的答案,但是有一个关键的区别:如果您在implementation
中使用新的关键字dependencies
,则其他答案均无效,您将得到一个空白课程路径
dependencies {
// ensure the keyword here matches what
// you have in the jar->manifest->attributes
// that is "implementation"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
// ...
}
// by default, implementation cannot be referenced,
// this allows us to use it below
project.configurations.implementation.setCanBeResolved(true)
jar{
manifest {
attributes(
"Main-Class": "app.Program",
"Class-Path": configurations.implementation.collect { it.name }.join(' ')
)
}
dependsOn ('dependencies')
}
答案 7 :(得分:0)
如果您的项目具有外部库依赖项,则可以将jars复制到文件夹中,并在清单中添加类路径条目。
def dependsDir = "${buildDir}/libs/dependencies/"
task copyDependencies(type: Copy) {
from configurations.compile
into "${dependsDir}"
}
task createJar(dependsOn: copyDependencies, type: Jar) {
manifest {
attributes('Main-Class': 'com.example.gradle.App',
'Class-Path': configurations.compile.collect { 'dependencies/' + it.getName() }.join(' ')
)
}
with jar
}
更多详细信息,请阅读here
答案 8 :(得分:0)
我设法用其自己的清单文件创建了一个自定义的Jar文件,如下所示:
task createJar(type : Jar) {
manifest {
attributes(
'Manifest-Version': "1.0",
'Main-Class': "org.springframework.boot.loader.JarLauncher",
'Start-Class': "com.my.app.AppApplication",
'Spring-Boot-Version': "2.2.4.RELEASE",
'Spring-Boot-Classes': "BOOT-INF/classes/",
'Spring-Boot-Lib': "BOOT-INF/lib/"
)
}
def originDir = file("${buildDir}/unpacked")
def destinationFile = "${buildDir}/repackaged/${project.name}-${version}"
entryCompression ZipEntryCompression.STORED // no compression in case there are files in BOOT-INF/lib
archiveName destinationFile
from originDir
archiveFile
}