• Your project is updated with the changes that happened between 4.5 and 5.
  • You have a task in your version handler for each migration task covered by the migration tool.
  • You have a task in your version handler for each custom migration task that is not covered by the migration tool.


Follow this process for migrating from 4.5 to 5:

  1. Update project dependencies to match 5.x dependencies.
  2. Update deprecated code if your IDE turns red. 
  3. For all the topics you identified in your analysis.
    • Add the corresponding migration tasks in the version handler of your modules as shown below.
    • Create your own migration tasks for things that are not covered by the migration tool such as defining a custom workflow.
  4. Start Magnolia for the first time on the saved repository and check the migration result.
  5. Improve your version handler by adding post-migration tasks. For example, grant permissions to the apps that were created during Data module migration.
  6. Add tasks to remove old configuration such as the Extended Templating Kit (ETK) module.
  7. Test your migration tasks again on the saved repository until your are happy with the result.
  8. Test your migration tasks with data from production.
  9. Build your WAR file.

Update project dependencies

What changed:

  • Some group and artifact IDs changed.

How to migrate:

  •   Update dependencies in your project POM file to match the changed group and artifact IDs. 

Update group IDs

Group IDs of the following artifacts have changed. Update dependencies in your project POM. 

ArtifactOld group IDNew group ID
CE bundleinfo.magnoliainfo.magnolia.bundle
Enterprise webappsinfo.magnoliainfo.magnolia.eebundle
CE bundle dependency in POM
Enterprise webapp dependency in POM

Update module artifact IDs

Artifact IDs of the following modules have changed. Update dependencies in your project POM. 

ModuleOld nameNew name
Multisiteextended-templating-kit magnolia-module-multisite
Module dependency in POM

Update deprecated code

If your IDE turns red, update the deprecated code. Enable warnings on deprecated API. Here is an example from Eclipse.


Deprecated code to look for:

  • DAM asset manipulation. See Migrate DMS to DAM below.
  • Command  interface changed. 
  • Old workflow code

Migrate dialog definitions

What changed:

How to migrate:

  1. If you have custom save handlers, replace them with a custom action or a custom property transformer.
  2. If you have custom controls, replace them with an existing Vaadin field or create a custom field. See Concept - Dialog Migration from 4.5.x to 5.x for scenarios and code examples.
  3. Add a dialog migration task to your version handler.

    DialogMigrationTask in version handler
    .addTask(new DialogMigrationTask("your_module_name"));

Migrate metadata to mixin node types

What changed:

  • Metadata used to be stored in subnodes. It was replaced with special mixin node typesThis change was implemented in the Magnolia node type definition.
  • Same name sibling nodes are no longer allowed. 

How to migrate:

  1. If you have custom code the uses JCR queries to search for metadata such as metaData/template, rewrite these queries.
  2. The Magnolia core module contains a metadata migration task that is triggered during the update. You don't need to add it to your version handler.

    ConvertMetaDataUpdateTask in version handler
    .addTask(new ConvertMetaDataUpdateTask("Convert meta data", "Done on all workspaces."))
  3. Same name sibling nodes are no longer allowed. This restriction was implemented in the Magnolia node type definition. The migration tool performs this update automatically for all Magnolia workspacesIf you have custom workspaces, add the following task to your version handler.

    IdentifySameNameSiblingNodesTask in version handler
    .addTask(new IdentifySameNameSiblingNodesTask("your_custom_workspace", "/", "nt:base"));

    The task accepts the following attributes:

    • workspace : Your custom workspace name.
    • path : A valid path in the workspace. Use / to find everything under the workspace root.
    • node type : A valid JCR node type. The query goes through all node types but the results are filtered to the type you specify. Use nt:base as a "wildcard".

For details and usage examples see Concept - metaData content & nodeTypeDefinition migration task.

Migrate DMS to DAM

What changed:

  • New module magnolia-dam replaced the magnolia-module-dms module.
  • New workspace dam replaced the dms workspace.
  • All assets such as images and videos should now be stored in the DAM. There is no possibility to store an asset directly in website content by uploading it directly or by uploading in the CKEditor.

How to migrate:

Example: DAM API usage

Old codeNew Code



stkFunctions.getAssetLink(yourNode, "photoProperty");

// First inject in your constructor:

DamTemplatingFunctions damFunctions

// Then

String assetIdentifier = PropertyUtil.getString(recipe, "photoDAM");


[#if model.caption??]${model.caption}[/#if]

The behavior of the asset returns by ImageModel.getImage() has changed, it does not look at Metadata stored in the content node anymore (such as imageCaption) but only those on the asset node in the DAM.

In this example, model.caption uses ImageModel.getImage() to retrieve the underlying asset. The template must be updated:

[#if content.imageCaption?? || model.caption??]${content.imageCaption!model.caption}[/#if]
  • Add the migration tasks shown below into your version handler. The tasks will:
    • Move assets from dms workspace to dam workspace.
    • Move assets from website workspace to dam workspace.
    • Move uploaded assets to dam workspace.
    • Update UUID references so they point to the asset's new location.
    • Update permissions (ACLs) from DMS to DAM.

(warning) The example tasks below are for a typical website where binary content resides all over the place: in the DMS, in the website and in the FCKEditor. You may not need to add all these migration tasks in your version handler. See Usage of the DMS to DAM migration task for a complete list of tasks.

DAM migration tasks in version handler
	new IsModuleInstalledOrRegistered("Migrate DMS Repository 1", "Migrate only if DMS is installed", "dms", new MoveDataWorkspaceToDamMigrationTask(
		"Migration task: Migrate DMS content to DAM", "Migrate DMS to DAM", Arrays.asList("/resto"), null, "dms")))
	new IsModuleInstalledOrRegistered("Migrate DMS Repository 2", "Migrate only if DMS is installed", "dms", new ChangeWebsiteDmsReferenceToDamMigrationTask(
		"Migration task: Migrate Identifier ID to point to DAM", "", "website", Arrays.asList("/home"))))
/* This task takes assets from the website workspaces stored at path /restaurant to the dam workspace at path /moved_uploaded */
	new MoveContentToDamMigrationTask("Migration task: Migrate Uploaded content to DAM repository", "", "website", Arrays.asList("/restaurant"), "/moved_uploaded", null))
	new MoveFCKEditorContentToDamMigrationTask("Migration task: Migrate Uploaded content to DAM repository", "", "website", Arrays.asList("/home"), "/moved_uploaded_fck", null))
    new UpdateDamAssetFileNamePropertiesTask("Migration task: Aggregate file name and extension", ""))
    new MoveLinkToDamForFCKEditorContentMigrationTask("Migration task: Update FCK editor links from dms to dam.", "", "website", Arrays.asList("/home"), null))
	new CleanContentForDamMigrationTask("Migration task: Clean Content repository", "", "website", Arrays.asList("/home")))
	new MoveAclPermissionsBetweenWorkspaces("Move ACL define for the DMS workspace to the DAM workspace", "", "dms", DamConstants.WORKSPACE, null, false))

Post-migration task:

  • Organize your DAM assets. The migration tool moves assets from the website workspace to the DAM. The structure created by the migration tool follows the old website workspace structure, which is probably not what your editors expect. Go to the DAM app and re-organize the assets in a way that makes sense.
  • The old dms workspace and its configuration are still present. We recommend that you check that all the configuration and assets are correctly moved and then remove the old workspace and configuration with a dedicated task in the version handler.

Recreate workflow

What changed:

  • jBPM workflow engine replaced the OpenWFE engine. You need to recreate any custom workflow definitions you have.

Before you start:

How to create a new workflow definition:

  • See Workflow on how to work with the new jBPM workflow engine.

Replace custom data types with content apps

What changed:

  • The Data module should not be used anymore. Replace your custom data types with content apps.

  • Magnolia has already replaced the demo data types (Contact, Company, RSS, Category) with content apps.

How to migrate:

  1. The Data module will create a new content app for each of your custom data types during the update.
    • It stores the new app configuration in /modules/data/apps.
    • It stores the app data in the data workspace.
  2. If you used images from the DMS with your data items:
    1. Move the images to the dam workspace with MoveDataWorkspaceToDamMigrationTask.
    2. Update the references in the data workspace with ChangeWebsiteDmsReferenceToDamMigrationTask.
  3. If you used images that were uploaded and stored in the website workspace using the dam control:
    1. Use MoveContentToDamMigrationTask to move the images to the DAM.
  4. If you have JCR queries in your code, rewrite them.
  5. If you have custom menu items in AdminCentral that display pages, replace the pages with content apps or standard apps. You need to create the apps yourself.


Data migration tasks in a version handler
// Data migration
// Needed because images are now stored in the DAM and references must be updated.
.addTask(new ChangeWebsiteDmsReferenceToDamMigrationTask("Migration task: Migrate Identifier ID to point to DAM", "Of Data module", "data", Arrays.asList("/recipe")))

