使用Gradle在清单中添加类路径

时间:2014-03-26 11:23:39

标签: java gradle

我希望我的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

9 个答案:

答案 0 :(得分:64)

在Gradle论坛上找到解决方案:

jar {
  manifest {
    attributes(
      "Class-Path": configurations.compile.collect { it.getName() }.join(' '))
  }
}

来源:Manifest with Classpath in Jar Task for Subprojects

答案 1 :(得分:10)

在最新版本的gradle中,compileruntime已弃用。相反,请使用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/")
        }
    }
} 

来源:uploading_to_maven_repositories

答案 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
}