arrow-down
  1. Intro
    1. Widgets
    1. ID providers
    2. System ID provider
    3. Users and groups
    4. Roles
    1. Projects
    2. Layers
        1. AttachmentUploader
        2. Checkbox
        3. Combobox
        4. ContentSelector
        5. ContentTypeFilter
        6. CustomSelector
        7. Date
        8. DateTime
        9. Double
        10. GeoPoint
        11. HtmlArea
        12. ImageSelector
        13. Long
        14. MediaSelector
        15. Radiobutton
        16. Tag
        17. TextArea
        18. TextLine
        19. Time
      1. Field set
      2. Item set
      3. Option set
      4. Mixins
      5. Localization
    3. Content Types
    4. X-data
    5. Macros
    6. Custom styles
    7. Sites
      1. Regions
      2. Part component
      3. Layout component
      4. Text component
      5. Fragments
      6. Filtering
      7. Component indexing
      8. Visual editor
    8. Page templates
  2. Applications
    1. Sandboxes
    2. Code
    3. Building
    4. Configuration
    5. TypeScript
      1. Controllers
      2. Globals
      3. HTTP
      4. Events
      5. Error handler
      6. Filters
      7. ID provider
      8. Tasks
      9. Templating
      10. Localization
      11. Websocket
      12. Mappings
      13. Components
      14. Processors
      15. Contributions
      16. Main controller
      17. Java bridge
      1. Admin API
      2. Application API
      3. Auditlog API
      4. Authentication API
      5. Cluster API
      6. Common API
      7. Content API
      8. Context API
      9. Event API
      10. Export API
      11. Grid API
      12. I18N API
      13. IO API
      14. Mail API
      15. Node API
      16. Portal API
      17. Project API
      18. Repo API
      19. Scheduler API
      20. Schema API
      21. Tasks API
      22. Value API
      23. VHost API
      24. Websocket API
      1. Webapp Engine
        1. Image service
        2. Component service
      2. Universal API Engine
      3. Media API
      4. Admin Engine
      5. Asset service
      6. HTTP service
      7. IDprovider service
    1. Task engine
    2. Management Endpoint
    3. Statistics Endpoint
    1. Nodes and repos
    2. Properties
    3. Indexing
    4. Branches
    5. Queries (NoQL)
    6. Queries (DSL)
    7. Filters
    8. Aggregations
    9. Highlighting
    10. Editors
    1. Strategies
    2. Distributions
    3. Docker image
    4. Vhosts
    5. Configuration
    6. Backup & restore
    7. Systemd
    8. Clustering
  3. Audit Logs
    1. Upgrade Notes
    2. Upgrading Apps

Upgrading applications from XP 7 to XP 8

Contents

This section describes the steps required to upgrade an XP application from 7.x to 8.0

This section is only relevant when upgrading from XP 7 to XP 8.

Preparations

Before you start the upgrade procedure:

  • Make sure you have Enonic CLI installed

  • Check out the project source code to a local folder i.e. myapp/

Create a sandbox

To create the sandbox, go to your project folder and run the following command:

enonic project sandbox

When the command is completed successfully, the sandbox will be associated with your project. This enables us to build, deploy and test the application.

Using Git? Enonic CLI adds a .enonic file to your project root, consider updating your .gitignore file with the following entry:

### Enonic ###
.enonic

Build system

The standard build system used for XP projects must be updated.

Gradle Wrapper

XP 8.0 standardizes on the use of Gradle 9.x. We recommend bundling Gradle wrapper of version 9.2.1 or later in your project.

For simple installations, from your project root, run:

./gradle wrapper --gradle-version 9.2.1

This will install or update your project with a new Gradle wrapper.

XP Gradle plugins

Application upgrade

If you are upgrading an application, you need to use a version greater or equal to '4.0.0' of the XP Gradle plugin (com.enonic.xp.app).

This plugin expects application properties to be defined in the app {} section of build.gradle and enables quick reference to the Enonic repo via xp.enonicRepo() shortcut

Syntax for adding plugins to Gradle may have changed for your project, we recommend the following updates to your build files:
build.gradle sample
plugins {
    id 'com.enonic.xp.app' version '4.0.0-A2'
}

app {
    name = "${appName}"
    displayName = "${appDisplayName}"
    vendorName = "${vendorName}"
    vendorUrl = "${vendorUrl}"
    systemVersion = "${xpVersion}"
}

dependencies {
    implementation "com.enonic.xp:script-api:${xpVersion}"
    include "com.enonic.xp:lib-content:${xpVersion}"
    include "com.enonic.xp:lib-portal:${xpVersion}"
}

repositories {
    mavenCentral()
    xp.enonicRepo('dev') //TODO 'dev' is only while XP 8.0 is in development
}

Additionally, this is the recommended format for gradle.properties

gradle.properties sample
# Gradle Project settings
projectName = myproject
version = 1.0.0-SNAPSHOT

# XP App values
appDisplayName = My Cool App
appName = com.acme.something.myproject
vendorName = Acme Inc
vendorUrl = https://example.com
xpVersion = 8.0.0-SNAPSHOT #TODO 'dev' is only while XP 8.0 is in development

# Settings for publishing to a Maven repo
group = com.acme.something
appName and appDisplayName are only used for application projects, as well as app config in build.gradle

Library upgrade

If you are upgrading a library, you don’t need to use com.enonic.xp.app plugin or have app {} section in build.gradle. Below is a sample content of build.gradle and gradle.properties files for a library:

build.gradle sample
plugins {
    id 'java'
    id 'maven-publish'
    id 'com.enonic.xp.base' version '4.0.0-A2'
}

repositories {
    mavenCentral()
    xp.enonicRepo('dev') //TODO 'dev' is only while XP 8.0 is in development
}
You only need to use com.enonic.xp.base plugin if you are using XP dependencies and need to shortlink to Enonic repo via xp.enonicRepo() shortcut
gradle.properties sample
group=com.mycompany.lib
projectName=mylib
xpVersion=8.0.0-SNAPSHOT #TODO 'dev' is only while XP 8.0 is in development
version=1.0.0-SNAPSHOT

Verify

After completing the steps above, you should now be able to test that your build is working, using the Enonic CLI:

enonic project deploy

This command proxies the Gradle wrapper, but also connects with the project sandbox. You may also use enonic project build to build without deploying

Projects containing Java code might get build errors at this point, otherwise the build should complete successfully.

Default context

In XP 8 context repository and branch may return null if they are not set. This is a default behavior. Previously the default context was set with com.enonic.cms.default repository and draft branch.

JDK

Java 25 is required for XP 8.0.0

Testing API

If you are using Enonic testing API (com.enonic.xp:testing) You need to add Junit 5 dependency with the corresponding platform launcher.

dependencies {
testImplementation "com.enonic.xp:testing:${xpVersion}"
testImplementation(platform("org.junit:junit-bom:6.0.1"))
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

test {
    useJUnitPlatform()
}

Junit 4 is not supported in XP 8.0.0

API Deprecations and Breaking Changes

Application Descriptor

The application.xml descriptor must be converted to application.yml.

Use the xp8migrator tool to automate the conversion of XML descriptors to YAML.
XP 7 - application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="urn:enonic:xp:model:1.0">
  <description>My app description</description>
</application>
XP 8 - application.yml
description: "My app description"

Admin API

All XML descriptor files must now be converted to YAML (.yml) descriptor files. XML descriptors are no longer supported in XP 8.

Use the xp8migrator tool to automate the conversion of XML descriptors to YAML.

Admin Tool

Admin Tool descriptors must be converted from XML to YAML.

XP 7 - admin/tools/main/main.xml
<?xml version="1.0" encoding="UTF-8"?>
<tool xmlns="urn:enonic:xp:model:1.0">
  <display-name>My Admin Tool</display-name>
  <description>An admin tool</description>
  <allow>
    <principal>role:system.authenticated</principal>
  </allow>
</tool>
XP 8 - admin/tools/main/main.yml
displayName: "My Admin Tool"
description: "An admin tool"
allow:
- "role:system.authenticated"

Widgets / Extensions

Widgets are now part of the Admin Extensions API. The admin/widgets directory has been renamed to admin/extensions, and descriptors must be converted from XML to YAML.

XP 7 - admin/widgets/settings/settings.xml
<widget xmlns="urn:enonic:xp:model:1.0">
  <display-name>Settings</display-name>
  <description>Configure Projects</description>
  <interfaces>
    <interface>contentstudio.menuitem</interface>
  </interfaces>
</widget>
XP 8 - admin/extensions/settings/settings.yml
displayName: "Settings"
description: "Configure Projects"
interfaces:
- "contentstudio.menuitem"

Task

Task descriptors must be converted from XML to YAML.

Task descriptor forms do not support form-fragments.
XP 7 - tasks/mytask/mytask.xml
<?xml version="1.0" encoding="UTF-8"?>
<task xmlns="urn:enonic:xp:model:1.0">
  <description>Background job</description>
  <form>
    <input type="Long" name="count">
      <label>Number of items to process</label>
      <default>42</default>
      <occurrences minimum="1" maximum="1"/>
    </input>
  </form>
</task>
XP 8 - tasks/mytask/mytask.yml
description: "Background job"
form:
- type: "Long"
  name: "count"
  label: "Number of items to process"
  occurrences:
    min: 1
    max: 1
  default: 42

ID Provider

ID Provider descriptors must be converted from XML to YAML.

XP 7 - idprovider/idprovider.xml
<?xml version="1.0" encoding="UTF-8"?>
<id-provider xmlns="urn:enonic:xp:model:1.0">
  <mode>MIXED</mode>
  <form>
    <input name="appClientId" type="TextLine">
      <label>Client ID</label>
      <occurrences minimum="1" maximum="1"/>
    </input>
  </form>
</id-provider>
XP 8 - idprovider/idprovider.yml
mode: "MIXED"
form:
- type: "TextLine"
  name: "appClientId"
  label: "Client ID"
  occurrences:
    min: 1
    max: 1

CMS Schema

All XML descriptor files must now be converted to YAML (.yml) descriptor files. XML descriptors are no longer supported in XP 8.

Use the xp8migrator tool to automate the conversion of XML descriptors to YAML.

Site descriptor split

The site.xml descriptor has been split into two separate files in XP 8:

  • site.yml - contains processors, mappings, and apis

  • cms.yml - contains mixin references (previously x-data) and the site form configuration

Additionally, the site directory has been renamed to cms.

XP 7 - site/site.xml
<?xml version="1.0" encoding="UTF-8"?>
<site xmlns="urn:enonic:xp:model:1.0">
  <x-data name="myapp:my-mixin"/>
  <form>
    <input type="TextLine" name="some-name">
      <label>Textline</label>
      <occurrences minimum="0" maximum="1"/>
    </input>
  </form>
  <processors>
    <response-processor name="filter1" order="10"/>
  </processors>
  <mappings>
    <mapping controller="/controllers/preview.js" order="50">
      <match>type:'.*:person'</match>
    </mapping>
  </mappings>
</site>
XP 8 - cms/site.yml
processors:
- name: "filter1"
  order: 10
mappings:
- controller: "/controllers/preview.js"
  order: 50
  match: "type:'.*:person'"
XP 8 - cms/cms.yml
mixin:
- name: "myapp:my-mixin"
  optional: false
form:
- type: "TextLine"
  name: "some-name"
  label: "Textline"
  occurrences:
    min: 0
    max: 1

Page descriptor

XP 7 - site/pages/main/main.xml
<?xml version="1.0" encoding="UTF-8"?>
<page xmlns="urn:enonic:xp:model:1.0">
  <display-name>Main</display-name>
  <description>Contains a single main region</description>
  <form/>
  <regions>
    <region name="main"/>
  </regions>
</page>
XP 8 - cms/pages/main/main.yml
displayName: "Main"
description: "Contains a single main region"
form: []
regions:
- "main"

Layout descriptor

XP 7 - site/layouts/2-column/2-column.xml
<?xml version="1.0" encoding="UTF-8"?>
<layout xmlns="urn:enonic:xp:model:1.0">
  <display-name>2 columns</display-name>
  <description>Provides left and right regions</description>
  <form/>
  <regions>
    <region name="left"/>
    <region name="right"/>
  </regions>
</layout>
XP 8 - cms/layouts/2-column/2-column.yml
displayName: "2 columns"
description: "Provides left and right regions"
form: []
regions:
- "left"
- "right"

Part descriptor

XP 7 - site/parts/my-part/my-part.xml
<?xml version="1.0" encoding="UTF-8"?>
<part xmlns="urn:enonic:xp:model:1.0">
  <display-name>My Part</display-name>
  <description>A simple part</description>
  <form>
    <input name="title" type="TextLine">
      <label>Title</label>
      <occurrences minimum="1" maximum="1"/>
    </input>
  </form>
</part>
XP 8 - cms/parts/my-part/my-part.yml
displayName: "My Part"
description: "A simple part"
form:
- type: "TextLine"
  name: "title"
  label: "Title"
  occurrences:
    min: 1
    max: 1

Content type

XP 7 - site/content-types/article/article.xml
<?xml version="1.0" encoding="UTF-8"?>
<content-type xmlns="urn:enonic:xp:model:1.0">
  <display-name>Article</display-name>
  <super-type>base:structured</super-type>
  <form>
    <input name="title" type="TextLine">
      <label>Title</label>
      <occurrences minimum="1" maximum="1"/>
    </input>
  </form>
</content-type>
XP 8 - cms/content-types/article/article.yml
superType: "base:structured"
displayName: "Article"
form:
- type: "TextLine"
  name: "title"
  label: "Title"
  occurrences:
    min: 1
    max: 1

X-data renamed to Mixin

X-data has been renamed to Mixin in XP 8. The x-data directory should be renamed to mixins, and descriptor files updated accordingly.

XP 7 - site/x-data/myattachment/myattachment.xml
<?xml version="1.0" encoding="UTF-8"?>
<x-data>
  <display-name>My Attachment</display-name>
  <form>
    <input name="myAttachment" type="AttachmentUploader">
      <label>My Attachment</label>
      <occurrences minimum="1" maximum="1"/>
    </input>
  </form>
</x-data>
XP 8 - cms/mixins/myattachment/myattachment.yml
displayName: "My Attachment"
form:
- type: "AttachmentUploader"
  name: "myAttachment"
  label: "My Attachment"
  occurrences:
    min: 1
    max: 1

Mixins renamed to Form Fragments

Mixins (XP 7) have been renamed to Form Fragments in XP 8. The mixins directory should be renamed to form-fragments.

XP 7 - site/mixins/address/address.xml
<?xml version="1.0" encoding="UTF-8"?>
<mixin xmlns="urn:enonic:xp:model:1.0">
  <display-name>Address</display-name>
  <form>
    <input type="TextLine" name="street">
      <label>Street</label>
      <occurrences minimum="0" maximum="1"/>
    </input>
  </form>
</mixin>
XP 8 - cms/form-fragments/address/address.yml
displayName: "Address"
form:
- type: "TextLine"
  name: "street"
  label: "Street"
  occurrences:
    min: 0
    max: 1

Macro

Macro descriptors must be converted from XML to YAML.

XP 7 - site/macros/my-macro/my-macro.xml
<macro>
  <display-name>Current user</display-name>
  <description>Shows currently logged user</description>
  <form>
    <input name="defaultText" type="TextLine">
      <label>Default text</label>
    </input>
  </form>
</macro>
XP 8 - cms/macros/my-macro/my-macro.yml
displayName: "Current user"
description: "Shows currently logged user"
form:
- type: "TextLine"
  name: "defaultText"
  label: "Default text"
  occurrences:
    min: 0
    max: 1

DateTime and Instant input types

The XP 7 DateTime input type with <timezone>true</timezone> has been split into a separate Instant type in XP 8. DateTime is now used exclusively for local date-time values (without timezone), while Instant represents a point in time.

XP 7 - DateTime with timezone (XML)
<input name="publishDate" type="DateTime">
  <label>Publish date</label>
  <config>
    <timezone>true</timezone>
  </config>
</input>
XP 8 - Instant (YAML)
- type: "Instant"
  name: "publishDate"
  label: "Publish date"
XP 7 - DateTime without timezone (XML)
<input name="eventDate" type="DateTime">
  <label>Event date</label>
</input>
XP 8 - DateTime (YAML)
- type: "DateTime"
  name: "eventDate"
  label: "Event date"

HTTP Controllers

HTTP controller method names have been changed to uppercase to avoid conflicts with JavaScript reserved words and imported library methods.

The lowercase method names (get, post, delete, etc…​) are deprecated but still supported for backward compatibility. It is recommended to migrate to the new uppercase names (GET, POST, DELETE, etc…​).

The all function remains lowercase and has not been changed to uppercase.
XP 7 (deprecated but still works in XP 8)
exports.get = function(req) {
    return {
        body: 'Hello World',
        contentType: 'text/plain'
    };
};

exports.post = function(req) {
    // Handle POST
};

exports.delete = function(req) {
    // Handle DELETE
};

exports.all = function(req) {
    // Handle all other methods
};
XP 8 (recommended)
exports.GET = function(req) {
    return {
        body: 'Hello World',
        contentType: 'text/plain'
    };
};

exports.POST = function(req) {
    // Handle POST
};

exports.DELETE = function(req) {
    // Handle DELETE
};

exports.all = function(req) {
    // Handle all other methods
};

HTTP Services

HTTP Services are deprecated. Universal API should be used instead.

Old services
src/
  main/
    resources/
      services/
        coolservice/
          coolservice.xml
          coolservice.js
      myservice/
        myservice.js
        myservice.xml
New APIs
src/
  main/
    resources/
      apis/
        coolservice/
          coolservice.yml
          coolservice.js
        myservice/
          myservice.js
          myservice.yml
Old service.xml
<service>
  <allow>
    <principal>role:system.admin</principal>
  </allow>
</service>
New api.yml
allow:
  - "role:system.admin"

In order for API to work on admin tool, site or webapp, it must be mounted via the descriptor.

Example of mounting "coolservice" API in an admin tool
displayName: "My Admin Tool"
allow:
  - "role:system.admin"
apis:
  - "coolservice"

Assets service

Assets service has been deprecated since XP 7.15 Use lib-asset instead.

TODO: Do we remove assets service?

lib-admin

getAssetsUri method is removed. This method was never in use since XP 7.

getBaseUri method is removed. Use getHomeToolUrl instead as a drop-in replacement.

getLocale method is removed without replacement. This method was causing issues when first user preference did not match any localization files and English was chosen as default.

getLocales method is removed. Use request.locales instead.

getPhrases method is removed. Use lib-i18n getPhrases instead.

getLauncherUrl and getLauncherPath methods are removed. Launcher is a widget now and available via widgets API.

lib-admin no longer depends on lib-portal. You need to explicitly add lib-portal dependency to your project if you are using it.

XP 7

dependencies {
    include "com.enonic.xp:lib-admin:${xpVersion}"
}

XP 8

dependencies {
    include "com.enonic.xp:lib-admin:${xpVersion}"
    include "com.enonic.xp:lib-portal:${xpVersion}"
}

lib-node

_inheritsPermissions node property is removed. It can only be used as an argument in create method - to copy permissions from the parent node.

setRootPermissions method is removed. Use applyPermissions instead.

modify method is deprecated. Use update instead.

editor of deprecated modify method can no longer edit node permissions. Use separate call to applyPermissions method instead.

lib-content

setPermissions method is removed. Use applyPermissions instead.

applyPermissions method applies permissions on published and draft content simply.

editor of deprecated modify method can no longer edit content permissions. Use separate call to applyPermissions method instead.

modify method is deprecated. Use update instead.

modifyMedia method is deprecated. Use updateMedia instead.

delete method is renamed to deleteContent to avoid conflicts with the JavaScript reserved word. The old delete export is still available for backward compatibility, but it’s recommended to use the new name directly.

XP 7

import {delete as deleteContent} from '/lib/xp/content';

XP 8

import {deleteContent} from '/lib/xp/content';

lib-project

delete method is renamed to deleteProject to avoid conflicts with the JavaScript reserved word. The old delete export is still available for backward compatibility, but it’s recommended to use the new name directly.

XP 7

import {delete as deleteProject} from '/lib/xp/project';

XP 8

import {deleteProject} from '/lib/xp/project';

lib-repo

delete method is renamed to deleteRepo to avoid conflicts with the JavaScript reserved word. The old delete export is still available for backward compatibility, but it’s recommended to use the new name directly.

XP 7

import {delete as deleteRepo} from '/lib/xp/repo';

XP 8

import {deleteRepo} from '/lib/xp/repo';

create method settings param is removed. This was a direct exposure of internal implementation details.

lib-scheduler

delete method is renamed to deleteJob to avoid conflicts with the JavaScript reserved word. The old delete export is still available for backward compatibility, but it’s recommended to use the new name directly.

XP 7

import {delete as deleteJob} from '/lib/xp/scheduler';

XP 8

import {deleteJob} from '/lib/xp/scheduler';

lib-i18n

localize method no longer accepts application parameter - because application load order is not guaranteed, trying to load foreign application localization might fail. Required localize phrases should be copied over the applications instead.

lib-task

submitNamed method is removed. Use submitTask instead.

submit method is removed. Use executeFunction instead.

lib-auth

login method idProvider parameter now defaults to system if not provided, instead of trying all available id providers. It is also not possible to specify multiple values anymore. This change ensures consistent id provider selection during login.

lib-context

run method context.user.idProvider parameter now defaults to system if not provided, instead of trying all available id providers.

lib-export

exportNodes

includeNodeIds and includeVersions parameters are removed.

Exports are now stored as ZIP archives. The output file is named {exportName}.zip in the exports directory, replacing the previous folder-based structure.

Folder-based exports from XP 7 should be converted to a ZIP archive before they can be imported in XP 8.

Javax to Jakarta

Most of the Java EE APIs have been migrated to Jakarta EE APIs. For instance javax.servlet is replaced with jakarta.servlet.

Jetty was updated to version 12.x and now uses Jakarta EE APIs.

FasterXML Jackson JSON API

Java FasterXML Jackson JSON API is no longer a transitive dependency of XP Core API.

If you need to serialize or deserialize JSON in Java, you need to add the dependency to your project, preferably using a library different from XP internal one (FasterXML Jackson) to avoid conflicts.

FasterXML Jackson Annotations com.fasterxml.jackson.core:jackson-annotations transitive dependency is still available in JAX-RS API.

JAX-RS API

Java JAX-RS API is deprecated. It was not documented and used internally to implement legacy REST APIs.

If you have used JAX-RS API in your application, you need to migrate to the new XP 8 Universal API.

To know if you are using JAX-RS API, check for com.enonic.xp:jaxrs-api dependency in the project’s Gradle file.

Dropwizard Metrics

Java Dropwizard Metrics is no longer available in XP Core API. Migrate to com.enonic.xp.metrics Core API.

Java APIs

There are many changes in Java APIs, multiple classes were moved or renamed, as well as their methods. The intention was to keep JavaScript API as compatible as possible, while improving Java API design and removing unnecessary or confusing methods and classes.

The most noticeable changes are:

  • Java methods and classes marked as @Deprecated were removed.

  • Many classes and methods that were only used for internal implementation details and not intended for public use were removed.

  • Methods that had names that could cause confusion with JavaScript API we renamed, for instance ContentService.deleteWithoutFetch renamed ContentService.delete.

  • Classes that have direct replacement in Java 25 standard library were removed.

  • ContentService.update method was split into 3 separate methods: ContentService.update, ContentService.updateMedia and ContentService.updatePermissions.

  • Java Portal View Functions are no longer part of XP Core API. They were incorporated into lib-thymeleaf and lib-xslt libraries.

  • com.enonic.xp.page.DescriptorKey moved to com.enonic.xp.descriptor.DescriptorKey.

  • Concrete collection types like LinkedList, HashMap, etc. were replaced with corresponding interfaces like List, Map, etc.

  • Javax Mail is no longer a transitive dependency of XP Core API.

  • OSGi classes are no longer part of API. OSGi is still used internally in XP.


Contents

Contents

AI-powered search

Juke AI