Когда меня познакомили с проектом 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”