What’s New

This section covers new features of Jmix framework and Studio 2.5, as well as some breaking changes to be aware of when upgrading from a previous version of the framework.

How To Upgrade

To create new projects with Jmix 2.5 or to upgrade an existing project, you need Studio 2.5 or later, so update your Jmix Studio plugin first.

The minimal supported IntelliJ IDEA version is now 2024.2.

See Upgrading Project section for how to upgrade your project using Studio. The automatic migration procedure makes the following changes in your project:

  • Updates the version of Jmix BOM which in turn defines versions of all dependencies.

  • Updates the version of Jmix Gradle plugin.

  • Updates the version of Gradle wrapper to 8.12.1 in gradle/wrapper/gradle-wrapper.properties.

  • Migrates imports of NotInstantiatedList and NotInstantiatedSet classes. See details below.

  • If the project includes the REST API add-on, sets the jmix.rest.inline-fetch-plan-enabled to false. See details below.

  • If the project includes the Authorization Server add-on, sets the jmix.authserver.use-in-memory-authorization-service property to true. See details below.

See also the full list of breaking changes that can affect your project after the upgrade.

If, after upgrading the project and starting the application, you encounter the following exception:

com.vaadin.flow.server.ExecutionFailedException: Vite build exited with a non zero status

remove the following files and directories from the project root: node_modules, package.json, pnpm-lock.yaml, tsconfig.json, types.d.ts, vite.config.ts, vite.generated.ts

Also, if you have Node.js installed globally, update it to the latest LTS version available on the website https://nodejs.org.

Updated Dependencies

The following major dependencies have been updated:

New Features and Improvements

Studio Improvements

Hot Deploy Indication

Studio now displays a new icon in the top right corner of hot-deployable files (view controllers and descriptors, message bundles, roles, etc.). This icon indicates the status of hot deployment for this file.

The purpose of the indicator is to continuously inform the developer about the delivery of the latest changes in the source code to the working application.

Application Log Analysis

Studio can now detect common exceptions appearing in the application console and offer suggestions for their resolution.

The hot deploy indicator also works by analyzing the application console output.

Jmix Run/Debug Configuration

We have introduced a new Jmix run/debug configuration that replaces the standard Gradle configuration. It is created automatically when you open a Jmix project in the IDE. You can distinguish the new configuration by the Jmix icon.

In contrast to the Gradle configuration, the new Jmix configuration allows the application to shut down gracefully without generating errors in the console.

You can create the Jmix run/debug configuration in Run/Debug Configurations window by clicking Add New Configuration tool button and selecting Jmix Application item. The configuration is also created if you click Start Application in the context menu of the root node in the Jmix tool window.

classNames Editor and Autocompletion

Studio now provides advanced support for entering values in the classNames property of UI components. When editing a view XML descriptor, available class names are offered by autocompletion. The Jmix UI component inspector provides an editor window that allows you to select class names visually.

Available class names are obtained from the following sources:

  • com.vaadin.flow.theme.lumo.LumoUtility class and its nested classes.

  • io.jmix.flowui.themes.JmixLumoUtility class.

  • Any custom class annotated with @ThemeUtilityClasses. You can provide shared class names in your own add-ons and in the application sources.

OpenAPI Client Generation by Tags

When generating client code by OpenAPI schema as described in Integrating Applications Using OpenAPI guide, you can now select only particular tags defined in the schema. This reduces the amount of generated code if not all paths of the schema are needed for the integration.

Message Templates Add-on

The Message Templates add-on allows you to create reusable templates for sending emails and in-app notifications.

Tabbed Application Mode (Experimental)

The new Tabbed Application Mode add-on allows you to open application views in separate tabs inside the main view.

The add-on transparently replaces navigation by opening views in the main view tabs. You can also use the specific ViewBuilders bean to open views in the current main view tab, in a new tab, or in a dialog window.

The Tabbed App Mode add-on is currently in the experimental state and can change significantly in the next Jmix release.

Editing Objects on Map

The Maps add-on now provides support for selecting, moving and modifying features added to vector sources.

See #2832 for more information.

Advanced BPM Task List View

Now you can generate an advanced BPM task list view in your project using the BPM: Advanced task list view template of the view creation wizard.

This view has more features than the built-in My tasks view and can be customized in the project as needed.

See #3752 for more information.

Substituted User in Audit

The Entity log view provided by the Audit add-on now shows both the logged-in user and a substituted user for each change.

Related issue: #4034

DataGrid Empty State

The dataGrid component now supports emptyStateComponent and emptyStateText properties for displaying some content when there’s no data available.

For more information, see Vaadin documentation and #3884.

REST API and REST DataStore Improvements

Fetch Plans in REST API and REST DataStore

Previously, generic REST endpoints could accept only names of fetch plans registered in the shared fetch plan repository. Now you can also pass arbitrary fetch plans as JSON objects, see Inline Fetch Plans.

This feature affects the usage of REST DataStore: now you don’t have to define all fetch plans in the shared repositories both on the client and in the service. Instead, you can use inline fetch plans in your client views and Java code as usual.

The REST API now exposes a new Capabilities API. It informs the client about features supported by this generic REST API. Currently, the JSON object returned by the /capabilities endpoint includes a single property: inlineFetchPlans. If its value is true, then inline fetch plans are enabled. Otherwise, a client can pass only named fetch plans as before.

