gpt4 book ai didi

java - 如何将类路径添加到 Gradle JavaExec 任务以执行可运行的 jar?

转载 作者:行者123 更新时间:2023-11-30 05:49:45 26 4
gpt4 key购买 nike

我的应用程序需要 spring-context图书馆。所以在我的build.gradle文件,我添加这个依赖,

dependencies {
compile 'org.springframework:spring-context:5.1.6.RELEASE'
}

我还想创建一个可运行的 jar 文件,jar任务看起来像,

jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}
}

启动构建文件时一切正常,

gradle build

但是当我尝试执行这个可运行的 jar 应用程序时,

task runJar(dependsOn: jar, type: JavaExec) {
classpath(configurations.compile)
main = '-jar'; args 'build/libs/my-runnable.jar'
}

控制台抛出 NoClassDefFoundError ,

Exception in thread "main" java.lang.NoClassDefFoundError: 
org/springframework/context/ConfigurableApplicationContext
...
...

我试过了 sourceSets.main.runtimeClasspath ,问题依旧,

task runJar(dependsOn: jar, type: JavaExec) {
classpath(sourceSets.main.runtimeClasspath)
main = '-jar'; args 'build/libs/my-runnable.jar'
}

我检查了 classpath文件收集,

classpath.each {
println it.name
}

spring-context包裹就在那里,

spring-context-5.1.6.RELEASE.jar
spring-aop-5.1.6.RELEASE.jar
spring-beans-5.1.6.RELEASE.jar
spring-expression-5.1.6.RELEASE.jar
spring-core-5.1.6.RELEASE.jar
spring-jcl-5.1.6.RELEASE.jar

然后我尝试了另一种绕过方法来解决这个问题。我从那些 .jar 中提取了所有类文件库,并将它们直接包含在我的最终 runnable.jar 中,

jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}

configurations.compile.each {
from(project.zipTree(it))
}
}

而且这个解决方案有效。但这样的“肥 jar ”并不是我想要的。

我是gradle的新手。这真的让我很困惑。任何人都可以帮忙吗?谢谢!

最佳答案

经过大约 3 个小时的工作,一个简单的事实是:

When you specify -jar then the -cp parameter will be ignored.

一些详细的讨论在这个问题中:

Run a JAR file from the command line and specify classpath

有 2 种简单的绕行解决方案:

  1. 如我在问题中提到的那样,将所有 .class 文件直接提取到您的可执行 jar 中。
jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}

configurations.compile.each {
from(project.zipTree(it))
}
}
  1. 第二种解决方案是在manifest 文件中添加一个Class-Path 参数。
jar {
manifest {
attributes 'Main-Class': 'your.main.class.full.name'
attributes 'Class-Path': configurations.compile.collect { it.name }.join(' ')
}
}

确保您可以在本地系统中找到 .jar 库。例如,只需将它们复制到同一目录中,

task copyLibs(type: Copy) {
from configurations.compile
into 'build/libs/'
}

之后我的 build/libs/ 目录看起来像,

build
├── libs
│   ├── my-runnable-app.jar
│   ├── spring-aop-5.1.6.RELEASE.jar
│   ├── spring-beans-5.1.6.RELEASE.jar
│   ├── spring-context-5.1.6.RELEASE.jar
│   ├── spring-core-5.1.6.RELEASE.jar
│   ├── spring-expression-5.1.6.RELEASE.jar
│   └── spring-jcl-5.1.6.RELEASE.jar

请注意,所有 .jar 库都位于 my-runnable-app.jar 之外。如果你想将它们包含在你的 my-runnable-app.jar 中,你需要 One-Jar 工具包。有关 One-Jar 的更多信息,请阅读以下问题:

Reference jars inside a jar

关于java - 如何将类路径添加到 Gradle JavaExec 任务以执行可运行的 jar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55769289/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com