运行从基于 gradle 的项目构建的可执行 jar 文件

Posted

技术标签:

【中文标题】运行从基于 gradle 的项目构建的可执行 jar 文件【英文标题】:Running an executable jar file built from a gradle based project 【发布时间】:2014-01-10 18:59:35 【问题描述】:

我有一个基于 gradle 的独立项目。当我做 gradle build 时,jar 是在 build/libs 下生成的。如何从命令行运行这个可执行 jar?我试过了:java -cp build/libs/foo.jar full.package.classname 但我得到了导入的类的 noClassFoundException 。如何将依赖 jar 包作为类路径的一部分?

【问题讨论】:

如果你有一个可执行的 jar 只需使用 java -jar path-to-jar-file 考虑使用应用插件。见gradle.org/docs/current/userguide/application_plugin.html @Satya 我收到无法加载主类清单属性错误。当我使用 gradle (gradle run -DmainClass=) 运行它时,它会将所有 jars(来自 ~/.gradle/caches 目录)添加为类路径的一部分。仅使用构建的 jar 文件还有其他方法吗? @Jayan 我正在使用应用程序插件在我的本地开发盒上构建和运行。但是在生产环境中,gradle 可能不存在,我只能将 jar 复制到 prod 并运行。 截至主题:如果您不确定 gradle 的可用性,请使用 gradlew 【参考方案1】:

由于问题标有 gradle 标签,我假设您想从 gradle build 运行 jar。我还假设您使用 java 插件进行 gradle 构建。

在你的 gradle 中添加下一行:

task runFinalJar(type: JavaExec) 
   classpath = files('build/libs/foo.jar')
   classpath += sourceSets.main.runtimeClasspath
   main = full.package.classname

您现在可以将您的任务包含在构建过​​程中:

build.dependsOn.add("runFinalJar")

或者直接从命令行运行:

gradle build runFinalJar

更新:使用应用插件as Peter suggested更简洁

【讨论】:

实际上我可以从 gradle build 成功运行它。我会使用 gradle build 创建一个 jar 文件,这个 jar 将部署在不一定安装 gradle 的生产环境中。所以问题是如何运行这个jar? Gradle 在内部包含所有依赖的 jars(来自 ~/.gradle 目录)作为类路径的一部分。所以我想知道是否有任何方法可以仅使用 jar 文件轻松完成。 gradlew 会帮你安装gradle 我不想在 prod 环境中安装 gradle。不过,我找到了解决方法。通过编写一个简单的 gradle 任务,我能够将项目的所有依赖 jar 复制到一个目录中。现在,我的 jar 和它的依赖 jar 在一个目录中可用:~/myproject/build/libs。如果我执行 java -cp *.jar 我在我的主类上得到一个 NoClassDefinedException。我验证了我的项目的 jar 在同一个目录中,并且也有主类。我错过了什么? 我也想知道同样的事情。我也不知道如何让 gradle 生成一个完全打包的 jar,它可以在没有 gradlew 的情况下运行。如何将依赖类捆绑到输出 jar 中? 这一行:classpath = file('build/libs/foo.jar') 给了我一个“Cannot cast object 'path to jar' with class "java.io.File" to class 'org .gradle.api.file.FileCollection' - 所以我猜它不应该是 file(...) 而是类似 fileset(...) 的东西(我不认为 fileset 存在,但是有些东西,所以确实存在其他东西而是在 gradle 中)?【参考方案2】:

要么使用application plugin 创建一个包含你的代码、它的依赖项和启动脚本的存档,要么创建一个可执行的 fat Jar。后者不应该以幼稚的方式完成,而应使用gradle-one-jar(或类似的)插件。

【讨论】:

可以通过告诉读者如何识别“天真的方式”来改进这个答案。例如,使用from configurations.compile.collect it.isDirectory() ? it : zipTree(it) with jar 是一种幼稚的方式吗?【参考方案3】:

添加一个简单的任务来运行jar

task runJar(type: JavaExec) 
    main = "-jar";
    args jar.archivePath

更新jar.archivePath 现已弃用,您可以使用jar.archiveFile.get()

task runJar(type: JavaExec) 
    main = "-jar";
    args jar.archiveFile.get()

【讨论】:

【参考方案4】:

我认为答案超出了实际问题的范围。问题是,或者可以重述为,如何运行 gradle 构建的 JAR。

提问者表示他们尝试过java -cp build/libs/foo.jar full.package.classname 无济于事。

正确的语法是 java -jar build/libs/foo.jar,或者如果 JAR 就在那儿,那么显然它就像往常一样只是 java -jar foo.jar

为了清楚起见,应该编辑问题,恕我直言。

【讨论】:

【参考方案5】:

我是新手,所以我在这里的解释会很简单。我的build.gradle 文件只包含一行:apply plugin: 'java'。我在src/main/java/org/dx/test/App.java 中有一个hello world java 代码。在命令 shell 中,我输入:gradle build。然后我看到这个jar文件神奇地创建了:

build/libs/helloworld.jar

以上所有答案均无效。对我有用的是:

java -cp build/libs/helloworld.jar org.dx.test.App

现在,我知道 gradle 充满了魔法,所以我确信我的情况可能无法完全反映您的情况。采取的行动是:

    创建那一行build.gradle文件 在医生指定的文件夹位置下创建App.java 输入gradle build

【讨论】:

以上是关于运行从基于 gradle 的项目构建的可执行 jar 文件的主要内容,如果未能解决你的问题,请参考以下文章

Gradle学习笔记之Groovy

运行从 Ubuntu 到 Debian 的可执行文件

jenkins构建基于gradle的springboot项目CI采坑(采用jar方式部署)

使用 Gradle 构建 Java 项目

下载的可执行文件无法在主机上执行

在gradle中构建java项目