You can disable inline fetch plans for the generic REST in your application using the jmix.rest.inline-fetch-plan-enabled application property. When you use Studio to upgrade an existing project to Jmix 2.5, it sets this property to false automatically to prevent accidental data leaks.

Related issue: #4031

Using FileStorage with REST DataStore

The REST DataStore add-on now includes a specific FileStorage implementation that works with files located in the remote application’s file storage through the /files generic REST endpoints. See REST DataStore: File Storage for more information.

Related issue: #4119

Configurable Paths of REST Endpoints

Paths of the generic REST API endpoints can now be configured using application properties, see REST Properties: Paths.

Related issue: #4052

Sessions in REST API

The Jmix Sessions add-on provides support for sessions maintained across REST requests with the same token. You can use the add-on in your project by adding the following dependency to your build.gradle:

implementation 'io.jmix.sessions:jmix-sessions-starter'

Related issue: #3915

Using UUIDv7 for Entity Identifiers

UUIDv7 are now used when generating values for UUID attributes annotated with @JmixGeneratedValue. UUIDv7 are time-based, which makes them better suited for database keys because of natural ordering.

The UuidProvider class now has the createUuidV7() method that is used by default by EntityUuidGenerator bean. If you want to revert to previous random UUIDs for entity identifiers, set the following application property:

jmix.core.legacy-entity-uuid=true

Related issue: #3424

Copier Interface

The new Copier interface provides the copy(Object) method for copying entities. It is similar by semantics to MetadataTools.deepCopy(Object) but different in that its default implementation doesn’t rely on metadata and copies all object’s state using Java serialization.

You can use Copier to isolate entities from UI when sending them to custom services from views. DataContext uses this interface to make entity copies when saving them to DataManager.

Related issue: #3937

Current Locale Query Parameter

Now you can use the current_locale predefined query parameter in the same way as parameters with the current_user_ prefix. For example:

select e from Region e where e.locale = :current_locale

The parameter value is the locale of the current user session taken from the CurrentAuthentication object.

Related issue: #3958

Hot Deploy Folder Cleanup

Previously, the .jmix/conf folder that is used for hot deploy was cleaned only by Studio "before launch" task Clean Hot Deploy Conf Directory.

To make the cleanup more reliable and not depending on Studio, we have added the cleanConf task to the Jmix Gradle plugin. It runs each time before launching the application by the bootRun task.

If you have any trouble with this feature, you can disable the cleanConf task in the project by adding the following property to your build.gradle:

jmix {
    // ...
    confDirCleanupEnabled = false
}

Related issue: #3451

Breaking Changes

Checkbox Required State

The checkbox component supports validation of the "required" state. If the checkbox is required due to its own required attribute or if it’s connected to a mandatory entity attribute, only true value will pass the validation and the detail view will be closed.

For more information, see Vaadin documentation and #4045.

Core Modules Refactoring

Due to refactoring of database-related dependencies of core subsystems (in #3918), the following breaking changes may affect your project:

  • NotInstantiatedList and NotInstantiatedSet classes have been moved from io.jmix.data.impl.lazyloading to io.jmix.eclipselink.lazyloading package. These classes are used for initializing entity collection attributes in Kotlin projects. Update imports in your entities accordingly.

  • io.jmix.data.entity.ReferenceToEntity embeddable entity has been removed. If you need it in your project, create your own copy.

  • io.jmix.flowuidata.accesscontext.UiGenericFilterModifyGlobalConfigurationContext class has been moved to io.jmix.flowui.accesscontext package.

  • All classes of io.jmix.flowuidata.action.genericfilter package have been moved to io.jmix.flowui.action.genericfilter package.

  • All classes of io.jmix.securityflowui.model have been moved to io.jmix.security.model package.

  • io.jmix.flowuidata.genericfilter.UiDataGenericFilterSupport class has been merged into io.jmix.flowui.component.genericfilter.GenericFilterSupport and removed.

See #3982 for more information.

Authorization Server Token Storage

The Authorization Server add-on now stores tokens in the database, which ensures the tokens are preserved on server restarts.

If you are using the Password Grant, you need to define a bean of the JdbcOAuth2AuthorizationServiceObjectMapperCustomizer type and implement it as follows:

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);
    }
}

Here User is your user entity class.

If you get java.lang.IllegalArgumentException: The class …​ is not in the allowlist when using a token, it means that your user entity contains fields of types not supported by the token serializer by default. Then create a mixin class extending DefaultOAuth2TokenUserMixin and use it in the JdbcOAuth2AuthorizationServiceObjectMapperCustomizer bean. For example:

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;
}

If you want to revert to the previous in-memory token storage, set the jmix.authserver.use-in-memory-authorization-service application property to true. When you use Studio to upgrade an existing project to Jmix 2.5, it sets this property to true automatically to facilitate the process.

See #4153 for more information.

FileStorageLocator Interface

Added getAll() method to io.jmix.core.FileStorageLocator interface. If you have your own implementation of this interface, implement also this method. See #4119 for more information.

Changed Constructors

Due to internal refactoring (#4152), constructor signatures of the following beans have been changed:

  • DetailViewNavigationProcessor

  • HtmlContainerReadonlyDataBindingImpl

  • MenuItemCommands

  • UrlQueryParametersFacetProvider

  • ViewNavigationDelegate

If you have extended versions of these beans, you may need to adapt them.

Changelog

  • Resolved issues in Jmix Framework:

  • Resolved issues in Jmix Studio: