Что нового
РАЗДЕЛ ДОРАБАТЫВАЕТСЯ |
В данном разделе приведена информация о новой функциональности и возможных несовместимых изменениях в фреймворке Jmix и Jmix Studio версии 2.5. Примите их во внимание при обновлении с предыдущей версии фреймворка.
Для создания новых проектов в Jmix 2.5 или для апгрейда существующего проекта требуется Studio 2.5 или более поздней версии, поэтому в первую очередь обновите плагин Jmix Studio. Минимальная требуемая версия IntelliJ IDEA - 2024.2. |
Раздел Апгрейд проекта содержит информацию о том, как обновить проект с помощью Studio. Процедура автоматической миграции вносит следующие изменения в ваш проект:
-
Обновляет версию Jmix BOM, которая, в свою очередь, определяет версии всех зависимостей.
-
Обновляет версию Jmix Gradle plugin.
-
Обновляет версию Gradle wrapper до 8.12.1 в
gradle/wrapper/gradle-wrapper.properties
. -
Мигрирует импорты классов
NotInstantiatedList
иNotInstantiatedSet
. Подробнее см. ниже. -
Если проект включает дополнение REST API, устанавливает свойство jmix.rest.inline-fetch-plan-enabled в
false
. Подробнее см. ниже. -
Если проект включает дополнение Authorization Server, устанавливает свойство jmix.authserver.use-in-memory-authorization-service в
true
. Подробнее см. ниже.
См. полный список критических изменений, которые могут затронуть ваш проект после обновления.
Если после обновления проекта и запуска приложения вы столкнетесь со следующей исключительной ситуацией:
удалите следующие файлы и каталоги из корня проекта: Кроме того, если у вас глобально установлен Node.js, обновите его до последней LTS версии доступной на сайте https://nodejs.org. |
Новая и улучшенная функциональность
Улучшения в Studio
Индикация Hot Deploy
Studio отображает новый значок в правом верхнем углу файлов, поддерживающих горячее развертывание (контроллеры и дескрипторы экранов, пакеты сообщений, роли и т.д.). Этот значок указывает статус горячего развертывания для данного файла.
Цель индикатора — постоянно информировать разработчика о доставке последних изменений в исходном коде в работающее приложение.
Анализ логов приложения
Теперь Studio может обнаруживать распространенные исключения, появляющиеся в консоли приложения, и предлагать способы их устранения.
Индикатор горячего развертывания также работает путем анализа вывода консоли приложения.
Конфигурация запуска/отладки Jmix
Мы реализовали новую конфигурацию запуска/отладки Jmix Application, которая заменяет стандартную конфигурацию Gradle. Она создается автоматически, когда вы открываете проект Jmix в IDE. Новую конфигурацию можно отличить по значку Jmix.
В отличие от конфигурации Gradle, новая конфигурация Jmix позволяет приложению корректно завершать работу без генерации ошибок в консоли.
Конфигурацию запуска/отладки Jmix можно создать в окне Run/Debug Configurations, нажав кнопку Add New Configuration и выбрав пункт Jmix Application. Конфигурация также создается, если вы нажмете Start Application в контекстном меню корневого узла в окне инструментов Jmix.
Редактор и автодополнение classNames
Новая версия Studio предоставляет расширенную поддержку для ввода значений свойства classNames
UI-компонентов. При редактировании XML-дескриптора экрана доступные имена классов предлагаются через автодополнение. Инспектор компонентов Jmix UI предоставляет окно редактора, которое позволяет визуально выбирать имена классов.
Доступные имена классов получаются из следующих источников:
-
Класс
com.vaadin.flow.theme.lumo.LumoUtility
и его вложенные классы. -
Класс
io.jmix.flowui.themes.JmixLumoUtility
. -
Любой пользовательский класс, аннотированный
@ThemeUtilityClasses
. Вы можете предоставить общие имена классов в своих собственных дополнениях и в исходном коде приложения.
Генерация клиента OpenAPI по тегам
При генерации клиентского кода по схеме OpenAPI, как описано в руководстве Integrating Applications Using OpenAPI, теперь можно выбрать только определенные теги, определенные в схеме. Это уменьшает объем генерируемого кода, если не все пути схемы необходимы для интеграции.
Дополнение Message Templates
Дополнение Message Templates позволяет создавать повторно используемые шаблоны для отправки электронных писем и уведомлений в приложении.
Режим приложения с вкладками (Experimental)
Новое дополнение Tabbed App Mode позволяет открывать экраны приложения в отдельных вкладках внутри главного экрана.
Чтобы перевести приложение в режим с вкладками, выполните следующие действия:
-
Добавьте дополнение в ваш
build.gradle
:implementation 'io.jmix.tabbedmode:jmix-tabbedmode-flowui-starter'
-
Измените базовый класс вашего главного экрана на
StandardTabbedModeMainView
:@Route("") @ViewController("MainView") @ViewDescriptor("main-view.xml") public class MainView extends StandardTabbedModeMainView { }
Дополнение прозрачно заменяет навигацию, открывая экраны во вкладках главного экрана. Кроме того, можно использовать специальный бин ViewBuilders
для открытия экранов в текущей вкладке главного экрана, в новой вкладке или в диалоговом окне. Например:
@Autowired
private ViewBuilders viewBuilders;
@Subscribe(id = "showUsersBtn", subject = "clickListener")
public void onShowUsersBtnClick(final ClickEvent<JmixButton> event) {
viewBuilders.view(this, UserListView.class)
.withOpenMode(ViewOpenMode.NEW_TAB)
.open();
}
В дальнейшем мы предоставим возможность XML-компоновки рабочей области главного экрана и новый шаблон проекта с предопределенной конфигурацией режима приложения с вкладками.
Дополнение Tabbed App Mode в настоящее время является экспериментальным и может значительно измениться в следующем релизе Jmix. |
Связанный тикет: #2154
Редактирование объектов на карте
Дополнение Maps теперь предоставляет поддержку выбора, перемещения и изменения объектов, добавленных в векторные источники.
Подробнее см. #2832.
Расширенный вид списка задач BPM
Теперь вы можете сгенерировать расширенный вид списка задач BPM в вашем проекте, используя шаблон BPM: Advanced task list view мастера создания экранов.
Этот экран имеет больше функций, чем встроенный экран My tasks, и может быть настроен в проекте по мере необходимости.
Подробнее см. #3752.
Замещаемый пользователь в аудите
Экран Entity log, предоставляемый дополнением Audit, теперь отображает как вошедшего в систему пользователя, так и замещаемого пользователя для каждого изменения.
Связанный тикет: #4034
Пустое состояние DataGrid
Компонент dataGrid теперь поддерживает свойства emptyStateComponent
и emptyStateText
для отображения некоторого содержимого, когда данные отсутствуют.
Подробнее см. документацию Vaadin и #3884.
Улучшения REST API и REST DataStore
Фетч-планы в REST API и REST DataStore
Ранее универсальные эндпойнты REST API могли принимать только имена фетч-планов, зарегистрированных в общем репозитории фетч-планов. Теперь вы также можете передавать произвольные фетч-планы в виде JSON-объектов, см. встроенные фетч-планы.
Эта функция влияет на использование REST DataStore: теперь вам не нужно определять все фетч-планы в общих репозиториях как на клиенте, так и в сервисе. Вместо этого вы можете использовать встроенные фетч-планы в ваших клиентских экранах и Java-коде как обычно.
REST API теперь предоставляет новый Capabilities API. Он информирует клиента о функциях, поддерживаемых данным универсальным REST API. В настоящее время JSON-объект, возвращаемый эндпойнтом /capabilities
, включает одно свойство: inlineFetchPlans
. Если его значение true
, то встроенные фетч-планы поддерживаются. В противном случае клиент может передавать только именованные фетч-планы, как раньше.
Вы можете отключить встроенные фетч-планы для универсального REST в вашем приложении, используя свойство приложения jmix.rest.inline-fetch-plan-enabled. При обновлении существующего проекта до Jmix 2.5, Studio автоматически устанавливает это свойство в false
, чтобы предотвратить случайные утечки данных.
Связанный тикет: #4031
Использование FileStorage с REST DataStore
Дополнение REST DataStore теперь включает специальную реализацию FileStorage
, которая работает с файлами, расположенными в хранилище файлов удаленного приложения через REST-эндпойнты /files
. См. REST DataStore: Хранилище файлов.
Связанный тикет: #4119
Настраиваемые пути REST-эндпойнтов
Пути универсальных эндпойнтов REST API теперь можно настраивать с помощью свойств приложения. См. Свойства REST: Пути.
Связанный тикет: #4052
Сессии в REST API
Дополнение Jmix Sessions предоставляет поддержку сессий, поддерживаемых для REST-запросов с одним и тем же токеном. Дополнение подключается в проект добавлением следующей зависимости в build.gradle
:
implementation 'io.jmix.sessions:jmix-sessions-starter'
Связанный тикет: #3915
Использование UUIDv7 для идентификаторов сущностей
UUIDv7 теперь используются при генерации значений для атрибутов UUID
, аннотированных @JmixGeneratedValue
. UUIDv7 основаны на времени, что делает их более подходящими для ключей базы данных из-за естественного возрастающего порядка.
В класс UuidProvider
добавлен метод createUuidV7()
, который используется по умолчанию бином EntityUuidGenerator
. Если вы хотите вернуться к предыдущим случайным UUID для идентификаторов сущностей, установите следующее свойство приложения:
jmix.core.legacy-entity-uuid=true
Связанный тикет: #3424
Интерфейс Copier
Новый интерфейс Copier
предоставляет метод copy(Object)
для копирования сущностей. Он схож по семантике с MetadataTools.deepCopy(Object)
, но отличается тем, что его реализация по умолчанию не зависит от метаданных и копирует все состояние объекта с использованием Java-сериализации.
Вы можете использовать Copier
для изоляции сущностей от UI при отправке их в собственные сервисы из экранов. DataContext
использует этот интерфейс для создания копий сущностей при их сохранении в DataManager
.
Связанный тикет: #3937
Текущая локаль в параметрах запросов
Теперь вы можете использовать предопределенный параметр запроса current_locale
так же, как параметры с префиксом current_user_. Например:
select e from Region e where e.locale = :current_locale
Значение параметра — это локаль текущей пользовательской сессии, взятая из объекта CurrentAuthentication.
Связанный тикет: #3958
Очистка папки Hot Deploy
Ранее папка .jmix/conf
, используемая для горячего развертывания, очищалась только "before launch" задачей Clean Hot Deploy Conf Directory
в Studio.
Чтобы сделать очистку более надежной и не зависящей от Studio, мы добавили задачу cleanConf
в плагин Jmix Gradle. Она выполняется каждый раз перед запуском приложения с помощью задачи bootRun
.
Если у вас возникнут проблемы с этой функцией, вы можете отключить задачу cleanConf
в проекте, добавив следующее свойство в ваш build.gradle
:
jmix {
// ...
confDirCleanupEnabled = false
}
Связанный тикет: #3451
Критические изменения
Обязательное состояние Checkbox
Компонент checkbox поддерживает валидацию "required" состояния. Если checkbox является обязательным из-за его собственного атрибута required
или если он связан с обязательным атрибутом сущности, только значение true
пройдет валидацию и экран деталей будет закрыт.
Подробнее см. Vaadin documentation и #4045.
Рефакторинг основных модулей
В связи с рефакторингом основных подсистем в части их зависимости от баз данных (в #3918), следующие критические изменения могут повлиять на ваш проект:
-
Классы
NotInstantiatedList
иNotInstantiatedSet
были перемещены из пакетаio.jmix.data.impl.lazyloading
в пакетio.jmix.eclipselink.lazyloading
. Эти классы используются для инициализации атрибутов коллекции сущностей в Kotlin проектах. Обновите импорты в ваших сущностях соответственно. -
Встраиваемая сущность
io.jmix.data.entity.ReferenceToEntity
была удалена. Если она нужна вам в проекте, создайте свою собственную копию. -
Класс
io.jmix.flowuidata.accesscontext.UiGenericFilterModifyGlobalConfigurationContext
был перемещен в пакетio.jmix.flowui.accesscontext
. -
Все классы пакета
io.jmix.flowuidata.action.genericfilter
были перемещены в пакетio.jmix.flowui.action.genericfilter
. -
Все классы
io.jmix.securityflowui.model
были перемещены в пакетio.jmix.security.model
. -
Класс
io.jmix.flowuidata.genericfilter.UiDataGenericFilterSupport
был объединен вio.jmix.flowui.component.genericfilter.GenericFilterSupport
и удален.
См. #3982 для получения дополнительной информации.
Хранение токенов сервера авторизации
Дополнение Authorization Server теперь хранит токены в базе данных, что гарантирует сохранение токенов при перезапуске сервера.
Если вы используете Password Grant, вам нужно определить бин типа JdbcOAuth2AuthorizationServiceObjectMapperCustomizer
в приложении и реализовать его следующим образом:
import io.jmix.authserver.service.mapper.DefaultOAuth2TokenUserMixin;
import io.jmix.authserver.service.mapper.JdbcOAuth2AuthorizationServiceObjectMapperCustomizer;
// ...
@SpringBootApplication
public class MyApplication implements AppShellConfigurator {
// ...
@Bean
JdbcOAuth2AuthorizationServiceObjectMapperCustomizer tokenObjectMapperCustomizer() {
return objectMapper ->
objectMapper.addMixIn(User.class, DefaultOAuth2TokenUserMixin.class);
}
}
Здесь User
— это ваш класс сущности пользователя.
Если при использовании токена вы получаете java.lang.IllegalArgumentException: The class … is not in the allowlist
, это означает, что ваша сущность пользователя содержит поля типов, не поддерживаемых сериализатором токенов по умолчанию. В этом случае создайте класс миксина, расширяющий DefaultOAuth2TokenUserMixin
, и используйте его в бине JdbcOAuth2AuthorizationServiceObjectMapperCustomizer
. Например:
package com.company.backend.security;
import com.company.backend.entity.Department;
import com.company.backend.entity.UserStep;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.jmix.authserver.service.mapper.DefaultOAuth2TokenUserMixin;
import io.jmix.core.FileRef;
import java.util.List;
public class OAuth2TokenUserMixin extends DefaultOAuth2TokenUserMixin {
@JsonIgnore
private Department department;
@JsonIgnore
private List<UserStep> steps;
@JsonIgnore
private FileRef picture;
}
Если вы хотите вернуть хранение токенов в памяти, как в предыдущих версиях, установите свойство приложения jmix.authserver.use-in-memory-authorization-service в true
. При обновлении существующего проекта до Jmix 2.5, Studio автоматически устанавливает это свойство в true
, чтобы упростить процесс перехода на новую версию.
Подробнее см. #4153.
Интерфейс FileStorageLocator
В интерфейс io.jmix.core.FileStorageLocator
добавлен метод getAll()
. Если у вас есть собственная реализация этого интерфейса, реализуйте также и этот метод.
См. #4119 для получения дополнительной информации