You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Liferay网页内容中使用staticUtil服务触发FreeMarker错误求助

解决FreeMarker中获取ServiceContext时的ClassNotFoundException问题

你在Liferay的FreeMarker模板里尝试获取ServiceContext时碰到的类加载问题,我帮你分析下原因并给出可行的解决方案:

问题根源

这个java.lang.ClassNotFoundException是Liferay模块类加载器隔离机制导致的:com.liferay.portal.template.freemarker模块的类加载器没办法直接访问com.liferay.portal.kernel.service.ServiceContext类(该类属于kernel模块),直接用staticUtil调用会触发跨模块的类加载权限限制。

解决方案

方案1:直接从ThemeDisplay获取ServiceContext(推荐)

既然你本来就要获取ThemeDisplay,其实它本身就持有ServiceContext的引用,完全不用绕ThreadLocal的路子,直接用下面的写法就行:

<#assign serviceContext = themeDisplay.getServiceContext() />

这种方式既简洁,又能避开类加载的权限问题,是Liferay模板里获取ServiceContext的标准做法。

方案2:使用portalClassInvoker工具类调用静态方法

如果你确实需要通过ServiceContextThreadLocal来获取,建议用Liferay专门为模板提供的portalClassInvoker工具类,它能正确处理跨模块的类加载逻辑:

<#assign serviceContext = portalClassInvoker.invokeStaticMethod(
    "com.liferay.portal.kernel.service.ServiceContextThreadLocal",
    "getServiceContext",
    []
) />

额外提示:如果只是对比页面标题,无需ServiceContext

你的最终目的是对比页面标题,其实直接从ThemeDisplay关联的布局对象里就能拿到页面标题,根本不需要ServiceContext:

<#assign currentPageTitle = themeDisplay.getLayout().getTitle(themeDisplay.getLocale()) />

<!-- 标题对比的示例逻辑 -->
<#if currentPageTitle == "目标页面标题">
    <p>当前是目标页面</p>
<#else>
    <p>当前不是目标页面</p>
</#if>

内容的提问来源于stack exchange,提问作者designershyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:06:11