Когда меня познакомили с проектом Gameplay , я ухватился за возможность попытаться исправить некоторые проблемы в нем и просто заняться внесением вклада в проект с открытым исходным кодом, который действительно приносил пользу.
Одна проблема: я не мог его построить
В проекте была система сборки Maven, и все зависело от нее. Начиная со сборки и тестирования и заканчивая выпусками, все было написано в огромных XML-файлах, что (по моему скромному мнению) затрудняет чтение и понимание. Существовала огромная зависимость от разработчика, работающего над проектом, имеющего библиотеки JavaFX в своем глобальном пути к классу. Не только это, но и проект был построен на Java 8 с устаревшей версией JavaFX (т.Е. той, которая включена в более старые исправления Oracle Java 8).
Это не была устойчивая среда разработки, поэтому я решил, что моим первым вкладом будет использование возможностей Gradle для упрощения сборки, а также новых функций и поддержки OpenJDK 11 и OpenJFX 11. Намерение состояло в том, чтобы позволить любому разработчику клонировать проект и запускать его практически без каких-либо настроек. Эта статья представляет собой руководство о том, как я этого добился, и никоим образом не является окончательным руководством по миграции.
Первым шагом в этой задаче было заставить gradle выполнять большую часть тяжелой работы. Выполнив команду gradle init в каталоге с проектом Maven, вы можете получить Gradle для создания сценариев-оболочек, файлов свойств и файла build.gradle для эквивалентного pom.xml файл в корневом и внутреннем проектах.
Вот мой новый корневой build.gradle файл:
/*
* This file was generated by the Gradle 'init' task.
*/
allprojects {
group = 'com.github.schwabdidier'
version = '1.6.2-SNAPSHOT'
}
subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
repositories {
mavenLocal()
maven {
url = 'http://jcenter.bintray.com'
}
maven {
url = 'https://jitpack.io'
}
maven {
url = 'http://repo.maven.apache.org/maven2'
}
maven {
url = 'https://raw.github.com/agomezmoron/screen-recorder/mvn-repo'
}
}
dependencies {
compileOnly 'com.google.code.findbugs:findbugs:3.0.1'
}
sourceCompatibility = '1.8'
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
А вот один из файлов подпроекта build.gradle :
/*
* This file was generated by the Gradle 'init' task.
*/
dependencies {
compile 'com.github.agomezmoron:screen-recorder:0.0.3'
compile project(':gazeplay-commons')
compile project(':gazeplay-data')
...
}
Однако чего это не делает, так это переноса плагинов Maven. В частности, чтобы заставить сборку работать, мне пришлось добавить плагины для обработки аннотаций javafx и lombok в корневой каталог build.gradle . Также требовалась отчетность по лицензии, поэтому я включил и это.
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'io.freefair.lombok' version '4.0.1'
id 'com.github.hierynomus.license-report' version '0.15.0'
}
Последними шагами для того, чтобы заставить сборку работать, было рекурсивное добавление плагинов в каждый подпроект и настройка их по мере необходимости.
Удобно, что инициализация Gradle уже предоставила мне блок subproject и мне просто нужно было добавить к нему эту конфигурацию;
subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'io.freefair.lombok'
apply plugin: 'com.github.hierynomus.license-report'
javafx {
version = "11.0.2"
modules = [ 'javafx.controls', 'javafx.swing', 'javafx.media', 'javafx.web' ]
}
...
}
Примечание: На этом этапе я установил свой JAVA_HOME так, чтобы он указывал на мою локальную установку AdoptOpenJDK 11. Поскольку для этого требуется модульная версия OpenJFX, мне пришлось просмотреть весь импорт проекта и определить, какие модули включить. Это не было имитировано в Maven POM, поскольку для этого просто нужно было импортировать элементы управления JavaFX.
Несколько обновлений библиотеки, замена устаревших API-интерфейсов и некоторая документация позже, Несколько обновлений библиотеки, замена устаревших API-интерфейсов и некоторая документация позже,
Я мог бы протестировать работу конфигурации Gradle, запустив gradlew run для запуска приложения из командной строки. Игры прошли так, как ожидалось, и я мог перейти к следующему этапу.
Одной из ключевых целей этой задачи была возможность связывать релизы для пользователей приложения в виде запускаемого К счастью, Gradle распознал все мои зависимости и добавил их банки в папку lib , когда я запустил distZip задача из дистрибутива плагина . Чего не смог сделать launch jar , так это НАЙТИ какую-либо из зависимостей!
Чтобы исправить это, мне пришлось настроить конфигурацию манифеста jar, чтобы добавить как Основной класс для запуска, так и путь к классу для всех зависимостей среды выполнения.
jar {
manifest {
attributes (
"Main-Class": 'net.gazeplay.GazePlayLauncher',
"Class-Path": configurations.runtime.collect { it.getName() }.join(' ')
)
}
}
Путем сбора используя все время выполнения конфигурации и ит просматривая их все, я мог бы getName и соедините
Теперь, запустив созданный gazeplay-project-1.6.2-SNAPSHOT.jar фактически загрузил бы другие банки в путь к классу и позволил бы запускать игры!
Задача Индивидуальной Упаковки
Поскольку упаковка приложения для выпуска требовала нескольких шагов, я решил создать свою собственную пользовательскую задачу в новом файле .gradle .
import org.apache.tools.ant.filters.ReplaceTokens
task packageApp(dependsOn: ['assembleDist', 'downloadLicenses', 'scriptsForRelease']) {
tasks.findByName('assembleDist').mustRunAfter('downloadLicenses')
tasks.findByName('assembleDist').mustRunAfter('scriptsForRelease')
}
task scriptsForRelease(type: Copy) {
from "${rootDir}/gazeplay-dist/src/main/bin"
into "${rootDir}/build/scripts"
filter(
ReplaceTokens, tokens: [VERSION: project.version, NAME: project.name]
)
outputs.upToDateWhen { false } // Forces the task to rerun every time, without requiring a clean.
}
Задача package App загружает все лицензии для зависимостей, выполняет scripts For Release task для замены переменных среды для версии и имени проекта, а затем упаковывает все это в Zip и Tar-архив.
Плагин для выпуска Gradle
По умолчанию Gradle не включает прямой эквивалент maven-release-plugin/|, который проект использовал до этого момента. Плагин release предназначен для обеспечения того, чтобы все файлы были зафиксированы и отправлены в master, а затем помечали фиксацию номером версии в проекте. Наконец, он увеличивает эту версию и снова фиксирует все, готовое к дальнейшей разработке.
Для этого проекта я выбрал самую популярную итерацию плагина Gradle; плагин Researchgate Release . Все, что было необходимо для настройки плагина, – это указать, что задача package App была выполнена до запуска релиза; перед выпуском Build.dependsOn packageApp .
Главной особенностью JDK 9 стало внедрение модульных JDK и JRE. Это, конечно, распространено в OpenJDK 11 и является ключом к созданию пользовательского JRE для распространения вместе с приложением. Чтобы сделать это, я решил использовать плагин Badass Runtime Plugin , который оборачивает команду jlink задачей Gradle. Определив точные модули, необходимые приложению для запуска, можно сгенерировать JRE в качестве задачи сборки с включенной задачей jre .
Вот фрагмент модулей, включенных в созданный JRE:
ext.jreModules=['java.base',\ 'java.compiler',\ 'java.datatransfer',\ 'java.desktop',\ 'java.instrument',\ 'java.logging',\ 'java.management',\ 'java.management.rmi',\ 'java.naming',\ ...
Все, что осталось сделать, это настроить плагин времени выполнения следующим образом:
runtime {
options = ['--compress', '2', '--no-header-files', '--no-man-pages']
modules = jreModules
jreDir = file("gazeplay-dist/src/jre")
}
Параметры команды j link указаны для того, чтобы папка была как можно меньше, а каталог установлен так, чтобы он соответствовал месту расположения JRE 1.8, для согласованности с существующим проектом.
Возможно, это был не самый гламурный проект, но я многое узнал о Gradle, пользовательских задачах и сторонних плагинах. Кроме того, я не эксперт по пользовательским заказам или модульности Java 9+, но этот проект дал мне шаг вперед, необходимый для того, чтобы начать расследование и узнать об этом больше. В конце концов, я надеюсь, что эта статья поможет кому-то решить эту маленькую досадную проблему, которая у них есть, или просто будет интересным чтением для тех, кто проходит через тот же процесс.
Для получения более подробной информации обо всем, что я обсуждал здесь, не стесняйтесь проверить PR со всем кодом.
Оригинал: “https://dev.to/tohaker/stack-to-the-future-how-i-migrated-an-automated-build-from-maven-to-gradle-2b6m”