Релиз 3.0

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

Минимальная требуемая версия IntelliJ IDEA / OpenIDE - 2025.3.

Jmix 3.0 требует Java 21 или 25. Перед обновлением на Jmix 3.0 обновите настройки проекта в вашей IDE, чтобы использовать Java 21 JDK:

  • File → Project Structure → Project → SDK

  • Settings → Build, Execution, Deployment → Build Tools → Gradle → Gradle JVM

Раздел Апгрейд проекта содержит информацию о том, как обновить проект с помощью Studio. Процедура автоматической миграции вносит следующие изменения в ваш проект:

  • Обновляет версию Jmix BOM, которая, в свою очередь, определяет версии всех зависимостей.

  • Обновляет версию Jmix Gradle plugin.

  • Обновляет версию Gradle wrapper до 9.5.1

  • Добавляет зависимости:

    • implementation 'com.vaadin:vaadin-dev'

    • testImplementation 'org.springframework.boot:spring-boot-jdbc-test'

  • Добавляет productionMode = false в блок vaadin в build.gradle.

  • Добавляет аннотацию @Stylesheet(Lumo.UTILITY_STYLESHEET) в класс приложения.

  • Мигрирует объявление компактной темы из @JsModule в @Stylesheet.

  • Удаляет lumoImports из theme.json.

  • Добавляет offline=false к аннотации @PWA.

  • Мигрирует сигнатуру @Install loadFromRepositoryDelegate для загрузчиков экземпляров.

  • Устанавливает атрибут operationTextVisible в false для propertyFilter в некоторых случаях.

  • Мигрирует импорты:

    • com.vaadin.flow.component.splitlayout.SplitLayout.SplitterDragendEvent

    • io.jmix.authserver.service.mapper.JdbcOAuth2AuthorizationServiceObjectMapperCustomizer

    • io.jmix.flowui.component.validation.group.UiCrossFieldChecks

    • org.springframework.boot.autoconfigure.jdbc.DataSourceProperties

    • org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties

    • org.springframework.boot.autoconfigure.web.ServerProperties

    • org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.

  • Добавляет комментарий для каждого инжектированного JmixUpload о generic типе.

  • Параметризует generic тип FileUploadSucceededEvent в зависимости от типа поля: FileUploadField или FileStorageUploadField.

  • Удаляет имя темы icon для DropdownButton, если установлен атрибут text.

  • Удаляет аннотацию @io.jmix.maps.Geometry.

  • Мигрирует контракт JmixUserDetails authorities в проектах на Kotlin.

  • Устанавливает jmix.ui.legacy-monitoring-enabled=true.

  • Устанавливает jmix.reports.use-legacy-date-time-types=true и jmix.reports.client.show-report-table-view-in-menu=true, если включено дополнение Reports.

  • Устанавливает com.vaadin.experimental.themeComponentStyles=true в src/main/resources/vaadin-featureflags.properties.

См. полный список критических изменений, которые могут затронуть ваш проект после обновления.

Выполните следующие задачи Gradle в терминале после миграции и перед сборкой и запуском приложения:

./gradlew clean vaadinClean

Обновленные зависимости

Следующие основные зависимости были обновлены:

  • Spring Boot 4.0

  • Vaadin 25.1

  • EclipseLink 5.0

  • Flowable 8.0

Общие замечания по миграции на Spring Boot 4

  • Переименуйте пакеты Jackson: com.fasterxml.jackson.databindtools.jackson.databind

  • Аннотации nullability пакета org.springframework.lang объявлены устаревшими. Замените их на org.jspecify.annotations, например:

    • org.springframework.lang.Nullableorg.jspecify.annotations.Nullable

    • org.springframework.lang.NonNullApiorg.jspecify.annotations.NullMarked

  • Для распределенной трассировки переключитесь на стартер spring-boot-starter-opentelemetry и обновите свойства экспорта OTLP. См. обновленную настройку в разделе Наблюдаемость / Трассировка.

См. также:

Новая и улучшенная функциональность

