Gradle может запускать приложение TornadoFX без main (), а IntelliJ не может ... почему? - PullRequest
0 голосов
/ 28 мая 2020

Я только что создал простой проект Hello World со следующим кодом в Kotlin + TornadoFX с IntelliJ IDEA Community. По какой-то причине, если я наберу gradlew run в командной строке, ему удастся запустить приложение, загрузив класс MainApp напрямую, но IntelliJ настаивает, что «класс MainApp не имеет метода main ()», отказываясь запускать приложение, если я явно не напишите функцию main(). Почему это? Как я могу (или могу вообще) заставить IntelliJ запускать приложение так же, как и gradle?

Вот 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"
        }
    }
}

А вот 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"
    }
}

1 Ответ

1 голос
/ 28 мая 2020

После загрузки вашего тестового проекта я вижу несколько вещей:

  1. Ваша конфигурация запуска для «MainApp» не использует gradle, но использует управляемый проект Intellij, настроенный для сборки и запуска application.
  2. MainApp.kt не имеет "основной" функции для запуска Intellij

Я не эксперт по Intellij или gradle, поэтому я не могу объяснить, почему вы может запускаться с помощью gradle без основной функции, но не может этого делать из Intellij. Я ожидаю, что gradle может каким-то образом внедрить основную функцию, которая может выполнять класс приложения JavaFX, определенный вашим MainApp (класс приложения TornadoFX расширяет класс приложения JavaFX).

Чтобы это работало, вы можете либо настроить конфигурацию запуска на используйте gradle или добавьте основную функцию в MyApp.kt и обновите конфигурацию запуска MainApp.

Используйте Gradle для запуска из Intellij

  1. Щелкните вкладку gradle в правой части Intellij
  2. Разверните kotlin - конфигурация gradle для задач -> приложение Примечание: вам может потребоваться нажать кнопку «refre sh» в верхнем левом углу панели градиента, чтобы обновить sh список доступных задач.
  3. Дважды щелкните «запустить» и запустить задачу gradle. будет выполнено
  4. Когда вы это сделаете, Intellij автоматически добавит новую конфигурацию «test-project [run]»

Скриншот панели Gradle

Примечание: По-прежнему рекомендуется добавить основную функцию, как описано ниже, и обновить build.gradle.kts, чтобы использовать «MainAppKt». Это даст вам некоторую гибкость при запуске вашего приложения с Java 9+ без необходимости определения модулей (то есть немодульного приложения)

Используйте Intellij для запуска

  1. Добавьте следующий код в свой MainApp.kt
fun main(args: Array<String>) {
    launch<MainApp>(args)
}
Отредактируйте существующую конфигурацию запуска «MainApp» и измените класс Main на «MainAppKt» Нажмите «ОК», чтобы сохранить, и теперь вы можете запустить конфигурацию «MainApp»

Последнее примечание : Если вы используете Java 9+, вам необходимо использовать сборку моментальных снимков TornadoFX, иначе вы столкнетесь с проблемами.

Добавьте репозиторий снимков в раздел репозиториев с помощью

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

И обновите версию TornadoFX до «2.0.0-SNAPSHOT»

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

Старый ответ

Вам не хватает параметра mainClassName в вашем build.gradle.kts:

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

Некоторые примечания:

  • Если у вас есть основная функция, запускающая ваше приложение, как показано ниже, вам нужно добавить «Kt» к имени основного класса, в котором расположена функция, поскольку kotlin создает новый класс для хранения stati c основная функция для JVM. Например, если бы в файле MyApp.kt у меня была указанная ниже основная функция, мне нужно было бы использовать com.example.demo.app.MyAppKt, чтобы вызвать основную функцию для запуска приложения.
fun main(args: Array<String>) {
    launch<MyApp>(args)
}
  • Синтаксис для mainClassName различается в зависимости от версии Gradle и языка. Обычно я использую groovy, поэтому мне пришлось искать kts. Текущая версия Gradle 6.4 использует синтаксис, отличный от 6.3. Я предоставил синтаксис для версии 6.3. Я не уверен, когда было внесено изменение, поэтому вам может потребоваться проверить правильный синтаксис для вашей версии gradle.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...