简体   繁体   English

Gradle 可以在没有 main() 的情况下执行 TornadoFX 应用程序,而 IntelliJ 不能……为什么?

[英]Gradle can execute TornadoFX app without main() while IntelliJ can't…why?

I've just set up a simple Hello World project with the following code in Kotlin + TornadoFX with IntelliJ IDEA Community.我刚刚在 IntelliJ IDEA 社区的 Kotlin + TornadoFX 中使用以下代码设置了一个简单的 Hello World 项目。 For some reason, if I type gradlew run at the command line, it manages to run the app by loading the MainApp class directly, but IntelliJ insists "class MainApp has no main() method", refusing to launch the app unless I explicitly write a main() function.出于某种原因,如果我在命令行键入gradlew run ,它会通过直接加载 MainApp class 来管理应用程序,但 IntelliJ 坚持“类 MainApp 没有 main() 方法”,除非我明确写,否则拒绝启动应用程序一个main() function。 Why is this?为什么是这样? How can I (or can I at all) get IntelliJ to run the app the same way gradle is managing?我怎样才能(或完全可以)让 IntelliJ 以 gradle 管理的方式运行应用程序?

Here's the Kotlin source file这是 Kotlin 源文件

import tornadofx.*

// Define application with main View `Main`
class MainApp : App(Main::class)

// Define the view to display
class Main : View() {

    // override the root view with our container with the label within
    override val root = hbox {
        // use the tornado kotlin dsl to add a label and set the text
        label {
            text = "Hello World"
        }
    }
}

And here's build.gradle.kts这是 build.gradle.kts

plugins {
    kotlin("jvm") version "1.3.72"
    application
    id("org.openjfx.javafxplugin") version "0.0.8"
}

javafx {
    // Declare the javafx modules we need to use
    modules("javafx.controls")
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    implementation("no.tornado:tornadofx:1.7.20")
}

application {
    mainClassName = "MainApp"
}

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
}

After downloading your test project there are a couple of things I see:下载您的测试项目后,我看到了几件事:

  1. Your run configuration for "MainApp" is not using gradle but is using an Intellij managed project configured to build and run the application.您的“MainApp”运行配置未使用 gradle,而是使用配置为构建和运行应用程序的 Intellij 托管项目。
  2. MainApp.kt does not have a "main" function for Intellij to run MainApp.kt 没有供 Intellij 运行的“主”function

I'm not an expert on Intellij or gradle so I can't explain why you can launch with gradle without main function but can't do so from Intellij.我不是 Intellij 或 gradle 方面的专家,所以我无法解释为什么您可以在没有主 function 的情况下使用 gradle 启动但不能从 Intellij 启动。 I expect that gradle can somehow inject a main function that can execute the JavaFX Application class defined by your MainApp (TornadoFX App class extends JavaFX Application class). I expect that gradle can somehow inject a main function that can execute the JavaFX Application class defined by your MainApp (TornadoFX App class extends JavaFX Application class).

To get this working, you can either setup a run configuration to use gradle or add the main function to MyApp.kt and update the MainApp run configuration.要使其正常工作,您可以设置运行配置以使用 gradle 或将主 function 添加到 MyApp.kt 并更新 MainApp 运行配置。

Use Gradle to Run from Intellij使用 Gradle 从 Intellij 运行

  1. Click the gradle tab on the right hand side of Intellij单击 Intellij 右侧的 gradle 选项卡
  2. Expand the kotlin-gradle configuration for Tasks -> application展开 Tasks -> application 的 kotlin-gradle 配置
    Note: You may need to click the "refresh" button on the top left of the gradle panel to refresh the list of available tasks.注意:您可能需要单击 gradle 面板左上角的“刷新”按钮来刷新可用任务列表。
  3. Double click "run" and the gradle run task will be executed双击“运行”,执行gradle运行任务
  4. When you do this, Intellij will automatically add a new configuration "test-project [run]"当你这样做时,Intellij 会自动添加一个新的配置“test-project [run]”

Screenshot of Gradle Panel Gradle面板截图

Note: It is still a good idea to add the main function as described below and update your build.gradle.kts to use "MainAppKt".注意:按如下所述添加主 function 并更新您的 build.gradle.kts 以使用“MainAppKt”仍然是一个好主意。 This will give you some flexibility in launching your application with Java 9+ without requiring module definitions (ie non-modular appplication)这将使您在使用 Java 9+ 启动应用程序时具有一定的灵活性,而无需模块定义(即非模块化应用程序)

Use Intellij to Run使用 Intellij 运行

  1. Add the following code to your MainApp.kt将以下代码添加到您的 MainApp.kt
fun main(args: Array<String>) {
    launch<MainApp>(args)
}
  1. Edit your existing "MainApp" run configuration and change the Main class to "MainAppKt"编辑您现有的“MainApp”运行配置并将 Main class 更改为“MainAppKt”
  2. Click Ok to save and you can now run the "MainApp" configuration单击确定保存,您现在可以运行“MainApp”配置


Last note : If you are using Java 9+, you need to use a snapshot build of TornadoFX otherwise, you will run into problems.最后注意:如果您使用的是 Java 9+,则需要使用 TornadoFX 的快照构建,否则会遇到问题。

Add the snapshot repository to your respoitories section with将快照存储库添加到您的存储库部分

maven("https://oss.sonatype.org/content/repositories/snapshots")

And update the TornadoFX version to "2.0.0-SNAPSHOT"并将 TornadoFX 版本更新为“2.0.0-SNAPSHOT”

implementation("no.tornado:tornadofx:2.0.0-SNAPSHOT")



Old Answer旧答案

You are missing the mainClassName setting in your build.gradle.kts:您在 build.gradle.kts 中缺少 mainClassName 设置:

application {
    mainClassName = "com.example.demo.app.MyApp"
}

Some notes:一些注意事项:

  • If you have a main function that launches your app such as below, then you need to append "Kt" to the main class name where the function is located since a new class is created by kotlin to hold the static main function for the JVM. If you have a main function that launches your app such as below, then you need to append "Kt" to the main class name where the function is located since a new class is created by kotlin to hold the static main function for the JVM. For example, if in the MyApp.kt file I had the main function below, I would need to use "com.example.demo.app.MyAppKt" in order to call the main function to run the application.例如,如果在 MyApp.kt 文件中我有下面的主 function,我需要使用“com.example.demo.app.MyAppKt”来调用主 function 来运行应用程序。
fun main(args: Array<String>) {
    launch<MyApp>(args)
}
  • The syntax for the mainClassName is different depending on the gradle version and the language. mainClassName 的语法因 gradle 版本和语言而异。 I normally use groovy so I had to look it up for kts.我通常使用 groovy 所以我不得不查找它的 kts。 The current gradle version 6.4 uses a different syntax than 6.3.当前的 gradle 版本 6.4 使用与 6.3 不同的语法。 The syntax I provided is for 6.3.我提供的语法适用于 6.3。 I'm not sure when the change was made so you may need to verify the correct syntax for your gradle version.我不确定何时进行更改,因此您可能需要验证 gradle 版本的语法是否正确。

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

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