null

Использование новых версий Primefaces в Liferay 6.x

Некоторое время назад возникла необходимость в обновлении зависимостей портлета, работающего под Liferay 6.1 на сервере приложений Glassfish 3.1.2 (JSF 2.1). В ходе этого обновления версия Primefaces была обновлена с 5.3 до 6.2. На самый первый взгляд все прошло нормально — несколько страниц успешно отобразились. Лишь затем всплыла странная проблема — при использовании p:commandButton с action'ом возникало следующее исключение: 
java.lang.NullPointerException
	at org.primefaces.config.PrimeConfiguration.initConfigFromContextParams(PrimeConfiguration.java:106)
	at org.primefaces.config.PrimeConfiguration.<init>(PrimeConfiguration.java:82)
	at org.primefaces.context.DefaultApplicationContext.<init>(DefaultApplicationContext.java:41)
	at org.primefaces.context.DefaultRequestContext.getApplicationContext(DefaultRequestContext.java:270)
	at org.primefaces.metadata.transformer.MetadataTransformerExecutor.processEvent(MetadataTransformerExecutor.java:45)
	at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
	at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2168)
	at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:2144)
	at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:302)
	at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:246)
	at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:670)
	at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:812)
	at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:962)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1755)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
	at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
	at com.liferay.faces.bridge.application.ViewHandlerCompatImpl.renderView(ViewHandlerCompatImpl.java:52)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)

Умные люди в интернетах посоветовали обновить Liferay Faces Bridge. ВНЕЗАПНО оказалось, что все предыдущие артефакты (com.liferay.faces:liferay-faces-bridge-impl:3.2.4-ga5 и т.д.) были переименованы, при этом была изменена схема версионирования, а многие классы были перемещены в другие пакеты. Совместимость различных артефактов описана на сайте Liferay. В результате следующие зависимости:

<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>liferay-faces-bridge-impl</artifactId>
    <version>3.2.4-ga5</version>
</dependency>
<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>liferay-faces-portal</artifactId>
    <version>3.2.4-ga5</version>
</dependency>

превратились в такие:

<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>com.liferay.faces.bridge.ext</artifactId>
    <version>2.0.1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>com.liferay.faces.bridge.impl</artifactId>
    <version>3.1.0</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>com.liferay.faces.portal</artifactId>
    <version>2.0.1</version>
</dependency>

Класс com.liferay.faces.portal.bean.Liferay превратился в com.liferay.faces.portal.el.internal.Liferay, а com.liferay.faces.util.portal.WebKeys — в интерфейс om.liferay.portal.kernel.util.WebKeys.

К сожалению, данная конфигурация привела к появлению новой проблемы:

java.lang.UnsupportedOperationException
	at javax.faces.context.ExternalContext.getClientWindow(ExternalContext.java:1500)
	at javax.faces.context.ExternalContextWrapper.getClientWindow(ExternalContextWrapper.java:530)
	at com.sun.faces.renderkit.StateHelper.writeClientWindowField(StateHelper.java:315)
	at com.sun.faces.renderkit.ServerSideStateHelper.writeState(ServerSideStateHelper.java:283)
	at com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:126)
	at com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:113)
	at com.sun.faces.application.view.WriteBehindStateWriter.getState(WriteBehindStateWriter.java:328)
	at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:221)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:473)
	at com.liferay.faces.util.application.view.ViewDeclarationLanguageWrapper.renderView(ViewDeclarationLanguageWrapper.java:78)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
	at com.liferay.faces.bridge.application.internal.ViewHandlerCompatImpl.renderView(ViewHandlerCompatImpl.java:125)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)

Решить ее удалось лишь обновлением версии JSF до 2.2 (замена соответствующей библиотеки в сервере приложений) и соответствующих зависимостей лайфрея.

В итоге были использованы следующие зависимости.

<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>com.liferay.faces.bridge.ext</artifactId>
    <version>2.0.1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.liferay.faces</groupId>
    <artifactId>com.liferay.faces.bridge.impl</artifactId>
    <version>3.1.0</version>
    <scope>runtime</scope>
</dependency>

Надеюсь, вам это окажется полезным.

Засим откланиваюсь, прощайте.