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.lowagie package should be migrated to org.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 form tag 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 (like button) 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 persist or merge) 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 buildApp to build application distribution. Now we rely on built-in Gradle distribution plugin. It provides installDist (replace buildApp) but also adds support to package content into ZIP and TAR archives (ie distZip and distTar). 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 all grid 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.UserService for passwordMatchesPattern method.

  • 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 title attribute on xmlId fields in Meta entities

  • Fix pass action context in panel-dashlet edit form

    Details

    When a form view is opened through the panel-dashlet edit icon in a tab 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 _parent within 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 Tag widget 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.dir directory. It used to be possible to disable downloading and have exported files only accessible in data.export.dir directory. 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 download attribute: direct downloading is default

    • Remove output attribute.

  • 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 property auth.ldap.user.search.subtree = true | false, to update the search scope to onelevel if needed.

  • Add API key authentication via HTTP header

    Details

    Added support for authenticating API requests using API keys via the API-KEY HTTP header. Introduced UserToken entity 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 Fixture api 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
    • type is the model name.

    • key is a unique key for the fixture record.

    • properties contains 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 TenantAware and AuditableRunner behaviors.

    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).

    ContextAwareRunnable or ContextAwareCallable can 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 run and database gradle tasks as JavaExec tasks. This allows running them with vscode java debugger.

    Also, as Gradle support in all major IDEs is now matured, the run task should be the preferred way to debug axelor apps.

  • Add checkDuplicateClasses gradle task

    Details

    Added a new checkDuplicateClasses gradle 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 CliCommand instances using service loader interface. A database command is added to perform various database related tasks.

    The Gradle plugin adds a new task installDist to build application distribution. The application bundle will be generated at build/install/{project-name} folder which includes extracted war application in the app/ directory, launcher script dependencies in the lib/ directory and executable scripts in the bin/ directory.

    The axelor script is an executable command line tool that can be used to execute various commands provided by the app: ./bin/axelor --help for 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.ScriptAllowed annotation to your service interfaces or classes.

    • Implement the com.axelor.script.ScriptPolicyConfigurator interface 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.

    doInJpa helper has been removed, as it allowed unrestricted database access. To get a bean instance with policy check, \\__bean__ helper has been introduced to replace unrestricted com.axelor.inject.Beans.get usage.

    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 property auth.ldap.group.search.subtree = true | false, to update the search scope to onelevel if 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 AxelorCache interface 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.dir directory.

  • 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_HYPHENATION is renamed to IPDFRenderOption.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. path filename is used for download name if name is not specified as second parameter.

  • Migrate from Guava Cache to Caffeine for internal components

  • Update AuthUtils#getUser() to resolve the current user

    Details

    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 on ContextAware* 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 TagSelect widget in favor of Tags.

    Details

    TagSelect widget is deprecated in favor of Tags. 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

    Details
  • 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.

    • HttpSessionListener is no longer used. Instead, you can access active sessions via AuthSessionService.getActiveSessions() which uses the SessionDAO.

    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 javax namespace to the jakarta namespace.

  • Upgrade Spotless Gradle plugin from 6.25.0 to 7.0.4

    Details
  • 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 name on MetaFilter. Removed unique constraint on name, filterView, and replaced it with index meta_filter_filter_view_idx on 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 TenantAware and AuditableRunner

    Details

    This is replaced by a generic context propagation system based on ContextState and ContextAware* wrappers. Use ContextAwareRunnable or ContextAwareCallable instead.

Remove

  • Remove data.export.dir setting

    Details

    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, using com.axelor.file.temp.TempFiles, then download or attach the files somewhere for the users to access.

    Related ActionExport#getExportPath is also removed.

  • Remove top attribute in menuitem

    Details

    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/EvalRefSelect

    Details

    Added for backward compatibility, accessing fields now no longer need record. prefix. Update your js expressions, templates and EvalRefSelect x-eval-* attributes according.

  • Remove MetaPermissions#isCollectionReadable method

  • Remove method JPA#withTransaction(Supplier) in favor of JPA#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, licenseCheck and 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.

    There are many Gradle plugins that can do the job. List is available on the Gradle plugin portal. The awesome Spotless formatting plugin provides support for adding license headers.

  • 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:.\*} and ws/files/data-export/{fileName:.*} web services in favor of their equivalencies using query parameters : ws/files/report?link=<link> and ws/files/data-export?fileName=<fileName>.

  • Remove help css deprecated support

    Details

    Help widget css support is removed, use variant instead.

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.customFieldName in 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

Security

  • Don’t allow arbitrary file as template and export name in axelor-export

    Details

    The template file should be either uploaded MetaFile or should be within the template.search-dir.

    Shouldn’t be possible to have a "path" as export name (eg some/foo.xml).