Liferay: Converting 6.2 Portlets to 7.1 Part 2. The Service
Created: 7 June 2019 Modified:
Now we focus on converting the service layer. This targets legacy code that doesn’t meet the requirements as discussed in Liferay From 6.2 to 7.1: The Model is the key to Services, Security and Search. Before we get started, lets discuss the two different types of services. There are local services and remote services. Local services are designed to have access to the database, provide little security and are only used in the Java code. These types of interfaces and classes are easily recognizable as they are named <Model Name>LocalService.java and <Model Name>LocalServiceImpl.java. Remote services are designed to access local services, have security in place and can be accessed two ways. It can be accessed via Java code and Web Services. These classes are named <Model Name>Service.java and <Model Name>ServiceImpl.java. We will focus on local services. Remote services will bed addressed, in a following article.
Converting Liferay 6.2 local services can be broken down into the following steps.
Pick a package path for the new code.
Gather Information: servletContextName, schema version number and full path model names.
Create your new Service builder project.
Update pom.xml to stop version increments and to set version. Also adjust merging of model hints.
Migrate service.xml
Run service builder
Migrate over customizations from 6.2
Make BundleActivator class, update bnd file and update pom.xml.
Make UpgradeStep class
Make Upgrade Class
Migrate over model hints.
My old service package path was com.codeexcursion.application.feeds.service. For the new one I went with com.codeexcursion.application.myapplication. This is also the package I will use for MyApplication-Web. Note: Changing the package of the models in the service layer led to extra code and difficulties. Namely entries in the ClassName_ and Counter tables.
Now we need to find the servlet context and schema version for our service. In your Liferay deployment go to the Tomcat webapps directory for Liferay 6.2 and find the servlet context. Ours is myApplication-portlet. We now connect to the database and run query as shown below. Record the schemaVersion and servletContextName. If no results are returned, record 0.0.1 for the schemaVersion and the servlet context found on the file system.
Database Query for Info
To gather the model names we will need to look in the 6.2 service project. In this case it would be the myApplication/myApplication-portlet-service/src/main/java/. In subfolders will be the models from the old project. There will be subfolders matching the package-path in the service.xml. In this case our models are com.codeexcursion.application.feeds.service.model.Location and com.codeexcursion.application.feeds.service.model.Newsfeed.
File -> New -> Liferay Module Project. Enter the new module name “MyApplication-Service”. Verify the location is correct for your modules.Select build type Maven and Liferay Version 7.1. For project template we will choose service-builder. Click Next and enter your package path. Click the Finish button.
Next we edit the pom.xml for MyApplication-Service-service. Change the buildNumberIncrement to false and add a version number. You will also need to update the service.properties file. Also we have added additional relative paths to mergeModelHintsConfigs. This is so any changes manually made to portlet-model-hints.xml will be preserved even if we run the service builder build from the first two parent directories. The relative directory list should be comma separated and must be all on one line.
We can now copy over information from our old service.xml to our new service.xml. Make sure that our new package path is used. The majority of entity definitions can be copied over with no changes.
The generated code in MyApplication-Service-Api will likely remain untouched. As shown in Part 1 the cutomizable impl files will be in MyApplication-Service-service. Copy the code from 6.2 and modify as needed for 7.1. Keep in mind that your import statements will be different and that your IDE may insert the wrong ones as you copy from 6.2 to 7.1. Most likely the only differences in 7.1 will be the import statements.
Now we need to add the bundle activator class. First we need to add dependencies to our pom.xml.
We will need the servlet context and package path from earlier. The servlet context will be your old symbolic name and the package path appended with “.service” will be your new symbolic name. The namespace will be the namespace from our service.xml. The class should be placed in a package that is the package path appended with “.activator”.
MyApplicationServiceBundleActivator.java
Once our bundle activator class is complete we need to add a reference to it in our bnd.bnd file. Add an entry for Bundle-Activator.
Adding the upgrade step class is next. Remember my my decision to change the package path? The Counter and ClassName_ upgrade are only necessary because of that decision. The counter upgrade is only applicable for legacy tables with an int or long as a primary key. MyApplication has one table that meets this criteria. This updates the counter service that produces the primary key values. Next we will update the models names in for class name service. MyApplication has two tables and both should be updated. First we will need to find the full package path for our model from the 6.2 service builder project. This is com.codeexcursion.application.feeds.service.model.Location and com.codeexcursion.application.feeds.service.model.Newsfeed. The upgrade step code should be placed in the package path appended with “.upgrade”.
Note: The most reliable way to find the old model name is to query the Counter and ClassName_ tables. You can also go into the code in the old 6.2 service project.
MyApplicationUpgradeStep.java
I left the upgrade step code, above, as is to illustrate the process. In practice it should, and has, been abstracted out to reusable classes.
Next is our upgrade class. This class will go into the same package as the previous class and will use the schema version we acquired earlier. It will also use the previous class. If you didn’t need the previous class you can replace it with the DummyUpgradeStep class.
MyApplicationUpgrade.java
Finally we copy over the model hints for our service. The legacy copy will be in a similar location under myapplication-portlet.