null

Чиним отображение портлетов в Liferay 6.0.5

В текущей версии Liferay 6.0.5 CE есть одна очень раздражающая бага, практически полностью исключающая возможность нормального использования портала. Заключается она в том, что при попытке изменить настройки отображения портлета (убрать рамку, шапку или даже просто заменить заголовок) страница рушится с дикими воплями об ошибках в JSON. Stacktrace привожу полностью, дабы был понятен масштаб бедствия:

	[#|2010-11-11T18:21:12.087+0300|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=20;_ThreadName=httpSSLWorkerThread-40080-0;|18:21:12,083 ERROR [jsp:968] javax.servlet.ServletException: com.liferay.portal.kernel.json.JSONException: org.json.JSONException: A JSONObject text must end with '}' at character 1 of {
javax.servlet.ServletException: com.liferay.portal.kernel.json.JSONException: org.json.JSONException: A JSONObject text must end with '}' at character 1 of {
        at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:939)
        at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:871)
        at org.apache.jsp.html.portal.render_005fportlet_jsp._jspService(render_005fportlet_jsp.java:2020)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
        at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:873)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:723)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:679)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:594)
        at com.liferay.portal.util.PortalImpl.renderPortlet(PortalImpl.java:3723)
        at com.liferay.portal.util.PortalUtil.renderPortlet(PortalUtil.java:1180)
        at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processPortlet(RuntimePortletUtil.java:160)
        at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processPortlet(RuntimePortletUtil.java:94)
        at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processTemplate(RuntimePortletUtil.java:256)
        at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processTemplate(RuntimePortletUtil.java:181)
        at org.apache.jsp.html.portal.layout.view.portlet_jsp._jspService(portlet_jsp.java:815)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
        at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:873)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:723)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:679)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:594)
        at com.liferay.portal.action.LayoutAction.includeLayoutContent(LayoutAction.java:361)
        at com.liferay.portal.action.LayoutAction.processLayout(LayoutAction.java:618)
        at com.liferay.portal.action.LayoutAction.execute(LayoutAction.java:229)
        at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
        at com.liferay.portal.struts.PortalRequestProcessor.process(PortalRequestProcessor.java:152)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
        at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
        at com.liferay.portal.servlet.MainServlet.callParentService(MainServlet.java:508)
        at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:485)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:333)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.java:309)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:182)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:871)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:723)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:558)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:490)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:382)
        at com.liferay.portal.servlet.FriendlyURLServlet.service(FriendlyURLServlet.java:133)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:333)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilte|#]
[#|2010-11-11T18:21:12.088+0300|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=20;_ThreadName=httpSSLWorkerThread-40080-0;|rChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.java:261)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:182)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.i18n.I18nFilter.processFilter(I18nFilter.java:221)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.cache.CacheFilter.processFilter(CacheFilter.java:440)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.etag.ETagFilter.processFilter(ETagFilter.java:45)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.autologin.AutoLoginFilter.processFilter(AutoLoginFilter.java:254)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter.processFilter(NtlmPostFilter.java:81)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.java:179)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.processFilter(VirtualHostFilter.java:239)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
        at com.liferay.portal.servlet.filters.threadlocal.ThreadLocalFilter.processFilter(ThreadLocalFilter.java:35)
        at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:313)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
        at org.apache.catalina.core.ContainerBase.inv|#]
[#|2010-11-11T18:21:12.088+0300|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=20;_ThreadName=httpSSLWorkerThread-40080-0;|oke(ContainerBase.java:1093)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:291)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:666)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:597)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:872)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
        at com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:382)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:264)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: com.liferay.portal.kernel.json.JSONException: org.json.JSONException: A JSONObject text must end with '}' at character 1 of {
        at com.liferay.portal.json.JSONObjectImpl.<init>(JSONObjectImpl.java:69)
        at com.liferay.portal.json.JSONFactoryImpl.createJSONObject(JSONFactoryImpl.java:57)
        at com.liferay.portal.kernel.json.JSONFactoryUtil.createJSONObject(JSONFactoryUtil.java:37)
        at com.liferay.portlet.PortletSetupUtil._toJSONObject(PortletSetupUtil.java:71)
        at com.liferay.portlet.PortletSetupUtil.cssToJSON(PortletSetupUtil.java:40)
        at com.liferay.portlet.portletconfiguration.util.PortletConfigurationUtil.getPortletCustomCSSClassName(PortletConfigurationUtil.java:43)
        at org.apache.jsp.html.portal.render_005fportlet_jsp._jspService(render_005fportlet_jsp.java from :1073)
        ... 188 more
Caused by: org.json.JSONException: A JSONObject text must end with '}' at character 1 of {
        at org.json.JSONTokener.syntaxError(JSONTokener.java:451)
        at org.json.JSONObject.<init>(JSONObject.java:186)
        at org.json.JSONObject.<init>(JSONObject.java:327)
        at com.liferay.portal.json.JSONObjectImpl.<init>(JSONObjectImpl.java:66)
        ... 194 more<

При этом:

1. Бага стабильно воспроизводится на любой странице портала, равёрнутого "вручную" на домене Glassfish'а (v.2.1.1).

2. Бага НЕ воспроизводится на портале из бандла (с Glassfish'ем v.3.0.1).

3. Если вывести контент пресловутого JSON'а, то выясняется, что он состоит из одной открывающей фигурной скобки - в общем, неудивительно, что парсер "ругается".

Многодневное гугление на тему падений JSON-парсера портала ни к чему не привело - судя по всему, народ поголовно использует бандлы, а самостоятельно портал на сервер приложений не ставит. Нам такой вариант не подходит, так что продолжаем искать решение. Вспомнив о том, что JSON пустой, обращаем внимание на эту строчку стектрейса:

	...
at com.liferay.portlet.portletconfiguration.util.PortletConfigurationUtil.getPortletCustomCSSClassName(PortletConfigurationUtil.java:43)
...

Копируем её в строку поиска гугла, и (о, чудо!) получаем ссылку на запись в багтрекере лайфрея с описанием, один в один соответствующим нашей проблеме (правда, на сервере приложений Weblogic - поэтому и большая часть стектрейса не совпадает). Как выясняется, проблема заключается в конфликте версий библиотеки Woodstox, используемых порталом и сервером приложений, вследствие чего портал не может распарсить хранящиеся в XML-формате настройки портлета.

Разработчиком портала проблема хорошо известна и уже достаточно давно исправлена в Enterprise-версии, но пользователям Community Edition приходится решать задачу самостоятельно. К счастью, в той же записи багтрекера опубликованы и изменения, которые нужно внести в код (достаточно исправить всего один класс - com.liferay.portal.xml.StAXReaderUtil):

- private static XMLInputFactory _xmlInputFactory =
- XMLInputFactory.newInstance();
+ private static XMLInputFactory _xmlInputFactory = createXMLInputFactory();
+
+ private static XMLInputFactory createXMLInputFactory() {
+ XMLInputFactory _xmlInputFactory = XMLInputFactory.newInstance();
+ _xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
+ return _xmlInputFactory;
+ } 

После этих модификаций исправленный вариант StAXReaderUtil будет выглядеть так:

/**
 * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */
package com.liferay.portal.xml;

import com.liferay.portal.kernel.util.StringPool;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

/**
 * @author Shuyang Zhou
 * @author Brian Wing Shun Chan
 */
public class StAXReaderUtil {

    public static XMLInputFactory getXMLInputFactory() {
        return _xmlInputFactory;
    }

    public static String read(XMLEventReader xmlEventReader)
            throws XMLStreamException {

        XMLEvent xmlEvent = xmlEventReader.peek();

        if (xmlEvent.isCharacters()) {
            xmlEvent = xmlEventReader.nextEvent();

            return xmlEvent.asCharacters().getData();
        } else {
            return StringPool.BLANK;
        }
    }
    private static XMLInputFactory _xmlInputFactory = createXMLInputFactory();

    private static XMLInputFactory createXMLInputFactory() {
        XMLInputFactory _xmlInputFactory = XMLInputFactory.newInstance();
        _xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
        return _xmlInputFactory;
    }
}

После этого пересобираем Liferay, подсовываем новый portal-impl.jar в библиотеки портала на сервере приложений - и (даже не верится) всё начинает работать нормально! Таким образом, решение для сервера приложений Weblogic одинаково хорошо подходит и для использующих Glassfish v2.

Коротко о себе:

Работаю ведущим программистом в компании Tune IT и ассистентом кафедры Вычислительной техники в Университете ИТМО .

Занимаюсь проектами, связанными с разработкой разного рода веб-приложений (порталы, CRM-системы, системы электронного документооборота), а также, в рамках научной работы на кафедре, изучаю возможности применения семантического анализа в задачах САПР.