Liferay migration. Real examples. Step-by-step instructions. Screens.
Introduction
The article is written by mutual efforts of Vitaliy, Senior Liferay Developer, and Julia, Writer.
While people are still hotly debating on the buzz that Liferay is going to terminate supporting CE edition, many of you are probably on the way of upgrading your Liferay portal. Otherwise, you wouldn’t read this article.
Let’s list some key benefits of Liferay 7.1 CE release for developers:
- Streamlined and modular architecture makes Liferay 7.1 simpler.
- It is leaner that facilitates deployment.
- You can compose and reuse modules with a modular development paradigm.
- Reusability of services is available with CLP mechanism.
- Extensions are simpler, easier to maintain, more dynamic. Optimized for your tooling of choice.
- Configure your code with an auto-generated UI System Settings just on the go.
These improvements of Liferay 7.1 are tempting. Below, I’ll give you a tutorial on how to migrate data and code from Liferay 6.2 to 7.1 to make your upgrading process a piece of case.
Table of contents:
- I. Prerequisites: description of demo project and data/content to be migrated.
- II. Prepare for migration: recommendations on Liferay 6.2 migration, Liferay 7.1 installation/configuration, tools and instruments.
- III. Database migration: steps and tips for database migration.
- IV. Code migration: steps and tips for code migration.
- V. Post-migration issues: steps required after migration completed.
- VI. Common errors during migration: possible errors, which may occur during the migration process, and solutions to fix them.
I. Prerequisites
As the majority of our projects are under NDA and I can’t share with you no client’s project, therefore, I had to create a demo project to show you screenshots with visual illustrations of Liferay migration to 7.1. It contains a custom theme, layout, portlet, and hook. Also, I configured a set of pages and web content on the portal so that you can see it on practice.
While choosing a repository, usability always goes a long way for me. Therefore, I favored Bitbucket to deploy an original Liferay 6.2 code. I’d recommend this repository for many reasons. It allows creating unlimited private repositories, works well for sharing demo projects and collaboration of small dev teams. And then on top of it, we just like with guys to try some new hyping stuff in Liferay development, why not?
As somebody who is already familiar with default Liferay modules, you’re not going to surprise these four examples to be migrated:
- aimprosoft-portlet — a custom portlet for displaying a list of web contents, documents, wiki pages, documents and blogs from the portal;
- aimprosoft-theme — a custom theme (based on classic one) with 2 color schemes (orange and blue) and 2 theme settings (‘split-dockbar’ and ‘navigation-enabled’);
- 1-3-column-layouttpl — a custom layout;
- aimprosoft-hook — a JSP hook for the Sign In portlet to display a greeting message.
To demonstrate the migration of web content structures, I took “technology” and “portfolio” pages:
- “Technology”, fields: “header”, “logo”, “description”.
- “Portfolio”, fields: “header”, “icon”, “description”, “link”.
Well, there are two types of pages to be aware of: public and private. All pages in the Liferay portal are part of sites. They differ in access. All users can see public pages, but private ones are reachable only to authorized members of the site. It’s one on the main idea of Liferay in creating a closed collaborative environment for members of one single organization.
So, I chose the most popular pages which are the starting point in using the portal and I’m comfortable with.
Public pages:
- Welcome
- Portfolio
- Technologies



Private pages:
- Wiki
- Forum
- Blog
- Content Viewer




II. Prepare for migration
Liferay 6.2 preparations before migration
Before migrating, let’s do a little housekeeping. We need to clear data from old versions, duplicates and other unnecessary files. Then do not forget to download Liferay 7.1 CE at this step.
Remove unused objects
To speed up the migration process, and also to increase the performance of the portal after migration, we need to remove unused objects (Layouts, Users, Documents, etc.). Liferay procreates intermediate versions of web contents and documents every time the content is edited. For example, if we have web content updated three times, there are four different versions:

The portal always contains multiple contents with old versions. Instead of this bulk of files, it’s sensible to migrate only the last one (1.3). Three featured ones can be removed. Thus, we can facilitate migration time and reduce the volume of moving data.
Sure, you can do it manually if you have sufficient time for it. But I like fast actions; therefore, I used Liferay API that allows working with objects (to extract from the database, check, or delete, if needed). Liferay API for documents and API for web content will give you a piece of relief. You will need only to write a piece of code to do it.
Remove duplicated structure names
If you have different web content structures (text, images, links, checkboxes, etc.) in your portal, they are likely to have fields with the same names. It’s OK for Liferay 6.2, but migration to 7.x will fail because Liferay DMX requires having unique names of fields. Therefore, we need to rename structure fields, so they are unique overall the portal.
Liferay 7.1 installation/configuration
First of all, download Liferay 7.1 from open source apps and software directory SourceForge. Liferay was seen to cover needs beyond a basic CMS like WordPress, Joomla or Drupal. That’s why the founders chose SourceForge to make the code reachable for the people right away. And I like that.

Unpack Liferay archive but do not start it for now.
Tools/instruments
There are different tools/plugins to work with Liferay 7.x. It depends on which IDE you work with, which tool to use. Personally, IIntelliJ IDEA. If you use IDEA too, you can install Liferay IntelliJ Plugin for it. Eclipse, NetBeans, SlickEdit are also good, but sometimes they aren’t always reliable, lag and not scalable enough. With IDEA I can set up a project easier.
It allows you to setup Liferay workspace, configure Liferay server, create different modules from templates, deploy them, etc. For those, who work in Eclipse, there is Liferay Developer Studio and Liferay IDE. Although I’m not a fan of Eclipse, I have to admit that it has better integration with Liferay and more opportunities even for code migration process. I will refer to a subject later.
III. Liferay Database migration
This paragraph involves migration steps of Liferay database.
Prepare database for migration
- Create a separate database for migration in MySQL:
create database lr_migration_dxp character set utf8
- Create a database dump from 6.2 database and load it to new one:
mysqldump -uroot -p1 lr_migration > lr_migration.sql
mysql -uroot -p1 lr_migration_dxp < lr_migration.sql
- Specify database connection properties
Create file ‘portal-setup-wizard.properties’ with the DB connection properties inside:
jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost:3306/lr_migration_dxp
jdbc.default.username=root
jdbc.default.password=1
Note: DO NOT START Liferay instance right now. Otherwise, you’ll get an error like this:
2018-09-26 13:44:57.402 ERROR [main][MainServlet:273] java.lang.RuntimeException:
I couldn’t ignore it and first had to upgrade to Liferay Portal 7100
java.lang.RuntimeException:
Then you must first upgrade to Liferay Portal 7100
at com.liferay.portal.tools.DBUpgrader.checkRequiredBuildNumber(DBUpgrader.java:87)
(See errors list at the end).Copy data
To transfer document library files to the new environment, copy document_library and image folders into the data folder from Liferay 6.2 to Liferay 7.1. The migrated data will be stored in the default store. A location you can choose up to you.Disable indexer and autoUpgrade
Since we are going to start to upgrade process in our new installation, we have to disable indexing and create files for this. I did it to prevent reindexing content and performance issues from arising.
I added a file com.liferay.portal.search.configuration.IndexStatusManagerConfiguration.config to my folder [Liferay Home]/osgi/configs with the following content:
indexReadOnly=”true”
Then I added a file com.liferay.portal.upgrade.internal.configuration.ReleaseManagerConfiguration.config to the same folder [Liferay Home]/osgi/configs with autoUpgrade=”false” content.
Now indexing is completed and we can proceed with configuration.
Configure the upgrade tool
Unlike previous Liferay versions, where we had just to specify database configuration properties, and Liferay performed upgrade process during the startup, Liferay 7.x comes with a dedicated tool for database upgrade ‘portal-tools-db-upgrade-client’ in LR/tools folder.
We need to configure the following files before running the upgrade:



We should check a release buildNumber before running the upgrade tool because it is incremented by Liferay after each deployment in Service Builder which is used for generating internal database persistence code.

It should be 62xx before you run the upgrade.
Running the upgrade tool
Here we invoke the upgrade tool with the script ./db_upgrade.sh -l for Linux and “db_upgrade.log” for Windows. This will update Liferay core and output this message after finishing:

Then run the command upgrade:executeAll to execute all pending module upgrade processes. Gogo Shell will allow you to do it appearing on the screen. To launch Felix Gogo Shell, you need to execute command “telnet localhost 11311” in the command line.
Finally, just wait for a while to see the desired message after updating all the modules are completed:
Verification is executed in the core automatically. You need to check out a buildNumber to ensure portal has been updated successfully:

Enabling indexer
The most important step of post-upgrade is enabling indexer. To do this I modified the file com.liferay.portal.search.configuration.IndexStatusManagerConfiguration.config in the folder [Liferay Home]/osgi/configs with the following content:
indexReadOnly=”false”
Good job, dudes. You’re almost at the end. Now let’s start Liferay.
Starting LiferayWe’ve been working really hard. Start Liferay and ensure that the database has been updated successfully. The database migration should be finished at this point. In the next chapter, I will describe you how to make a code migration. It’s time to say a few words about Liferay migration process automation.
Liferay migration process automationAlthough there are not too many steps to perform the migration; it still requires a lot of manual work with configuration files, creation/restore dumps, copying files, etc. Moreover, if there are any errors during migration, you need to perform all these actions again and again from the beginning.
To automate this process, I have created a bash script which performs all the actions above. It’s available here. You just need to specify your properties as it is showed below:
Properties
#MySQL
db_user=root
db_password=1
#LR 6.2
lr62_path=/home/vitaliy/Work/Liferay/migration/liferay-6.2-ce-ga4/liferay-portal-6.2-ce-ga4
lr62_db_name=lr_migration
#LR 7.1
lr71_path=/home/vitaliy/Work/Liferay/migration/liferay-ce-7.1.0-ga1
lr71_archive=liferay-ce-portal-tomcat-7.1.0-ga1-20180703012531655.zip
lr71_dir=liferay-ce-portal-7.1.0-ga1
lr71_db_name=lr_migration_dxp
Have you got it? I’m sure, yes. So now run the script ./migrate.sh.

After finishing the script database and data should be already migrated. You can start your Liferay 7.1 instance and check the results.
What I’ve got is a virgin Liferay portal now so pure and beautiful:

Although there is still no custom theme, layout, hook changes; all the data (pages, content, etc.) is in place, and we can start with code migration.
IV. Code migration
For code migration, you need to set up a project environment. I use IntelliJ IDEA IDE with Liferay IntelliJ Plugin, Liferay 7.1 bundled with Tomcat, Maven for assembling, and MySQL as a database. All the instructions below are relevant for this stack.
IDE setup
I like this Liferay’s liberal position about tools choice. It’s up to a developer what tool to choose for generating and managing the project. Liferay’s default Gradle management system doesn’t suit me perfectly. So I preferred Maven. There are several Maven plugins with artifacts which I can use for module development. A Liferay Workspace works well to create and manage a structure for folds and files built with Maven.
First, I created a new Liferay project using Liferay Maven Plugin:


When you have a new project done, you will see the following structure displayed:

Go on with configuring a Liferay server in IDE as I did:

Congrats! Now you can start Liferay 7.1 portal from IDE.
Liferay theme migration
Before starting theme migration, we should consider the main points which were changed in Liferay 7.1:
- Velocity templates are no longer supported in favor of FreeMarker;
- Dockbar has been replaced with different menus: Product Menu, Control Menu, User Personal Bar.
Ways to update theme:
yo liferay-theme:import Note: this way works only for themes, created with Ant-base Liferay plugin SDK. Otherwise, such exception will appear:
- Run Gulp upgrade task to upgrade the theme:
yo liferay-theme:import
Note: this way works only for themes, created with Ant-base Liferay plugin SDK.
Otherwise, such exception will appear:
If you don’t’ like a dry sense of humor by Darth Vader, just follow my tips.
While upgrade tool automates the migrations process, there are still restrictions for theme structure.
- Manual theme creation and code transfer
Although it’s not an automatic process and needs some efforts. Sometimes it’s easier to create a theme from scratch in 7.1 and apply appropriate styling from 6.2 given changes in Liferay between those versions.
Well, let’s try to create a new theme using Liferay plugin:


Score! Now you’ve got an empty, but working theme created. After this, we can apply changes from 6.2 theme taking into account changes in 7.1.
As in version 6.2, we can also use a classic theme as an example and overwrite required sections (FTL templates, CSS files, etc.).
Liferay portlet migration
To migrate portlet code, I used the Code Upgrade Tool in Liferay Developer Studio (Project -> Liferay Code Upgrade Tool menu). After importing project we can click “Find breaking changes” button, and a list of code problems will appear:

Each of them contains API changes explanation, which affects custom code, reasons for it, links to Liferay JIRA tickets, examples and recommendations to fix code issues. Some of code problems can be fixed automatically using Liferay IDE, other ones need manual actions.

After fixing all the issues, you can try to build the portlet for Liferay 7.1. If you work in IntelliJ IDEA, you can copy migrated code to it from Liferay IDE.
Liferay hook migration
For hook migration (especially for JSP hooks) it’s better to create a hook module from scratch and overwrite the required JSP page. As Liferay’s JSP pages have changed significantly from Liferay 6.x to 7.x, using old 6.2 JSP pages for new 7.1 Liferay may break some functionality.
So, you need to create a hook module, find appropriate JSP, and overwrite it in hook, copying changes from 6.2.
To find what exactly was changed in hook, you can compare 2 JSP files in your Liferay 6.2 instance, xxx.jsp (hooked one) and xxx.portal.jsp (original one). In my example:

Then just apply these changes to your Liferay 7.1 page and deploy the hook.
Liferay layout migration
For layout migration we can create a new layout with Liferay IntelliJ plugin:


After that we can adjust FTL template according to the 6.2 code, for example:

Now you are free to change an icon for layout, deploy the layout, and use it.
V. Post-migration issues
After migration to 7.1 make sure that an indexer is enabled. Modify file com.liferay.portal.search.configuration.IndexStatusManagerConfiguration.config in [Liferay Home]/osgi/configs with content:
indexReadOnly=”false”
Also, you need to set up a standalone Elasticsearch instance that can index Liferay Portal’s content. Installed by default as an embedded service it can be used for local development, but not for production. I’m not going in how to install Elasticsearch in this article. You can get the details here.
Let’s elaborate on some typical errors you may face during migration.
VI. Common errors during migration
I summed up a list of errors that may occur during migration to 7.1.
1. You must first upgrade to Liferay Portal 7100
Name |
java.lang.NullPointerException at |
StackTrace |
ERROR [main][MainServlet:273] java.lang.RuntimeException: You must first upgrade to Liferay Portal 7100 |
Description | Exception is thrown, when Liferay 7.x is started with 6.x database before running upgrade tool |
Fix | Run upgrade tool before starting Liferay 7 |
2. NullPointer when upgrading DDM
Name |
com.liferay.portal.kernel.upgrade.UpgradeException: |
StackTrace |
com.liferay.portal.kernel.upgrade.UpgradeException: |
Description | The exception is thrown when there are orphaned templates (w/o structures) |
Fix | Delete such templates in 6.2 before migration to 7.1 |
LPS |
https://issues.liferay.com/browse/LPS-82417 |
If the issue still exists after migration, you can prevent the NPE if you start Liferay from IDEA in debug mode. Then run the upgrade process from Felix Gogo Shell and change the value in evaluator:

3. NullPointer when missing theme
Name |
java.lang.NullPointerException at |
Screen |
![]() Image 34. How to fix Liferay NullPointer missing theme |
StackTrace |
com.liferay.portal.kernel.events.ActionException: |
Description | Null pointer is thrown, when there is missing theme |
Fix | Deploy missing theme |
4. PwdEncryptorException: invalid keyLength value
Name |
PwdEncryptorException: invalid keyLength value |
StackTrace |
com.liferay.portal.kernel.exception.PwdEncryptorException: invalid keyLength value |
Description | Exception is thrown when there is specified incorrect password encryption algorithm |
Fix |
Add this property |
The bottom line
As you can see, it’s not that complicated to migrate Liferay 6.2 to 7.1 for competent Liferay developers. In this article, we’ve overviewed the process of migration for a demo project. For those who have a portal with needs beyond a simple static website, we can help with Liferay portal migration. Me or one of my senior colleagues can consult you on Liferay development solutions. Just drop us a line.
Frequently Asked Questions
When should I migrate to the higher version?
How long does it take to migrate Liferay?
How many resources (RAM/HDD) Liferay needs?
What is the latest Liferay version?
You may also want to read