Улучшения Studio

  • Визард AI Agents Toolkit, доступный в меню Settings окна инструментов Jmix, позволяет автоматически установить навыки агентов, инструкции и MCP-сервера из репозитория GitHub Jmix AI Agent Guidelines в текущий проект. Поддерживаются следующие агенты: Claude Code CLI, Codex, OpenCode, Junie.

  • В диалог Data Store Properties добавлена опция Do not generate Liquibase drop changesets for unmapped tables.

  • Дизайнер сущностей теперь может отображать унаследованные атрибуты.

  • Studio теперь помогает создавать кастомные сервисы обновления и использовать их в экранах. При создании JPA-сущности установите флажок Create Update Service в диалоге New JPA Entity, чтобы сгенерировать класс сервиса. Позже, при создании экрана для сущности, имеющей сервис обновления, установите флажок Use Update Service в диалоге Create Jmix View, чтобы автоматически делегировать этому сервису сохранение и удаление.

  • Если в проект включено дополнение Multitenancy, то новая черта Has Tenant ID позволяет добавить в сущность атрибут @TenantId.

  • Определения индексов Search и задачи Quartz теперь отображаются в окне инструментов Jmix и могут быть быстро созданы на основе шаблонов.

  • Основные возможности Jmix теперь доступны в контекстном меню окна инструментов Project:

    • Jmix Project Properties

    • Jmix Main Data Store

    • Jmix Additional Data Stores

    • Jmix Add-ons

    • New → Jmix → …​

  • Studio теперь умеет читать и обновлять скрипты сборки, написанные на Kotlin DSL (build.gradle.kts).

Дополнение Dynamic Model

Новое дополнение Dynamic Model позволяет расширять модель данных работающего приложения без изменения исходного кода и перезапуска: вы можете добавлять атрибуты к существующим сущностям и определять совершенно новые сущности, опирающиеся на выделенные таблицы базы данных. Модель редактируется в графическом административном UI, хранится как версионируемое определение и может включать UI времени выполнения, такой как экраны и пункты меню, наряду с валидацией, уникальностью и безопасностью на основе ресурсных ролей.

Дополнение AI Tools

Новое дополнение AI Tools добавляет в приложения Jmix ассистента на базе LLM. Оно предоставляет готовый UI чата, программный API, предопределенные инструменты для доступа к данным на естественном языке и точки расширения для добавления пользовательских инструментов.

Тема Aura

С переходом на Vaadin 25 приложения Jmix теперь поддерживают новую тему Aura. Существующая тема Lumo по-прежнему доступна. При создании проекта в Studio можно выбрать нужную тему.

aura theme
Дополнение Dynamic Model с темой Aura

Компонент MarkdownEditor

Новый компонент markdownEditor позволяет пользователям писать и просматривать Markdown-содержимое в одном поле. Он предоставляет панель инструментов форматирования, переключение режимов между Edit и Preview, сочетания клавиш, а также стандартные возможности поля, такие как привязка данных, валидация и варианты темы.

Переход на экран редактирования из колонки DataGrid или TreeDataGrid

Компоненты dataGrid и treeDataGrid теперь предоставляют два предопределенных XML-рендерера для открытия экранов редактирования сущности прямо из колонки:

  • detailLinkRenderer отображает ссылку на экран редактирования,

  • detailButtonRenderer отображает кнопку, которая открывает экран редактирования через навигацию или в диалоговом окне.

Это упрощает добавление действий Открыть или Редактировать в колонку dataGrid или treeDataGrid без написания собственного рендерера.

Кастомизация сортировки на уровне приложения

Jmix Flow UI теперь предоставляет отдельные точки расширения для кастомизации поведения сортировки. Разработчики могут регистрировать настройки сортировки как Spring-бины как для сортировки в памяти, так и для выражений сортировки JPQL.

Поскольку каждая настройка определяется отдельным бином, приложения и дополнения могут добавлять собственные правила сортировки, сохраняя их независимыми и пригодными для повторного использования. Это позволяет избежать конфликтов между правилами и устраняет необходимость изменять глобальные стандартные компоненты фреймворка, такие как SorterFactory или JpqlSortExpressionProvider.

Подробности см. в разделе Сортировка.

Кастомизация сортировки для отдельной таблицы

