在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
相关产品推荐
相关产品推荐

