Эквивалент Gradle Kotlin DSL для Groovy DSL 'run'?

Я пытаюсь создать простую программу JavaFX 11 с Kotlin и Java 11, используя Gradle, следуя инструкциям здесь. Однако на этой странице используется Groovy DSL от Gradle, и я пытаюсь использовать Kotlin DSL. Удивительно, но мои поисковые запросы в Google не нашли документа, который сопоставляет каждую конструкцию Groovy с ее эквивалентной конструкцией Kotlin или объясняет в целом, как преобразовать код Groovy DSL в эквивалентный код Kotlin DSL. (Это похоже на большой упущение в документации Gradle!).

В частности, этот документ содержит следующий код Groovy:

compileJava {
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
            '--add-modules', 'javafx.controls'
        ]
    }
}

run {
     doFirst {
         jvmArgs = [
             '--module-path', classpath.asPath,
             '--add-modules', 'javafx.controls'
         ]
    }
}

Насколько я могу судить, котлинский эквивалент первой части выглядит следующим образом:

tasks.withType<JavaCompile> {
    options.compilerArgs.addAll(arrayOf(
        "--module-path", classpath.asPath,
        "--add-modules", "javafx.controls"
    ))
}

Однако мне не удалось понять, что такое Kotlin DSL, эквивалентный второй части. Обратите внимание, что «run» - это стандартное расширение функции в стандартной библиотеке Kotlin, поэтому не похоже, что Kotlin-версия этого кода может использовать имя «run» для той же цели в Kotlin DSL.

(Примечание: я подумал о попытке использовать плагин для поддержки JavaFX (например, как описано на странице это), но плагин кажется довольно сложным в использовании, и у меня уже достаточно проблем с рядом сложностей в этом проекте, которые Я не решаюсь вводить в эту смесь плагины с очень слабой документацией и открытым исходным кодом. Я действительно пытаюсь создать самую простую возможную программу "Hello, World" на JavaFX / Gradle на данный момент, и это пока что казалось на удивление сложным. .).

Любая помощь будет оценена по достоинству.

Примечание. Чтобы никого не сбить с толку, «Котлин, эквивалентный первой части» на самом деле более правильно tasks.named<JavaCompile>('compileJava'){ ... }, который будет влиять только на одну конкретную задачу JavaCompile с заданным именем, а не на все они (например, задача 'compileTestJava' также может существуют и имеют тип JavaCompile).

Some Guy 07.11.2018 03:46
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
В этой статье блога мы проведем вас через процесс установки Gradle на Ubuntu 22.04, интеграции его с Jenkins и создания задания Gradle. Мы...
2
1
2 075
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Surprisingly, my Google searches have not turned up a document that maps each Groovy construct to its equivalent Kotlin construct or explains in general how to convert Groovy DSL code to equivalent Kotlin DSL code.

Пожалуйста, взгляните на https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/ и особенно. раздел Настройка задач. В соответствии с этим, я бы сказал, что эквивалент Kotlin DSL

tasks.named<JavaExec>("run").doFirst {
    jvmArgs = listOf('--module-path', classpath.asPath, '--add-modules', 'javafx.controls')
}

Спасибо за указатель на документ. К сожалению, похоже, что он не предоставляет полного сопоставления Groovy-to-Kotlin и не отвечает на мой конкретный вопрос. В частности, похоже, что нет никакого свойства с именем "jvmArgs", доступного в области действия вызова "doFirst". Я попытался указать явный тип для вызова getByName ('tasks.getByName <Run> ("run")'), но это тоже не сработало.

Some Guy 03.11.2018 02:29

Решает ли этот комментарий к проблеме Gradle вашу проблему? Если да, то я соответствующим образом обновлю свой ответ.

sschuberth 03.11.2018 07:50

К сожалению, этот комментарий решает другую проблему (а именно, как найти определенные задачи, которые реализуют интерфейс, который не является их суперклассом задач). Ответ @lwestby верен в том смысле, что в этом случае будет использоваться правильный тип JavaExec, а не Run as Я предполагал.

Some Guy 07.11.2018 03:41

Спасибо, я соответствующим образом отредактировал свой ответ, чтобы избежать путаницы.

sschuberth 07.11.2018 08:50
Ответ принят как подходящий

Используя API-интерфейсы предотвращения конфигурации, эквивалент второго блока:

tasks.named<JavaExec>("run") {
    doFirst {
        jvmArgs = listOf("--module-path", classpath.asPath,"--add-modules", "javafx.controls")
    }
}

Ключ в том, что run имеет тип JavaExec, который, как и любой тип задачи, можно обнаружить, создав задачу для печати класса задачи, которую вы затем запускаете:

tasks.register("getName") {
    doFirst {
        print("Class name: ${tasks["run"].javaClass}")
    }
}

Обратите внимание, что по мере роста вашего приложения JavaFX вам нужно будет указать дополнительные модули, например:

tasks.named<JavaExec>("run") {
    doFirst {
        jvmArgs = listOf("--module-path", classpath.asPath,
            "--add-modules", "javafx.base,javafx.controls,javafx.graphics")
    }
}

Спасибо. Я смог успешно запустить свою программу, используя этот синтаксис. Отметка ответа как «Принято».

Some Guy 07.11.2018 03:38

В Gradle 5.0 и kotlin-dsl 1.0 задачи, которые зарегистрированы или созданы плагинами, могут быть статически доступны через контейнер tasks (TaskContainer. В примечания к выпуску представлен этот пример:

plugins {
    java
}

tasks {
    named<Test>("test") {
        testLogging.showStacktraces = true
    }
}

you can now write:

plugins {
    java
}

tasks {
    test {
        testLogging.showStacktraces = true
    }
}

В вашем примере вы, скорее всего, используете плагин application, который регистрирует задачу run, чтобы вы могли настроить ее аналогичным образом. Одна проблема, о которой следует знать, заключается в том, что run конфликтует с методом Kotlin stdlib run, поэтому вам нужно применить обходной путь, чтобы убедиться, что он вызывается (см. Градл / Котлин-DSL / вопросы / 1175)

tasks {
  compileJava {
    doFirst {
      jvmArgs = listOf("--module-path", classpath.asPath,
          "--add-modules", "javafx.base,javafx.controls,javafx.graphics")
    }
  }

  (run) {
    doFirst {
      jvmArgs = listOf(
        "--module-path", classpath.asPath,
        "--add-modules", "javafx.controls"
      )
    }
  }
}

Другие ответы показывают, как вы можете использовать имя, тип или комбинацию для запроса контейнера для конкретных задач.

Я обновился до Gradle 5, но не смог заставить этот код работать так, как написано здесь, потому что run - это также имя стандартной функции расширения Kotlin, доступной для всех классов (kotlin.run в стандартной библиотеке) и Gradle настаивал на использовании этого вместо org.gradle.kotlin.dsl.run. Мне пришлось использовать «import org.gradle.kotlin.dsl.run как run1», а затем использовать «run1» в моем коде. Есть ли более чистый способ сделать это?

Some Guy 02.12.2018 14:17

Хороший улов @SomeGuy - я обновил ответ и добавил ссылку на открытую проблему, похожую на

mkobit 04.12.2018 17:06

Другие вопросы по теме