8.0 Changelog
This page lists all the changes introduced in 8.0 releases. See also the release notes and the migration guide.
8.0.5 (2026-01-23)
Change
-
Upgrade backend dependencies
Details
Here is the list of backend dependencies upgraded :
-
Upgrade Quartz from 2.5.1 to 2.5.2
-
Upgrade Logback from 1.5.21 to 1.5.25
-
Upgrade Undertow from 2.3.20.Final to 2.3.21.Final
-
Upgrade Hibernate from 6.6.36.Final to 6.6.40.Final
-
Upgrade Resteasy from 6.2.14.Final to 6.2.15.Final
-
Upgrade Tomcat from 10.1.49 to 10.1.50
-
Upgrade Swagger from 2.2.40 to 2.2.41
-
Upgrade Greenmail from 2.1.7 to 2.1.8
-
Upgrade Moxy from 4.0.8 to 4.0.9
-
Upgrade pac4j from 6.2.2 to 6.3.1
-
Upgrade Redisson from 3.51.0 to 3.52.0
-
Upgrade PostgreSQL JDBC driver from 42.7.8 to 42.7.9
-
Upgrade BIRT from 4.21.0 to 4.22.0
Due to OpenPDF library upgrade, import statements using
com.lowagiepackage should be migrated toorg.openpdf. -
Fix
-
Fix step validation in decimal input widget
-
Fix alpha transparency usage in theme editor
-
Fix check draggable attribute in tree view node
-
Fix dms grid auto scroll issue on cell selection
-
Fix generating extended entities not included in project
Details
Extended entities having a super class were wrongly generated in project : Entities in a 'SINGLE_TABLE' hierarchy shouldn’t be annotated with
@Table(the root class declares the table mapping for the hierarchy). Issue only happens with entities declared in module dependencies (project dependencies not concerned). -
Disallow
formtag in DOMPurify sanitization -
Normalize empty HTML content in HTML widget
Details
Treat HTML editor output that contains only whitespace or <br> tags as empty. This prevents leftover <br> content when clearing the field and allows required validation to work as expected.
-
Fix perform advanced search on entire dms tree
8.0.4 (2026-01-05)
Feature
-
Implement tenant-aware AxelorCache
Details
By default, when multi-tenancy is active, the cache automatically segregates entries based on the current tenant context. Use
CacheBuilder#nonTenantAware()to disable this behavior and allow the cache to be shared globally across all tenants.
Fix
-
Fix connect/disconnect lines in gantt view
-
Fix bind close action in popup view
Details
When header/footer is hidden then it should still bind close handler properly so that action handler can close the view.
-
Fix kanban record opening permission check (canView/read)
Details
Allow opening a record in form view from the kanban view when either read or canView permission is granted.
-
Fix MFA form email resend timer
Details
Fix initial email resend timer when email method is default. Fix email resend timer on browser refresh.
-
Fix adding custom button in grid view customization
-
Fix auto-selection of created record in M2O widget
Details
When a record is created through the many-to-one widget using the popup form, the record is persisted via an action. After clicking OK, the newly created record should be automatically selected in the M2O widget.
-
Fix findFields to consider jsonModel for custom models
Details
Fix findFields returning wrong field metadata when different JSON models have fields with the same name. The method now correctly filters fields by jsonModel to avoid returning data from unrelated custom models.
-
Fix action-attrs support on tooolbar/menubar
Details
Fix changing title of toolbar buttons and menubar items in form view. Also add support for title/hidden/readonly attributes for cards/kanban/dms/grid views.
-
Improve DMS upload notification visibility and statuses
Details
Keep the DMS upload panel visible briefly after uploads complete, show accurate titles for running/failed/complete states, and add missing translations.
-
Don’t show automatic attrs on form view when there is at least one manual custom field
Details
Don’t show automatic attrs on form view when there is at least one manual custom field, e.g.
<field name="attrs.customField" />Static widgets on grid view (likebutton) do not prevent automatic attrs. -
Apply tenant-aware for database-dependent caches
Details
Use tenant-aware caches for MFAService, I18nBundle, and MetaStore. Any cache that contains database-dependent data should be tenant-aware.
8.0.3 (2025-12-04)
Fix
-
Restore flush on JPA.persist and JPA.merge
Details
In previous version, we removed automatic flush calls from JPA.persist() and JPA.merge() methods to restore JDBC batching for bulk operations. We restored this behavior to ensure backward compatibilities. It was initially added for an eager synchronization model (assume read-your-own-writes consistency immediately after any
persistormerge) but also to reduced cognitive load (doesn’t have to wired about potential synchronization issues). We thought the impact will be restricted, but the fact is that lot of process depending the behavior. This requires more preparation and details before we can get ride of this anti-pattern strategy and fit on standard.
8.0.2 (2025-12-01)
Change
-
Upgrade backend dependencies
Details
Here is the list of backend dependencies upgraded :
-
Upgrade Quartz from 2.5.0 to 2.5.1
-
Upgrade Hibernate from 6.6.31 to 6.6.36
-
Upgrade Groovy from 4.0.28 to 4.0.29
-
Upgrade Logback from 1.5.19 to 1.5.21
-
Upgrade Caffeine from 3.2.2 to 3.2.3
-
Upgrade Undertow from 2.3.19 to 2.3.20
-
Upgrade Tomcat from 10.1.47 to 10.1.49
-
Upgrade Bytebuddy from 1.17.7 to 1.17.8
-
Upgrade Swagger from 2.2.38 to 2.2.40
-
Upgrade Greenmail from 2.1.6 to 2.1.7
-
Upgrade Shiro from 2.0.5 to 2.0.6
-
Upgrade Jackson from 2.19.2 to 2.19.4
-
-
Remove flush from JPA.persist and and JPA.merge
Details
Removed automatic flush calls from JPA.persist() and JPA.merge() methods to restore JDBC batching for bulk operations. Previously, calling flush inside these methods forced Hibernate to execute SQL immediately, disabling JDBC batching and causing significant performance degradation. Since entities use SEQUENCE-based ID generation, Hibernate does not require an immediate flush to obtain IDs.
Behavior changes:
-
Constraint violations detected at next flush or transaction commit instead of during .save()
-
JPA lifecycle callbacks (@PrePersist, @PostPersist, @PreUpdate, @PostUpdate, etc.) execute at flush time rather than immediately after save()
-
JPA event listeners and entity interceptors (e.g., AuditInterceptor setting createdBy/updatedBy) trigger at flush time, not during save()
-
SQL execution order may shift slightly due to batching (no functional impact)
-
The changes are now not visible to native SQL or other connections/sessions until the transaction successfully commits
Code that expects entity state to be populated by listeners/interceptors immediately after save() must call flush() explicitly. For example, asserting createdBy field after save() now requires flush() to trigger the audit interceptor.
-
-
Use Gradle distribution plugin
Details
In recent 8.0, we introduced a new task
buildAppto build application distribution. Now we rely on built-in Gradle distribution plugin. It providesinstallDist(replacebuildApp) but also adds support to package content into ZIP and TAR archives (iedistZipanddistTar). CLI is still in BETA, so both tasks have been disabled by default. Request the tasks explicitly to generate the archives.
Fix
-
Prevent long panel titles from overflowing
Details
Form panel headers now force their title container to shrink so overly long titles are truncated (ellipsis) instead of spilling outside of the panel frame. Applies to standard panels, o2m/m2m grids, and dashlets.
-
Fetch calendar records based on visible range instead of current month
Details
Previously, records were fetched based on the strict start and end of the current month. This caused missing data for the trailing days of the previous month and leading days of the next month that were still visible. The fetch logic now calculates the actual start and end dates of the visible viewport.
-
Fix files upload store
Details
Ensures all stream are closed in order to avoid memory leak. S3 now upload files using stream-based uploads instead of file based upload as it costs a bit of extra I/O. S3 caching mechanism stores the entire file content in the Java Heap memory : this cause high memory consumption.
-
Fix monaco editor worker loading for non-basic languages
Details
Web workers is required for rich language features (validation, formatting, completion). This ensure these resources are fetched correctly using explicit paths containing
/vs. -
Fix how to handle 50x response errors
Details
Display 50x error response in alter, except for the special maintenance mode.
-
Fix redundant dashlet refresh after grid initialization
Details
Previously, when a dashlet was not yet rendered (e.g., in an inactive panel tab or hidden state) and refresh: true was set through action-attrs, it would trigger an unnecessary refresh once it became visible. This fix ensures that if the dashlet has already been refreshed during grid initialization, the extra refresh triggered by the earlier refresh: true flag is skipped.
8.0.1 (2025-11-10)
Feature
-
Improve frontend loading performance with lazy loading
Details
Lazy load application routes, but also ReactDatePicker and libphonenumber-js libraries. This reduce main bundle size by 50% and loaded them on-demand.
Fix
-
Fix blinking grid header
Details
While switching from edit/view mode, grid header label was blinking due to style changes.
-
Rotate x-axis labels to avoid hiding overlaps on bar chart
-
Don’t render grid footer if no records
Details
In case of
allgrid aggregation type, don’t render grid footer if there is no record. This also ensure the aggregate function doesn’t not crash when no data are available. -
Fix time series with line chart
Details
Use xAxis type "time" for
<category type="date|time" />Line chart was always using "category" type (equal spacing), which is incorrect when dealing with time. -
Fix search collection records when saving via onChange
-
Fix test sources used as deployment assembly in eclipse
Details
Sometime when refreshing gradle projects, test sources appears as deployment assembly causing unexpected behavior.
-
Fix forbidden action condition when changing user password
Details
Add script-allowed
com.axelor.auth.UserServiceforpasswordMatchesPatternmethod. -
Fix UI blocking after re-login popup
Details
Fix duplicate count decrement upon 401 (session expiration), that caused non-blocking UI after re-login from popup.
-
Fix response error handling
Details
On constraint violations, return the violations mentioning the fields and the associated explicit constraint message.
Add the check, not null and too long violations to as explicit messages returned to users. Other cases are default messages.
-
Fix handling of end-of-lines in i18n messages
Details
CSV normalized end-of-lines to \r\n, between CSV records only, not for cell data. CSV cell data is now also normalized to \r\n.
For multiline translation keys, need to normalize back to \n, as that’s what is used in source code, meta views, etc. This fixes translations when keys contain end-of-lines.
-
Fix set action attrs in collection field of m2o editor
Details
This fix enables setting action-attrs (e.g., show/hide columns) for collection fields in O2O/M2O editors. Attributes can now be set both from the main form scope (customer.addresses.country: { hidden: true }) and within the editor scope (addresses.country: { hidden: true }).
-
Fix close action behavior in custom model popup
-
Fix binding of collection of proxies
Details
Example:
// titles contains HibernateProxy objects List<Contact> results = contactRepo.all().filter("self.title IN :titles").bind("titles", titles).fetch();Caused UnknownEntityTypeException
-
Fix missing series labels on bar chart
Details
Also don’t show bar group for discrete bar, i.e., when groupBy is not used.
-
Adjust compose message popup title and buttons
-
Horizontal bar chart y-axis should be in descending order
Details
For example, if y-axis has years, top should be earliest, bottom should be latest.
-
Add
titleattribute onxmlIdfields in Meta entities -
Fix pass action context in panel-dashlet edit form
Details
When a form view is opened through the
panel-dashletedit iconin atab view, the newly opened form view (in tab) record should be treated as the_parent, and the original panel-dashlet record should be passed as a nested_parentwithin it. -
Make autocomplete search non-blocking to prevent keyboard input disruption
Details
On M2O input autocomplete, as soon as search was triggered, onSelect then search query was triggered. onSelect is a UI blocking action, so any subsequent keyboard input in that time is skipped causing a poor user experience on heavy application.
Now onSelect is triggered if necessary, means only if the context doesn’t change. This reduce the number of calls. Moreover, keyboard input isn’t blocking on input element anymore. This allow users to continue typing smoothly while the onSelect action processes in the background.
An abortion technique is implemented to abort previous search request depending on keyboard input received.
8.0.0 (2025-10-14)
Feature
-
Implement
Tagwidget for M2O/O2O to render value as a tag element. -
Add docx/xlsx/odt/ods to action-report supported formats
-
Lazy load popper to improve views rendering
-
Auto adaptive scale for grid aggregation
Details
Grid aggregation values had a hard coded scale to 2. Now, grid aggregation values have auto adaptive scale depending on values calculated and trailing zeros are removed.
-
Rework axelor-export storage
Details
Exported files are now created as a temporary files instead of being saved to
data.export.dirdirectory. It used to be possible to disable downloading and have exported files only accessible indata.export.dirdirectory. This is no longer the case: the export files have to be either downloaded or attached to the current record.-
Add
attachment="true|false"attribute to attach the exported file to the current object. -
Remove
downloadattribute: direct downloading is default -
Remove
outputattribute.
-
-
Add LDAP support to subtree search for users
Details
By default, search scope to locate users is
subtree: search whole subtree of base DN. Use new propertyauth.ldap.user.search.subtree = true | false, to update the search scope toonelevelif needed. -
Add API key authentication via HTTP header
Details
Added support for authenticating API requests using API keys via the
API-KEYHTTP header. IntroducedUserTokenentity to manage API tokens per user, with secure token generation, hashing, and expiration handling.Tokens can be created, revoked, and rotated from the User form.
-
Implement new Fixture api
Details
The new
Fixtureapi provides a more clean yaml format.For example:
- type: User # model key: user:admin # unique key properties: name: Some Name code: admin role: role:1 # reference key groups: - group:1 # reference key - group:2 # reference key-
typeis the model name. -
keyis a unique key for the fixture record. -
propertiescontains the fields of the model.
The relationships are defined using reference keys.
-
-
Cache version/hash-named static assets in production
-
Implement a new context propagation system across threads and tasks submission
Details
The new context propagation system is used to propagate context across threads and tasks submission. This is an all in one system combining
TenantAwareandAuditableRunnerbehaviors.Main issue is to propagate in threads and tasks all information’s coming from HTTP requests (only available in servlet environments). Are concerned: the current user, tenant, locale, language and base URL. Some can be determined by application properties, some logic can be dependent from the request. The system is now able to propagate all current context information in threads and tasks. It also allows manually defining them in (case of scheduling / batching).
ContextAwareRunnableorContextAwareCallablecan be used to propagate context information.Usage :
ContextAware.of() .withTransaction(true) // true by default .withUser(AuthUtils.getUser("admin")) .withTenantId(myTenant) .build( () -> { // Task code here } ) .run() -
Re-implement run and database gradle tasks
Details
Re-implemented
runanddatabasegradle tasks asJavaExectasks. This allows running them with vscode java debugger.Also, as Gradle support in all major IDEs is now matured, the
runtask should be the preferred way to debug axelor apps. -
Add checkDuplicateClasses gradle task
Details
Added a new
checkDuplicateClassesgradle task to detect conflicting dependencies in application projects.The task analyzes runtime classpath dependencies and identifies duplicate classes between different jar files, helping to prevent classpath conflicts that can cause runtime issues.
Key features:
-
Automatically excludes Axelor modules (which can have duplicate domain classes by design)
-
Supports exclude patterns for specific libraries
-
-
Support global and component-specific cache configuration
Details
Cache can be configured for the whole application or for specific components (Hibernate, Shiro).
# Global cache configuration applied to Hibernate, Shiro and internal components # ~~~~~ # Global cache provider: default/caffeine/redisson application.cache.provider = redisson # Global cache configuration for specified provider: either on filesystem or resource in classpath application.cache.config = redisson.yaml # Hibernate-specific cache configuration (takes precedence over global cache configuration) # ~~~~~ #application.cache.hibernate.provider = redisson #application.cache.hibernate.config = redisson.yaml # Shiro-specific cache configuration (takes precedence over global cache configuration) # ~~~~~ #application.cache.shiro.provider = redisson #application.cache.shiro.config = redisson.yaml -
Add application bundle & CLI support
Details
The command line support can be used to implement custom commands to perform various tasks. The command line runner will locate
CliCommandinstances using service loader interface. Adatabasecommand is added to perform various database related tasks.The Gradle plugin adds a new task
installDistto build application distribution. The application bundle will be generated atbuild/install/{project-name}folder which includes extracted war application in theapp/directory, launcher script dependencies in thelib/directory and executable scripts in thebin/directory.The
axelorscript is an executable command line tool that can be used to execute various commands provided by the app:./bin/axelor --helpfor more details. -
Add S3-Compatible Object Storage
Details
Added support for S3-compatible object storage for DMSFile/MetaFile. The default implementation remains disk storage, but it can be switched to an S3-compatible service by configuring the
data.object-storage.*properties. This change introduces a storage abstraction layer (FileStoreFactory) that should be used instead of direct file system access to ensure compatibility with both storage types. -
Implement multi-tenancy support of quartz schedulers
Details
The app will now configure scheduled tasks per tenant during startup. Also added support to update/remove tasks per tenant at runtime.
-
Add Multi-Factor Authentication (MFA) support
Details
Introduced Multi-Factor Authentication (MFA) as an optional security feature to enhance user account protection. Supported MFA methods:
-
TOTP (Time-based One-Time Password) via authenticator apps.
-
Email verification codes (with 5-minute validity)
-
Recovery codes as backup authentication method Users can configure, test, and enable MFA from their preferences, select a default MFA method, and are prompted for a second-factor code during login once MFA is activated.
-
-
Implement scripting policy check support
Details
A scripting policy has been introduced to control which Java classes are accessible from scripts (Groovy, Expression Language, JavaScript). By default, access to most application classes is now restricted.
If your application uses scripts that call custom services or other classes, you will need to explicitly allow them. You can do this in two ways:
-
Add the
@com.axelor.script.ScriptAllowedannotation to your service interfaces or classes. -
Implement the
com.axelor.script.ScriptPolicyConfiguratorinterface to programmatically define allowed/denied packages and classes.
Additionally, a script execution timeout has been introduced to prevent infinite loops, which defaults to 5 minutes. This can be configured globally or per script execution.
doInJpahelper has been removed, as it allowed unrestricted database access. To get a bean instance with policy check,\\__bean__helper has been introduced to replace unrestrictedcom.axelor.inject.Beans.getusage.Note that the scripting policy is also applied to Groovy template engines by using the same class scanner and compiler configuration as for Groovy scripts. A side effect is that Groovy templates now use the same JPA class scanner.
-
-
Add code generation support for test entities
Details
Test entities can now be generated from XML files. This enables using the same domain modeling approach for test entities as production code.
-
Add LDAP support to subtree search for groups
Details
By default, search scope to locate groups is
subtree: search whole subtree of base DN. Use new propertyauth.ldap.group.search.subtree = true | false, to update the search scope toonelevelif needed. -
Add show and copy button to form password widget in readonly
Details
Improve form password widget in readonly mode by showing the "show password" button if there is any value and adding a copy button to copy the value to clipboard.
-
Return MediaType when downloading a file
Details
When downloading a file, return the right
Content-Type. Only pdf/images and html files can be previewed in browser. -
Format bytes on system information page
-
Add AxelorCache caching interface supporting distributed caching
Details
The
AxelorCacheinterface wraps various cache implementations.Supported implementations include:
-
Caffeine (in-memory)
-
Redisson (Redis/Valkey)
The underlying implementation that is used depends on application configuration.
Usage example:
private static final AxelorCache<String, Action> ACTIONS = CacheBuilder.newBuilder("actions").maximumSize(1000).weakValues().build(XMLViews::findAction);Added
DistributedFactory, which is a utility class that facilitates concurrency control in distributed cache environments. It provides static methods to access distributed-aware synchronization primitives, such as locks and atomic longs. -
-
Add mass updatable fields even if not declared in grid view
Details
Currently, only fields declared in the grid view marked with the massUpdate attribute are updatable. Now, fields in the entity, even if not declared in the grid view, will also be listed in the mass update popover.
Change
-
Download i18n export as zip file instead of using data.export.dir
Details
I18n exports are now downloaded as zip archive, instead of being created in
data.export.dirdirectory. -
Use Shiro 2 argon2id hash algorithm
Details
Use Shiro 2 default hash algorithm: argon2id
To migrate passwords to the more secure algorithm, you can force users with old hashes to change their passwords:
UPDATE auth_user SET force_password_change = TRUE WHERE password LIKE '$shiro1$%';When users set their new passwords, the new hash algorithm will be used.
-
Re-implemented audit tracking/fields support
Details
The old Interceptor based implementation has several limitations and couldn’t work in cases where persistence session is created manually.
The new implementation uses event listener api and thus can have access to the session for which the events are fired. Fixing, issues caused by persistent session created manually.
Also, new api handles multi-threading cases more effectively.
-
Upgrade backend dependencies
Details
Here is the list of backend dependencies upgraded :
-
Upgrade to Guice 7 (Jakarta EE 9)
-
Upgrade Hibernate from 5.6.x to 6.6.31.Final
-
Upgrade BIRT from 4.4.2 to 4.21.0
Many of your reports will likely have rendering changes or may even be broken due to numerous emitter improvements/changes in BIRT.
IPDFRenderOption.PDF_HYPHENATIONis renamed toIPDFRenderOption.PDF_WORDBREAK, but enabled by default.BIRT has a transitive dependency to Apache POI, upgraded from 3.9 to 5.4.0, that includes breaking changes: https://poi.apache.org/changes.html
Also, the XML parser in BIRT has become stricter. Most notably, in your
fontsConfig.xml, you need to omit the DOCTYPE declaration<!DOCTYPE font>to avoid validation against a non-existent DTD. Otherwise, your font configuration file will fail validation and will be ignored.-
Upgrade Apache Tomcat from 9.0.x to 10.1.47
-
Upgrade Junit5 from 5.11.4 to 5.13.4
-
Upgrade Ldaptive from 2.3.2 to 2.4.2
-
Upgrade jsoup from 1.18.3 to 1.21.2
-
Upgrade pac4j from 5.7.x to 6.2.2, buji-pac4j from 8.1.x to 9.1.0, and jakartaee-pac4j from 7.1.x to 8.0.1
-
Upgrade mysql-connector-j from 8.4.0 to 9.4.0
-
Upgrade Postgresql JDBC from 42.7.4 to 42.7.8
-
Upgrade Apache Tika from 2.9.x to 3.2.3
-
Upgrade UnboundID LDAP SDK from 6.0.11 to 7.0.3
-
Upgrade Woodstox from 6.7.0 to 7.1.1
-
Update Swagger from 2.2.28 to 2.2.38
-
Upgrade snakeyaml from 2.3 to 2.4
-
Upgrade Shiro from 1.13.0 to 2.0.5
-
Upgrade Redisson from 3.38.1 to 3.51.0
-
Upgrade Jackson from 2.18.x to 2.19.2
-
Upgrade HikariCP from 6.3.0 to 7.0.2
-
Upgrade hazelcast from 5.3.7 to 5.5.0
-
Upgrade guava from 33.3.1-jre to 33.4.8-jre
-
Upgrade from Groovy 3 to Groovy 4
-
Upgrade GraalJS from 22.3.5 to 24.2.2
-
Upgrade Flyway from 9.22.3 to 11.11.2
-
Upgrade Apache Commons JXPath from 1.3 to 1.4.0
-
Upgrade commons-io from 2.18.0 to 2.20.0
-
Upgrade commons-csv from 1.12.0 to 1.14.1
-
Upgrade Caffeine from 3.1.6 to 3.2.2
-
Update Byte Buddy from 1.15.11 to 1.17.7
-
Upgrade ASM from 9.7.1 to 9.8
-
Upgrade to Resteasy 6 (Jakarta EE 10)
-
Upgrade to Quartz 2.5
-
Upgrade to Logback 1.5
-
Switch from org.fusesource.jansi to org.jline:jansi 3.30.6
-
Upgrade to Jakarta XML Binding 4.0
-
Upgrade to Jakarta WebSocket 2.0
-
Upgrade to Jakarta Mail 2.1 and Jakarta Activation 2.1
-
Upgrade Hibernate Validator from 6.2.5.Final to 8.0.3.Final
-
Upgrade Infinispan from 13.0.22 to 15.2.6.Final
-
Upgrade Ehcache from 3.10.8 to 3.11.1
-
Upgrade Undertow from 2.2.37.Final to 2.3.19.Final
-
-
Upgrade Gradle from 8.11.1 to 8.14.3
-
Remove Junit4 support
Details
JUnit 4 is no longer actively maintained, and the last maintenance release was JUnit 4.13.2 in February 2021. Support for JUnit Jupiter (JUnit 5) was introduced in v6.0. It is time to drop support for JUnit 4. Migrate your Junit tests to Junit5.
-
Implement token-based download for ActionResponse#setExport
Details
Data export process now requires a token param instead of a file path relative to the export directory. ActionResponse#setExport has been updated and overloaded accordingly:
-
ActionResponse#setExport(String path) -
ActionResponse#setExport(String path, String name) -
ActionResponse#setExport(Path path, String name) -
ActionResponse#setExport(Path path, String name) -
ActionResponse#setExport(InputStream stream, String name)
The file path is copied to a dedicated temporary file for pending export.
pathfilename is used for download name ifnameis not specified as second parameter. -
-
Migrate from Guava Cache to Caffeine for internal components
-
Update
AuthUtils#getUser()to resolve the current userDetails
Initially,
the AuthUtils#getUser()method is used to retrieve the current connected user. This is only available in servlet environments. In case of non-servlet environments (batch/schedule/…), there is no connected user. Now the method retrieves the current user associated with the thread or session (see context propagation system based onContextAware*classes). It first uses the current user stored in the thread-local if provided. Else it attempts to retrieve the connected user if any. -
Deprecate
TagSelectwidget in favor ofTags.Details
TagSelectwidget is deprecated in favor ofTags. It has the same behavior, it’s just a renaming of the widget name for readability and relevance. Old name can still be used, but we encourage adopting the new name as its usage will be removed in a next version. -
Upgrade from JDK 11 to JDK 21
-
Switch to Shiro native sessions
Details
We have switched from servlet-container sessions to Shiro native sessions. This change enables the use of Redis/Valkey server as a session store and simplifies the overall architecture by leveraging Shiro’s
SessionDAO.Key changes to be aware of:
-
By default, the session manager now uses in-memory Caffeine cache. This means that sessions are not persisted between application restarts.
-
HttpSessionListeneris no longer used. Instead, you can access active sessions viaAuthSessionService.getActiveSessions()which uses theSessionDAO.
For more details about Shiro’s session management, see the Shiro Session Management documentation.
-
-
JEE Jakarta transition
Details
Move from Java EE to Jakarta EE. This include transition from the
javaxnamespace to thejakartanamespace. -
Upgrade Spotless Gradle plugin from 6.25.0 to 7.0.4
-
AppSettings#getBaseURL resolves as tenant host and app base url before request host
Details
In case of multi-tenancy, base url should favor tenant host. Without multi-tenancy, base url should favor app config base url.
Request host is now last fallback.
-
Save/update/delete filters now by id instead of name
Details
Removed field
nameon MetaFilter. Removed unique constraint on name, filterView, and replaced it with indexmeta_filter_filter_view_idxon filterView.This allows different users to create filters with the same title.
Database migration script:
ALTER TABLE meta_filter DROP COLUMN name; CREATE INDEX IF NOT EXISTS meta_filter_filter_view_idx ON meta_filter(filter_view);
Deprecate
-
Deprecate
TenantAwareandAuditableRunnerDetails
This is replaced by a generic context propagation system based on ContextState and ContextAware* wrappers. Use
ContextAwareRunnableorContextAwareCallableinstead.
Remove
-
Remove
data.export.dirsettingDetails
Another consequence of supporting multiple storage providers is the removal of export directory setting
data.export.dir. If you used it, you should migrate your code to create temporary files or directories instead, usingcom.axelor.file.temp.TempFiles, then download or attach the files somewhere for the users to access.Related ActionExport#getExportPath is also removed.
-
Remove
topattribute inmenuitemDetails
Top menu support has been removed since 7.0. To ensure compatibility, the attribute was still present in xsd.
-
Remove
record.prefix support in expressions/templates/EvalRefSelectDetails
Added for backward compatibility, accessing fields now no longer need
record.prefix. Update your js expressions, templates and EvalRefSelectx-eval-*attributes according. -
Remove
MetaPermissions#isCollectionReadablemethod -
Remove method
JPA#withTransaction(Supplier)in favor ofJPA#callInTransaction(Supplier) -
Remove built-in license header support
Details
As part of the AxelorPlugin, we historically provided built-in support to manage license headers. This support has been removed and
licenseFormat,licenseCheckand related tasks no longer exist. The plugin on which support was provided is no longer maintained. This is now application or module responsibility to provide it. -
Remove Gradle support for database management
Details
This removes Gradle support for database management (init/update/…) in favor of new CLI.
-
Remove support of Font Awesome icons
Details
Use either Material Symbols and Bootstrap Icons.
-
Remove deprecated web services
Details
Remove deprecated
ws/files/report/{link:.\*}andws/files/data-export/{fileName:.*}web services in favor of their equivalencies using query parameters :ws/files/report?link=<link>andws/files/data-export?fileName=<fileName>. -
Remove help
cssdeprecated supportDetails
Help widget
csssupport is removed, usevariantinstead.
Fix
-
Fix StringTemplate not taking into account locale for LocalDate/LocalDateTome/LocalTime formatting
-
Render Label widget as static text instead of a template
-
Fix item count in grid group aggregation
Details
On a grid with multiple groups, the item count displayed on each level was incorrect.
-
Fix prevents value change on number input via mouse wheel
-
Fix saving of custom attrs items in grid customization
Details
Custom attrs fields/buttons that were auto-added were not properly processed when saving customization.
This fixes preserving and removing of those fields.
When saved, all custom fields are explicitly present as view items.
-
Fix edit-window support and check perms in m2o editor
-
Fix audit tracking issue when L1 cache is cleared
Details
When a tracked value is lazy proxy and is not in L1 cache, it will give lazy initialization error.
-
Fix show download option in binary widget
-
Fix tree-grid border styles
-
Same context for form field and json field
Details
With this change custom field and form field are accessible through same way, i.e. form field can directly be accessed and custom fields are accessed like
$attr.customFieldNamein both kinds of fields. -
Fix null base url when using TenantAware
-
Fix generateCode task spurious warning "track unknown field"
Details
When defining an entity in xml, extending an entity not available in project source (defined in dependencies), that super entity was not available in lookup and caused spurious warning "track unknown field".
Now make sure to compute lookup for any super classes if not present.
-
Fix add $attachments to form action context
-
Fix styles for top level tree-grid
-
Allow selecting all custom fields when customizing grid columns
Details
When there are no custom fields in original grid view, all custom fields visible in grid are added to view.
But in the case when there is at least one custom field defined in original view, only that custom field was listed in grid customization selector. Now all custom fields are listed, even those who aren’t checked are visible in grid.
-
Check MetaPermissionRule on mass update
Details
During massUpdate web service, if any fields are not allowed to be updated through MetaPermissionRule, return an exception and display it to the user.
-
Add client side searching/sorting to fields selector grid
-
Fix closing LDAP connection pool when shutting down Tomcat
Details
With Runtime.getRuntime().addShutdownHook(), closing LDAP connection pool will attempt to log something after the web application has already been stopped.
Instead, now observing ShutdownEvent, ensuring we close LDAP connection pool within application lifecycle.
Fixes various NoClassDefFoundError, such as:
java.lang.NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy Caused by: java.lang.ClassNotFoundException: Illegal access: this web application instance has been stopped already. Caused by: java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already.
-
Fix json fields in customized grid
Details
Fix json fields handling in customized grid leading to duplication issues.
-
Validate image size against maximum upload size setting on html widget