Proper Portlet Name for your Portlet components...

Okay, this is probably going to be one of my shortest blog posts, but it's important.

Some releases of Liferay have code to "infer" a portlet name if it is not specified in the component properties.  This actually conflicts with other pieces of code that also try to "infer" what the portlet name is.

The problem is that they sometimes have different requirements; in one case, periods are fine in the name so the full class name is used (in the portlet component), but in other cases periods are not allowed so it uses the class name with the periods replaced by underscores.

Needless to say, this can cause you problems if Liferay is trying to use two different portlet names for the same portlet, one that works and the other that doesn't.

So save yourself some headaches and always assign your portlet name in the properties for the Portlet component, and always use that same value for other components that also need the portlet name.  And avoid periods since they cannot be used in all cases.

So here's an example for the portlet component properties from one of my previous blogs:

@Component(
  immediate = true,
  property = {
    "com.liferay.portlet.display-category=category.system.admin",
    "com.liferay.portlet.header-portlet-css=/css/main.css",
    "com.liferay.portlet.instanceable=false",
    "javax.portlet.name=" + FilesystemAccessPortletKeys.FILESYSTEM_ACCESS,
    "javax.portlet.display-name=Filesystem Access",
    "javax.portlet.init-param.template-path=/",
    "javax.portlet.init-param.view-template=/view.jsp",
    "javax.portlet.resource-bundle=content.Language",
    "javax.portlet.security-role-ref=power-user,user"
  },
  service = Portlet.class
)
public class FilesystemAccessPortlet extends MVCPortlet {}

Notice how I was explicit with the javax.portlet.name?  That's the one you need, don't let Liferay assume what your portlet name is, be explicit with the value.

And the value that I used in the FilesystemAccessPortletKeys constants:

public static final String FILESYSTEM_ACCESS =
  "com_liferay_filesystemaccess_portlet_FilesystemAccessPortlet";

No periods, but since I'm using the class name it won't have any collisions w/ other portlet classes...

Note that if you don't like long URLs, you might try shortening the name, but stick with something that avoids collisions, such as first letter of packages w/ class name, something like "clfp_FilesystemAccessPortlet" or something. Remember that collisions are bad things...

And finally, since I've put the name in an external PortletKeys constants file, any other piece of code that expects the portlet name can use the constant value too (i.e. for your config admin interfaces) and you'll know that all code is using the same constant value.

Enjoy!

Blogs
Is there any way to give ID to the portlet on top of name?

I have checked https://dev.liferay.com/es/develop/reference/-/knowledge_base/7-0/portlet-descriptor-to-osgi-service-property-map and didn't find so most probably there isn't, I guess...

Basically I want to add portlet to a page programatically. I know there is a method which does this by portlet ID but not by name. Hence if I have to use that method, then first iterate through all the portlets, find by name and then keep ID and add them.

If there is a way to get ID of the portlet easily then it would be easier.