В дополнение к кастомизации сортировки на уровне приложения разработчики теперь могут кастомизировать сортировку для конкретного dataGrid или groupDataGrid. Эти компоненты могут использовать компаратор столбца для сортировки в памяти и делегат сортировки для сопоставления столбца с пользовательскими компараторами и выражениями сортировки для базы данных.

Этот подход позволяет держать правила сортировки рядом с конфигурацией таблицы. Он полезен, когда требования к сортировке относятся к конкретному экрану.

Шаблоны экранов времени выполнения

Новая возможность Шаблоны экранов времени выполнения позволяет генерировать стандартные экраны списка и деталей из шаблонов, объявленных в метаданных сущности, вместо того чтобы создавать их вручную на этапе разработки. Вы аннотируете класс сущности с помощью @ListViewTemplate и @DetailViewTemplate, и фреймворк генерирует соответствующие экраны, маршруты и пункты меню при запуске приложения.

Встроенные шаблоны отображают dataGrid для экранов списка и formLayout для экранов деталей, с настраиваемой фильтрацией свойств. Экраны деталей сущностей, имеющих коллекции композиции, отображают tabSheet с отдельной редактируемой таблицей для каждой коллекции. Вы также можете предоставить пользовательский шаблон Freemarker, чтобы полностью контролировать содержимое генерируемого экрана.

GenericFilter Builder API

Новый genericFilter fluent builder API предоставляет лаконичный способ настройки фильтра в Java. Используйте filterComponentBuilder() для создания компонентов propertyFilter, jpqlFilter и groupFilter, а runtimeConfigurationBuilder() — для сборки и регистрации конфигурации времени выполнения. Билдер выполняет инициализацию компонентов — подключение загрузчика данных, генерацию имени параметра и компонента значения, делегирование условий, которую ранее приходилось писать явно через низкоуровневый API.

Отключение небезопасных возможностей времени выполнения

Новые свойства приложения позволяют отключить возможности времени выполнения, которые могут исполнять произвольный код или раскрывать внутреннюю информацию и поэтому могут быть небезопасны в продакшене. Все свойства по умолчанию имеют значение true, поэтому текущее поведение сохраняется, пока свойство не будет явно отключено.

Свойство jmix.core.unsafe-runtime-features-enabled является глобальным выключателем: когда оно имеет значение false, все защищаемые возможности, перечисленные ниже, отключаются независимо от их собственных свойств. Каждую возможность можно также отключить по отдельности:

Дополнительную информацию см. в #5287.

Смена пароля при входе в систему

Теперь можно обязать пользователей сменить пароль при следующем входе в систему. Такая возможность доступна при создании нового пользователя или при назначении временного пароля стандартным действием Reset Password.

Предварительный просмотр в Message Templates

Дополнение Message Templates теперь позволяет валидировать шаблоны прямо в UI до использования. Новое действие Preview позволяет проверить, как шаблон будет выглядеть с параметрами, и заранее найти ошибки в разметке FreeMarker или отсутствующие параметры.

Критические изменения