// Move images from data workspace to dam.
.addTask(new MoveContentToDamMigrationTask("Migration task: Move image of Recipe from Data To Dam", "Migrate Data to DAM", "data", Arrays.asList("/recipe"), "/moved_from_data", null))
// Extra migration tasks
// If you have custom data types, this is how you would migrate them.
// Imagine that you stored food recipes in a custom data type and displayed them on the site.
// Move recipes to a new recipe workspace.
// Extend info.magnolia.ui.contentapp.setup.AbstractDataTypeMigrationTask
.addTask(new RecipeDataMigrationTask())

// Update ACLs
.addTask( new AddPermissionTask("Add all permission to superuser for the recipe workspace","","superuser","recipe","/",info.magnolia.cms.security.Permission.ALL,true))

// Update content app and dialogs that are linked to a data type
// Content App Recipe
.addTask( new CheckAndModifyPropertyValueTask("Update workspace for the Recipe App.","For browser/workbench",RepositoryConstants.CONFIG,"/modules/data/apps/recipeApp/subApps/browser/workbench","workspace","data","recipe"))
.addTask( new CheckAndModifyPropertyValueTask("Update path for the Recipe App.","For browser/workbench",RepositoryConstants.CONFIG,"/modules/data/apps/recipeApp/subApps/browser/workbench","path","/recipe","/"))
.addTask( new CheckAndModifyPropertyValueTask("Update workspace for the Recipe App.","For recipe subapp",RepositoryConstants.CONFIG,"/modules/data/apps/recipeApp/subApps/recipe/editor","workspace","data","recipe"))

// Update dialog of Recipe component
// Move app to this module
.addTask (new CreateNodeTask("Create app node for miami-restaurant-demo-site-config", "",  RepositoryConstants.CONFIG, "/modules/miami-restaurant-demo-site-config", "apps", NodeTypes.Content.NAME))
.addTask( new MoveNodeTask("Move Recipe app to miami-restaurant-demo-site-config", "", RepositoryConstants.CONFIG, "/modules/data/apps/recipeApp", "/modules/miami-restaurant-demo-site-config/apps/recipeApp", true));


Post-migration tasks:

Once the migration task are completed, you can work with your data in content apps. But you can make the migration even better.

Starting with Magnolia 5.4, the Data module is no longer included. If for any reasons you still have a dependency to this module after the migration, you must update your pom file to explicitly include this module in your project. It can be the case if you decided to not migrate your import handlers.

Clean up obsolete configuration and workspaces

After the update to 5 you still have obsolete configuration for the DMS and ETK modules. We recommend that you verify that everything is moved to its new place and then remove the configuration with info.magnolia.module.delta.RemoveNodeTask.

Move ACLs

If you move content from one workspace to another, add a task in your version handler to grant permissions to the new content, for example:

.addTask(new MoveAclPermissionsBetweenWorkspaces("Move ACL define for the DMS workspace to the DAM workspace", "", "dms", DamConstants.WORKSPACE, null, false))

You then also need a dependency to magnolia-security-app:

Module dependency in POM

When you replace AdminCentral pages with content apps, convert the ACLs:

.addTask(new ConvertAclToAppPermissionTask("Convert permissions for 'Categories' app", "Convert ACL permissions for old 'Categories' menu to new 'category' app permissions.", "/modules/adminInterface/config/menu/data/category", "/modules/categorization/apps/categories", true))

Next step

11. Test migration to 5


  1. This article doesn't explicitly say that, but before starting DMS -> DAM tasks, you need to

    1. Install the DMS module in the new Magnolia instance
    2. (Maybe) create an app showing the old DMS browser
    3. Export data to XML on old Magnolia and import on the new one

    Is that correct? If so, maybe you could add this to the article.


    1. Your Magnolia 4.5 must have the DMS module installed for technical reasons. Even if you don't have any assets managed by the DMS in 4.5.

      In Magnolia 5, you should not have any DMS module, since you have removed its dependency. See 10Migratefrom45to5-UpdatemoduleartifactIDs

      However, the DMS workspace will still be available, but it should be empty.

  2. Possible lack of information in Update group IDs

    Is it possible that you forgot to mention that the bundled webapp now has a new id info.magnolia.bundle ?

    Would be great to complete the documentation!

    1. Hi Yann, CE bundle group ID changed in Magnolia 5.2. Added to Update group IDs section. Thanks for noticing!

  3. "This change was implemented in the Magnolia node type definition." look above in the page, the link to node type definition is broken

    1. Thank you Daniele for spotting this one. 
      I have fixed the link to the node type definition.