繁体   English   中英

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

[英]Running a Gradle compiled Java application with dependencies via the java command

我正在尝试从本文编译代码示例3,以解释使用Gradle 的Swing应用程序框架(JSR 296) ,并使用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编译可以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以某种方式管理了这些gradle dependencies

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
…

最后,在了解到缺少运行时依赖关系的问题后,我找到了几种提供它们的方法,我将分享这些方法。

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

如此Stackoverflow答案中所述,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

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

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目录

Gradle用户指南的使用同步任务部分中,它显式地使用了一个示例,该示例描述了解决当前问题的更好方法:

这是一个在build / libs目录中维护项目运行时依赖项副本的示例。

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运行应用程序

通过应用程序插件, Gradle本身提供了运行应用程序的便捷解决方案。 将这两行添加到我的build.gradle

apply plugin:'application'

mainClassName = 'demo.BasicSingleFrameApp'

我可以通过gradle run成功启动应用程序。 到目前为止最简单的解决方案!

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

另外,如果您喜欢Application Plugin的gradle run任务,但又担心Gradle在目标系统上是否可用,请查看Gradle Wrapper

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

似乎存在仅Gradle方式Gradle插件 ,可帮助创建包含应用程序所有必需依赖项的jars。

如果使用gradle-one-jar-Plugin ,则可以使用如下java命令来启动应用程序:

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

从我得到的是,您只是使用Java启动应用程序,因此您必须告诉Java在哪里可以找到下载的swing应用程序框架jar。 所以命令应该看起来像

java -cp pathtojdektopjar/jdesktopjar.jar;build/classes/main/ demo.BasicSingleFrameApp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM