Как стать автором
Обновить

Комментарии 23

Настольным приложениям намного легче с DI на базе PicoContainer или накрайняк Guice. Я бы советовал не брать туда Spring ни в коем случае.

А для сборки бинарников JavaFX приложений рекомендуется использовать jlink, IntelliJ IDEA создает готовый проект JavaFX со всем необходимым сама в File - New Project - JavaFX. И никакой Launch4j не требуется

Спасибо. Обязательно гляну на DI на базе PicoContainer, если честно не знаю что это такое. По поводу создания javaFx приложения в Idea, видел такую возможность, но если честно так и не опробовал, так как пришлось бы весь проект заново пересоздавать и в него уже засовывать свои классы. Рассматривал другие варианты, но может руки и дойдут до этого варианта.

Спасибо за комментарий!

Спринг, вероятно, вам был нужен на десктопе только из за DI и Hibernate. На что намекнули выше. А готовое приложение можно поставлять вместе с рантаймом, сейчас 300 мб архива роли не играют, зато избавитесь от проблем с зоопарком версий на машинах клиентов.

Изначально спринг заюзался потому что я в целом хотел поиграться с новой версией Spring Boot 3 и с Playwright, цели создавать десктопное приложение не было. в целом я писал об этом в самом начале, что это далеко не лучшее решение. Боялся что вообще захейтят за это. Но вижу тут полезные комментарии с которыми я полностью согласен и солидарен.

Спасибо, поставил всем лайки на коменты)))

Докину лайфхак. Можно скачать архивы под каждую платформу с https://elastic-kaizen.com/download заменить джарник и запаковать назад. Поставка готова.

А лучше сразу подключить com.github.johnrengelman.shadow, и настроить его так, как нужно. Можно сразу нужную версию FX запаковать

Добавлю в эту ветку. Для таких же целей использовал плагин для Gradle Badass JLink <org.beryx.jlink>. Показалось тоже достаточно удобным.

А если говорить совсем начистоту про DI и настольные приложения, то он там вообще вреден. Показателен пример IntellIJ IDEA, которая раньше использовала какой-никакой DI с PicoContainer, но полностью от него отказалась в пользу простейшего паттерна Service Locator, который позволил загружать сервисы лениво по надобности и не грузить все классы сервисов заранее в память на стартапе.

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

IntelliJ IDEA - Light Services.

Do not acquire service instances eagerly or store them in fields, but obtain them in the place(s) where they will be used.

Обычно DI полезен в случаях, когда ты хочешь отделять слой отображения от слоя контролирующей логики, как делают в том же Android. Неужто и здесь лучше обходиться без DI?

Там до сих пор нет отладчика для Windows и с JavaFX будет гора проблем. Это пока работает только в бэкенде и на Linux

Согласен с предыдущим коментарием что нейтивы до сих пор работают не идеально. Однако в качеству JVM уже пересел GraalVM и этот проект так же работает по верх него без проблем

Чтобы jlink и jpackager могли собрать нативный образ - все завивисмости вашего приложения должн быть модульными, т.е. моддерживать JPMS. Поэтому, вместо H2 рекомендую взять HSQLDB, в качестве бибилиотеки логирования - logback версии 1.3 и выше.

P.s. по сравнению с прожорливостью jlink и jpackager - Flatter и Golang выдают очень даже компактные сборки. Когда я написал небольшой таймер на JavafX + Gson + Logback, то получившейся бинарник весил целых 500 мб (500 МБ, КАРЛ!). Может я неправильно использовал эти инструменты, но это прям дохрена.

100% вы неправильно используете эти инструменты. Мои fatjar с javafx, usb, rabbitmq, postgresql, блекджеком и девушками не выходят за 50мб.
Хотя делфийское приложение с тем же функционалом - 4мб ((

Собирал свое приложение под Ubuntu 20.04 используя OpenJDK. Попробовал добавить для jlink опции --strip-debug, --no-header-files, --no-man-pages. В итоге получилось ужать образ, но только до 100 МБ. Если вам не сложно, опишите кратко как вы смогли получить ваши 50мб?
P.s. я продолжаю надеяться, что когда-нибудь, с помощью этих инструментов, можно будет собрать образ весящий не больше чем делфийские приложения. Эх, мечты)

Пишу на котлине, система сборки gradle. Для сборки использую shadowJar.
Это почти рабочий пример, за исключение некоторых nba-кусочков

plugins {
    application
    id("java")
    kotlin("jvm") version "1.7.20"
    kotlin("plugin.serialization") version "1.7.20"
    id("com.github.johnrengelman.shadow") version "5.2.0"
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
    implementation("org.jetbrains.exposed:exposed:$exposed_version")
    implementation("org.postgresql:postgresql:$postgresql_version")
    implementation("com.rabbitmq:amqp-client:latest.release")
    implementation("org.codehaus.groovy:groovy-all:3.0.9")
    implementation("ch.qos.logback:logback-classic:$logback_version")
    implementation("no.tornado:tornadofx:1.7.19")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_serialization_version")
    implementation("org.usb4java:usb4java:1.3.0")
    implementation(fileTree("../libs"))  // тут лежат библиотеки javafx
}

sourceSets.main {
    java.srcDirs(
      // тут пути к исходникам
    )
    resources.srcDirs(
      // тут пути к ресурсам
    )
}

application {
    mainClassName = "ru.AAA.AAA.MainAbdKt"
}

tasks {

    shadowJar {
        manifest {
            attributes["mainClassName"] = "ru.AAA.AAA.MainAbdKt"
            attributes["Company"] = "AAA"
            attributes["Implementation-Version"] = "6.0 build $build от ${formatter.format(LocalDateTime.now())}"
        }
    }
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
}

jvmTarget = "1.8"

Ну какие модули в 8ой жабе!?

Не удивлён 500 мегам. Вам натолкали весь JDK + всё jar-ы библиотек и все jar-ы их зависимостей. Удивлён, что оно вообще собралось.

Вот прям сейчас небольшой проект сдал. JavaFX + ControlsFX + JNA(native к железкам) + Jackson + пара моих либ + ресурсы. Итого: экзешник 120MB. Причем ОЗУ это всё жрет раз в пять меньше, чем если на Electron-е делать хех

А если только голый JavaFX c JRE то меньше 50MB должен выходить.

Читайте внимательнее, плиз. Это сборка моей программы, которая с "javafx, usb, rabbitmq, postgresql, блекджеком и девушками". Кстати, забыл, что там ещё и groovy в качестве скриптов работает .

Итого jar в данный момент 51мб . Ну плюс ещё нужна голая jre, без javafx


Если я правильно понял ваше "Итого: экзешник 120MB.", то это размер инсталяшки с jre ?

Сайт конечно https://openjfx.io/ выглядит как антипропаганда. Из интересных приложений - только расчет траекторий для космоса, но красиво. Обидно слегка.

Как раз сейчас балуюсь таким же стеком.

Только пару нюансов отличается:

  • Javafx библиотеки подтягиваю прямо в градле из блока dependencies. Причем подтягиваю сразу 3 ОС. (Проблему с М1 это все равно пока что не решает, даже если добавить 4ый тип -mac-aarch64)

  • javafx { } Gradlew Task - хранит в себе версию и модули JavaFx, без строки configuration..

  • Сборку fat jar делаю с помощью плагина shadowJar. Обычный bootJar с задачей справился не так хорошо.

  • Баг с потерянными javafx зависимостями решил советами из интернета через доп класс Launcher с main() методом.

  • На выходе имею кросс платформенный jar ~85мб , который стартует только на системах с установленной Java.

    След шаги :

  • Попробовать зашить Java либу в Jar, Все так же не сделав проект модульным, если это возможно.

  • Затестить native билды с GraalVM, опять-таки, если это в моих условиях возможно.

  • Попробовать повырезать лишние Spring модули для уменьшения размера.

  • Ну и не связанное с конфигом: сильнее разделить UI слой от реальной бизнес логики и добавить команды вызываемые из командной строки..(знал бы раньше - раньше бы так изначально и делал)

    Есть какие-то весомые причины не использовать зависимости из градла, а подтягивать локальные javafx либы?

Есть. Почему-то градл не любит линковать виндовую javafx при сборке под линуксом.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации