legacy-knowledge-base
公開されました Sep. 10, 2025

NullPointerException in getArticleDisplay without a ThemeDisplay

written-by

Cristina Rodriguez

How To articles are not official guidelines or officially supported documentation. They are community-contributed content and may not always reflect the latest updates to Liferay DXP. We welcome your feedback to improve How To articles!

While we make every effort to ensure this Knowledge Base is accurate, it may not always reflect the most recent updates or official guidelines.We appreciate your understanding and encourage you to reach out with any feedback or concerns.

legacy-article

learn-legacy-article-disclaimer-text

Issue

After upgrading to Liferay DXP 7.4 2025.Q1.0 or a newer version, calling the JournalArticleLocalService.getArticleDisplay() method for a Journal Article located in the Global Site fails if the themeDisplay parameter is null. This issue commonly occurs in headless scenarios or background tasks where there is no page context.

The following NullPointerException is thrown:

com.liferay.portal.kernel.exception.SystemException: java.lang.NullPointerException: Cannot invoke "com.liferay.portal.kernel.theme.ThemeDisplay.getScopeGroupId()" because "themeDisplay" is null
    at com.liferay.journal.service.impl.JournalArticleLocalServiceImpl.getArticleDisplay(JournalArticleLocalServiceImpl.java:6669)
    at com.liferay.journal.service.impl.JournalArticleLocalServiceImpl.getArticleDisplay(JournalArticleLocalServiceImpl.java:2427)
    ...
Caused by: java.lang.NullPointerException: Cannot invoke "com.liferay.portal.kernel.theme.ThemeDisplay.getScopeGroupId()" because "themeDisplay" is null
    at com.liferay.journal.service.impl.JournalArticleLocalServiceImpl.getArticleDisplay(JournalArticleLocalServiceImpl.java:6609)
    ... 104 more

Environment

  • Liferay DXP 7.4 2025.Q1.0+

Resolution

This behavior is a side effect of a fix introduced in version 2025.Q1.0 (LPD-42349). When rendering content from the Global Site, a ThemeDisplay object is now required to correctly resolve the scope, for instance, when a template from a specific site is used to display the global content.

There are two ways to resolve this issue:

Recommended Approach: Use Headless API

The recommended approach for fetching rendered content is to use the Headless Delivery API. This API handles the necessary context creation internally. Use the following endpoint:

GET /o/headless-delivery/v1.0/structured-contents/{structuredContentId}/rendered-content/{contentTemplateId}

Here, structuredContentId corresponds to the article's resourcePrimKey, and contentTemplateId is the DDM template's templateKey.

Alternative: Create a Minimal ThemeDisplay

If you must continue using the Java API, the workaround is to create a minimal ThemeDisplay object and pass it to the method call. The crucial part is to set the correct context, especially the scopeGroupId.

  • Examples:
    • Headless API class RenderedContentValueUtil.java includes a private method that creates a themeDisplay, you can use it as reference.
    • Below is an example of how to create and populate a minimal ThemeDisplay object:
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.model.Company;

// ...

ThemeDisplay themeDisplay = new ThemeDisplay();

// Fetch necessary objects like user and company
User user = _userLocalService.getDefaultUser(companyId);
Company company = _companyLocalService.getCompany(companyId);

// The scopeGroupId is the most critical parameter. It should be the groupId
// of the site where the content is intended to be displayed.
long scopeGroupId = 12345L; // Example site groupId

themeDisplay.setUser(user);
themeDisplay.setCompany(company);
themeDisplay.setScopeGroupId(scopeGroupId);

// Set other properties if your template requires them
themeDisplay.setSignedIn(true);
themeDisplay.setLanguageId("en_US");

// Make the API call with the newly created themeDisplay object
JournalArticleDisplay articleDisplay = _journalArticleLocalService.getArticleDisplay(
    article, article.getDDMTemplateKey(), "VIEW",
    LocaleUtil.toLanguageId(locale), 1, null, themeDisplay);

String articleContent = articleDisplay.getContent();


Additional Information

 

did-this-article-resolve-your-issue

legacy-knowledge-base