gpt4 book ai didi

java - 通过 java 命令运行具有依赖项的 Gradle 编译 Java 应用程序

转载 作者:行者123 更新时间:2023-11-30 07:01:59 24 4
gpt4 key购买 nike

我正在尝试编译来自 this article explaining the Swing Application Framework (JSR 296) 的代码示例 3与 Gradle并使用 java 命令从命令行运行它。

我的目录布局是这样的:

├── build.gradle
└── src/
└── main/
└── java/
└── demo/
└── BasicSingleFrameApp.java

build.gradle 文件定义了对 appframework 的依赖:

apply plugin: 'java'

repositories {
mavenCentral()
}

dependencies {
compile 'org.jdesktop:appframework:1.0.3'
}

这是 BasicSingleFrameApp.java 文件,是上述文章示例的副本,通过包声明进行了增强:

package demo;

import org.jdesktop.application.*;
import javax.swing.*;
import java.awt.*;

public class BasicSingleFrameApp extends SingleFrameApplication {
JLabel label;

@Override
protected void startup() {
getMainFrame().setTitle("BasicSingleFrameApp");
label = new JLabel("Hello, world!");
label.setFont(new Font("SansSerif", Font.PLAIN, 22));
show(label);
}

public static void main(String[] args) {
Application.launch(BasicSingleFrameApp.class, args);
}

}

使用 gradle build 编译工作正常,没有错误。

但是当我尝试运行 BasicSingleFrameApp

$ java -cp build/classes/main/ demo.BasicSingleFrameApp

我收到错误信息:

Error: Could not find or load main class demo.BasicSingleFrameApp

当我用简单的“Hello, world!”替换 BasicSingleFrameApp 类时没有依赖项的打印类,一切正常。

我很困惑,因为根据我的理解,我正确地设置了类路径,但我不明白为什么找不到 main 方法(具有正确的签名)。

这是我的 Java 版本:

java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

我运行的是 Mac OS X Yosemite 10.10.2。

最佳答案

好吧,@chuchikaeschtli 帮助我找到了问题的核心,即 Gradle 管理编译的依赖项并报告在运行时这样做,但是需要更多的手动任务才能使这些依赖项在运行时可用。

仍然让我感到困惑的是我收到的不直观的错误消息:

Error: Could not find or load main class demo.BasicSingleFrameApp

我本以为会出现与运行时缺少依赖项有关的问题,以报告类似

的错误
error: package org.jdesktop.application does not exist

这是我在编译时缺少这些依赖项时遇到的那种错误。

当 Gradle 向我提供以下关于运行时依赖项的报告时(通过运行 gradle dependencies),我认为 Gradle 以某种方式管理了这些:

compile - Compile classpath for source set 'main'.
\--- org.jdesktop:appframework:1.0.3
\--- org.jdesktop:swing-worker:1.1

runtime - Runtime classpath for source set 'main'.
\--- org.jdesktop:appframework:1.0.3
\--- org.jdesktop:swing-worker:1.1

最后,在知道是缺少运行时依赖的问题后,我找到了几种提供它们的方法,我将分享。

第一个解决方案:链接到缓存

this Stackoverflow answer 中所述,Gradle 在 $HOME/.gradle 中缓存依赖项,但它们的实际路径很棘手。答案描述了一个小的 Gradle 任务,它输出缓存中每个依赖项的完整路径(在本例中为 compile 配置,这是我需要的):

task showMeCache << {
configurations.compile.each { println it }
}

在我的例子中,gradle showMeCache 报告:

$HOME/.gradle/caches/modules-2/files-2.1/org.jdesktop/appframework/1.0.3/338045feff6e61df237aafd11b6f3fe1a3b4e60e/appframework-1.0.3.jar
$HOME/.gradle/caches/modules-2/files-2.1/org.jdesktop/swing-worker/1.1/dc9f8d6f7236087924aad28fbec794a087dd1b3d/swing-worker-1.1.jar

这些是又长又讨厌的文件路径,但我能够构建一个 java 命令,它以@chuchikaeschtli 建议的样式工作:

java \
-cp build/classes/main/\
:$HOME/.gradle/caches/modules-2/files-2.1/org.jdesktop/appframework/1.0.3/338045feff6e61df237aafd11b6f3fe1a3b4e60e/appframework-1.0.3.jar\
:$HOME/.gradle/caches/modules-2/files-2.1/org.jdesktop/swing-worker/1.1/dc9f8d6f7236087924aad28fbec794a087dd1b3d/swing-worker-1.1.jar \
demo.BasicSingleFrameApp

这行得通,但当然感觉不太“对”。但这有助于理解问题:这实际上是缺少依赖项 jar 的问题。

第二种方案:同步依赖到build目录

Using the Sync task of the Gradle User Guide 部分中,它明确使用了一个示例来描述手头问题的更好解决方案:

Here is an example which maintains a copy of the project's runtime dependencies in the build/libs directory.

task libs(type: Sync) {
from configurations.runtime
into "$buildDir/libs"
}

在使用 gradle libs 运行此任务后,我能够构建一个更简单的工作 java 命令:

java -cp build/classes/main/:build/libs/appframework-1.0.3.jar:build/libs/swing-worker-1.1.jar demo.BasicSingleFrameApp

请记住:默认情况下,这些依赖项并未同步到 build 目录中!

方案三:使用Gradle运行应用

有了 Application Plugin,Gradle 本身就为运行应用程序提供了一个方便的解决方案。将这两行添加到我的 build.gradle

之后
apply plugin:'application'

mainClassName = 'demo.BasicSingleFrameApp'

我能够通过 gradle run 成功启动应用程序。迄今为止最简单的解决方案!

请注意,应用程序插件还提供了一个名为 installDist 的任务,该任务在 build/install 中创建了一个可运行的应用程序及其所有依赖项的分发版,并包含了启动脚本UNIX 和 Windows 系统。这样做的好处是不需要 Gradle 来执行应用程序。

此外,如果您喜欢应用程序插件的 gradle run 任务,但担心 Gradle 在目标系统上是否可用,请查看 Gradle Wrapper

第四种解决方案:创建 One-JAR、Fat Jar 或 Uber Jar

似乎存在 Gradle-only waysGradle plugins 可以帮助创建这些包含应用程序所需的所有依赖项的 jar。

gradle-one-jar-Plugin 的情况下,然后可以使用 java 命令启动应用程序,例如:

java -jar build/libs/YOUR_APP_NAME-standalone.jar

关于java - 通过 java 命令运行具有依赖项的 Gradle 编译 Java 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29379736/

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