Некоторое время назад возникла необходимость в обновлении зависимостей портлета, работающего под 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>
Надеюсь, вам это окажется полезным.
Засим откланиваюсь, прощайте.