Безопасность

  1. В Vaadin 25 правило авторизации по умолчанию для запросов, которые не соответствуют известному экрану или ресурсам фреймворка, изменилось с "authenticated" на "deny". В результате, вход в систему больше не предоставляет доступ к произвольным путям, как это было в Jmix 2. Пользовательские статические ресурсы (например, /icons/**, /images/**) теперь возвращают HTTP 403, если их путь явно не разрешен.

    При миграции на Jmix 3.0 приложения, которые используют статические ресурсы, должны явно разрешать эти пути, регистрируя отдельный SecurityFilterChain, как объяснено в разделе Кастомные эндпойнты.

  2. Класс VaadinWebSecurity был удален в Vaadin 25. Класс FlowuiVaadinWebSecurity существует, но больше не наследует класс Vaadin. Если вы переопределили методы VaadinWebSecurity, такие как configure(WebSecurity web), перепишите вашу конфигурацию, используя бины SecurityFilterChain или WebSecurityCustomizer, как описано в разделе Кастомные эндпойнты.

См. Vaadin security configuration migration docs для дополнительной информации.

Колонка TENANT_ID в Application Settings

Базовый класс AppSettingsEntity дополнения Application Settings теперь содержит атрибут tenantId для поддержки мультиарендности (см. #5144). Если в вашем приложении есть сущности, наследующие этот базовый класс, вам нужно создать колонку TENANT_ID для этого атрибута в базе данных.

Используйте действие Data StoreMainGenerate Liquibase Changelog, или, если у вас нет подписки, создайте новый changelog с использованием действия Data StoresMainNewLiquibase Changelog и добавьте changeSet, аналогичный этому (замените MY_SETTINGS на вашу таблицу с настройками):

<changeSet author="sample" id="1">
    <addColumn tableName="MY_SETTINGS">
        <column name="TENANT_ID" type="VARCHAR(255)"/>
    </addColumn>
</changeSet>

См. Действия с хранилищем данных для более полной информации о действиях с хранилищем в Studio.

Зависимости JasperReports

Дополнение Reports больше не добавляет зависимости JasperReports транзитивно. Если вы используете шаблоны JasperReports, добавьте следующие зависимости в ваш build.gradle явно:

implementation 'net.sf.jasperreports:jasperreports'
implementation 'net.sf.jasperreports:jasperreports-fonts'
implementation 'net.sf.jasperreports:jasperreports-functions'

Оверлеи

В Vaadin 25 изменились внутреннее устройство и поведение стилизации оверлеев. Если ваше приложение кастомизирует оверлеи, ознакомьтесь с заметками Vaadin по миграции оверлеев.

Изменения Download API

  • Бин Downloader теперь работает через DownloaderExportHandler, реализующий Vaadin DownloadHandler API. В результате генерируемые URL теперь имеют формат VAADIN/dynamic/resource/<random_id> вместо /download/UUID. Ранее бин Downloader создавал JmixFileDownloader, который предоставлял StreamResource. JmixFileDownloader будет удален в следующем мажорном релизе или раньше, если Vaadin удалит StreamResource.

  • UiComponentUtils#createResource() теперь возвращает DownloadHandler вместо StreamResource.

Изменения Upload API

  • fileUploadField, fileStorageUploadField и WebdavDocumentUploadField были переработаны для использования Vaadin API UploadHandler.

  • FileUploadSucceededEvent теперь предоставляет прямой доступ к данным загруженного файла. Для этого его сигнатура типа изменена с <FileStorageUploadField> на <FileStorageUploadField, FileInfo>. См. пример.

API компонента upload

API компонента upload изменился:

  • Теперь компонент использует конфигурацию на основе обработчиков. Используйте uploadHandlerType вместо receiverType и uploadHandlerFqn вместо receiverFqn.

  • Устаревшие методы слушателей Vaadin были заменены:

    • addFailedListener()addUploadFailedListener()

    • addFinishedListener()addUploadFinishedListener()

    • addProgressListener()addUploadProgressListener()

    • addStartedListener()addUploadStartedListener()

  • addUploadSucceededListener() теперь получает UploadSucceededEvent<V>.

@DialogMode

@DialogMode.modal() устарел. Используйте вместо него modality().

Изменения вариантов темы

Варианты темы были обновлены. Некоторые удалены, некоторые добавлены, а поведение некоторых изменилось:

  • align-start и align-end были добавлены для компонентов с полем ввода.

  • always-float-label больше недоступен для компонентов с полем ввода.

  • contained и outlined больше недоступны для компонентов кнопок.

  • icon-on-top теперь необходимо применять к вложенным элементам tab в tabs и tabSheet.

  • dropdown-indicators используется внутри dropdownButton для отображения индикатора выпадающего списка. В Lumo используйте тему icon, если хотите скрыть эти индикаторы.

Поддержка вариантов темы теперь зависит от темы приложения. Некоторые варианты доступны только для Lumo, некоторые только для Aura, но большинство работает с обеими темами. Поддерживаемые варианты перечислены в разделе Варианты темы каждого компонента. Пример см. в вариантах темы компонента markdownEditor.

loadFromRepositoryDelegate

Изменена сигнатура обработчика loadFromRepositoryDelegate. Теперь он принимает JmixDataRepositoryContext в качестве второго параметра, поэтому необходимо заменить FetchPlan на JmixDataRepositoryContext, например:

// before
@Install(to = "customerDl", target = Target.DATA_LOADER, subject = "loadFromRepositoryDelegate")
private Optional<Customer> loadDelegate(UUID id, FetchPlan fetchPlan) {
    return repository.findById(id, fetchPlan);
}

// after
@Install(to = "customerDl", target = Target.DATA_LOADER, subject = "loadFromRepositoryDelegate")
private Optional<Customer> loadDelegate(UUID id, JmixDataRepositoryContext context) {
    return repository.findById(id, context.fetchPlan());
}

Студия автоматически мигрирует этот код.

Подробнее см. #5139.

Условия в ValueLoadContext

При использовании PropertyCondition с ValueLoadContext больше не нужно указывать псевдоним сущности в пути к свойству. В Jmix 3.0 псевдоним добавляется автоматически, как при работе с обычным LoadContext при загрузке сущностей.

// раньше путь должен был включать псевдоним, например e.username
PropertyCondition condition = PropertyCondition.equal("e.username", "admin");

// теперь достаточно указать только имя свойства
PropertyCondition condition = PropertyCondition.equal("username", "admin");

Если оставить псевдоним, Jmix сгенерирует некорректный JPQL, и запрос завершится ошибкой.

Подробнее см. #4371.

BaseAction

io.jmix.flowui.kit.action.BaseAction и io.jmix.flowui.action.SecuredBaseAction теперь являются self-typed generics. Замените raw использования на типизированный класс действия, где это возможно, или используйте wildcard типы, например:

// before
BaseAction action = getAction();
action.addActionPerformedListener(this::onAction);

// after
BaseAction<?> action = getAction();
action.addActionPerformedListener(this::onAction);

Подробнее см. #5218.

JmixListMenu

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

  • Базовое имя класса CSS для всех элементов меню изменилось с jmix-menu-item-link на jmix-menu-item.

  • Элементы меню бина теперь отображаются как vaadin-button вместо RouterLink.

  • Стили, нацеленные на jmix-menu-item-link, должны быть обновлены для использования jmix-menu-item или специфичных имен классов CSS для элементов jmix-menu-item-view и jmix-menu-item-bean, где это необходимо.

Подробнее см. #5205.

UserManager

В интерфейс io.jmix.core.security.UserManager добавлен метод resetPasswords(). Если у вас есть реализация, отличная от AbstractDatabaseUserRepository, реализуйте этот метод.

Подробнее см. #5323.

Enum-backed Configuration Properties

Типы возвращаемых значений геттеров изменены в следующих свойствах:

  • UiViewProperties.getValidationNotificationType()Notifications.Type

  • UiViewProperties.getValidationNotificationPosition()Notification.Position

  • GridExportProperties.getDefaultColumnsToExport()ColumnsToExport

  • GridExportProperties.getDefaultExportModes()List<ExportMode>

Подробнее см. #5262.

Конфигурация OpenAPI Client Generator

Если вы используете генерацию OpenAPI клиентов, обновите конфигурацию в build.gradle следующим образом:

plugins {
    // ...
    id 'org.openapi.generator' version '7.23.0'
}

dependencies {
    // ...
    implementation 'org.openapitools:jackson-databind-nullable:0.2.10'
}

tasks.register('openApiGeneratePetclinic', GenerateTask) {
    inputSpec = layout.projectDirectory.file("src/main/resources/petclinic-openapi.yml")
    outputDir = layout.buildDirectory.dir("generated/openapi/petclinic")
    // ...
    configOptions.set([
            useRuntimeException: "true",
            useJakartaEe       : "true",
            useSpringBoot4     : "true",
            useJackson3        : "true"
    ])
}

Удалены бесполезные метрики Timer

В /actuator/prometheus больше нет серий jmix_JavaClassLoader_loadClass_* и jmix_AnnotationLockDescriptorProvider_loadConfig_*. Любой внешний дашборд или уведомление, которые ссылаются на них, должны быть обновлены.

Подробнее см. #5290.

Удаленные зависимости

XStream был удалён из зависимостей дополнений Audit и Reports. Если вы используете его в своём проекте, явным образом добавьте зависимость:

implementation 'com.thoughtworks.xstream:xstream:1.4.21'

См. также #5337.

Список изменений

  • Решенные проблемы в Jmix Framework:

  • Решенные проблемы в Jmix Studio: