JBoss GateIn Portal, Spring Webflow and Primefaces

Foreword

I previously wrote a blog A working sample with JBoss Portal – Spring Webflow – Primefaces how to make Jboss Portal 2.6.4 with Spring Web Flow and Primefaces function together. The versions of those mentioned libraries in that blog are now quite outdated. It is time to update the libraries and also tell what is changed.

If you are curious why I wrote the previous blog and this one, it is better that you read the motivations chapter of that blog.

If you are done that, first thing you will discern, JBoss Portal implementation does not exist in the same form, JBoss merged with Exo GateIn Portal to its application server and now it exist with the name of JBoss GateIn Portal and as a consequence several core mechanics are also changed.

Further JBoss Portal was using JSF 1.2 as JSF implementation and Portlet Spec 1.0 wasn’t designed too much in consideration that it should co-exist with JSF technology, so many things were too clunky.

Luckily with Portlet Spec 2.0 and JSF 2, people who are designing those specs saw the problems and make sure that those two technology stacks are now much more compatible.

For those above reasons, I decided it is a good time to update that blog to reflect what is changed. There are still quite lot of hits to that blog page so I am guessing people does still need solutions for the problems caused from this technology stack.

Most of things from the blog are still valid, like project structure, maven usage, git, use cases of the feasibility application and I will not to go too detailed to these subject, you can still look for the old blog for those.

What is mainly changed is that project become much more light weight now that these technologies are much more compatible.

If you get the project from here as it defined in the previous blog Git but this time you have to clone the following branch from the repository.

git clone -b PF_SWF_UPDATE git@github.com/mehmetsalgar/jbp_swf_primefaces.git

Project Structure
Below you see the new Project Structure.

ps_jbp
picture 1

If you look to the previous blog, due to improvements in GateIn Portal, Spring Web Flow and Primefaces several artifacts are disappeared and removed from Git Repository. Thanks to improvement in the technology stacks project structure is much more cleaner now.

That off course doesn’t mean there are no problems, in the next section you will see the problems I discovered and my solutions for those problems.

Challenges

Challenge 1 – web.xml

Naturally with so many change in the technology stack we have to start with the web.xml.

One major change is how our Comet/Push mechanism configured, which is necessary one of our use case.

	<servlet>
		<servlet-name>Push Servlet</servlet-name>
		<servlet-class>org.primefaces.push.PushServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
		<!-- http://forum.primefaces.org/viewtopic.php?f=10&t=38078 -->
		<init-param>
			<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
			<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
		</init-param>
		<init-param>
			<param-name>org.atmosphere.useNative</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<description>Force Atmosphere to use WebSocket. (default: true)</description>
			<param-name>org.atmosphere.useWebSocket</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<description>Force Atmosphere to use WebSocket + Servlet 3.0 API. (default: false)</description>
			<param-name>org.atmosphere.useWebSocketAndServlet3</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<description>Switching to Blocking I/O instead of asynchronous servlets</description>
			<param-name>org.atmosphere.useBlocking</param-name>
			<param-value>true</param-value>
		</init-param>
		<async-supported>true</async-supported>
	</servlet>
	<servlet-mapping>
		<servlet-name>Push Servlet</servlet-name>
		<url-pattern>/primepush/*</url-pattern>
	</servlet-mapping>

Snippet 1

This is the critical part of the web.xml and most of the changes from the previous version of the blog lies here.

If we like to analyze the critical changes, Primefaces 5.2 uses Atmosphere Framework 2.x and there are some major changes in the framework, the followings are the critical setting for atmosphere framework to function correctly and improve performance.

	<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
	<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>

Snippet 2

Following configuration is necessary to force Atmosphere framework not to work in native IO mode (web sockets) but blocking IO. JBoss EAP and JBoss 7 has problems with Web Sockets. Solving those problems were not a primary focus for this article (but I will do it in a future article) so I disable it for the purpose of this blog and our project will use Blocking IO.

Websockets on paper will be more performant and will scale better but I used in another production application Blocking IO and it has an acceptable performance level.

	<init-param>
	       <param-name>org.atmosphere.useNative</param-name>
	       <param-value>false</param-value>
	</init-param>
	<init-param>
		<description>Force Atmosphere to use WebSocket. (default: true)</description>
		<param-name>org.atmosphere.useWebSocket</param-name>
		<param-value>false</param-value>
	</init-param>
	<init-param>
		<description>Force Atmosphere to use WebSocket + Servlet 3.0 API. (default: false)</description>
		<param-name>org.atmosphere.useWebSocketAndServlet3</param-name>
		<param-value>false</param-value>
	</init-param>
	<init-param>
		<description>Switching to Blocking I/O instead of asynchronous servlets</description>
		<param-name>org.atmosphere.useBlocking</param-name>
		<param-value>true</param-value>
	</init-param>

Snippet 3

We also need the Gatein Servlet class mapped so it can intercept the call to the portlets application.

	<servlet>
		<servlet-name>GateInServlet</servlet-name>
		<servlet-class>org.gatein.wci.api.GateInServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>GateInServlet</servlet-name>
		<url-pattern>/gateinservlet</url-pattern>
	</servlet-mapping>

Snippet 4

Challenge 2 – Spring Webflow Configuration
With better implementation of Portlet Spec 2.0 and JSF 2, some elements that are necessary to configure the Spring Web Flow in previous technology stack became obsolete.

Spring Web Flow is in the following application context file configured.

   tech_demo/src/main/webapp/WEB-INF/config/web-application-config.xml

Snippet 5

If we analyze the configuration elements one by one.

	<!-- Spring MVC -->
	<!-- Maps portlet modes to handlers -->
	<bean id="portletModeHandlerMapping"
		class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
		<property name="portletModeMap">
			<map>
				<entry key="view">
					<bean class="org.salgar.techdemo.flowhandler.TechdemoFlowHandler" />
				</entry>
			</map>
		</property>
	</bean>

Snippet 6

This configuration tells Spring Web Flow which flow configuration it must read. Normally, without the Portal Engine Spring Web Flow will read from URL which flow is intended for the user but while the Portlet Engine masking the real urls from the Spring Web Flow and JSF, we have to state here explicitly which flow should be executed when this portlet is called.

If you observe the TechdemoFlowHandler java class, you will see that class points for the ‘demo’ flow.

	<!-- Enables FlowHandler -->
	<bean class="org.springframework.webflow.mvc.portlet.FlowHandlerAdapter">
		<property name="flowExecutor" ref="flowExecutor" />
	</bean>

	<!-- Maps logical view names selected by the url filename controller to .jsp view templates within the /WEB-INF directory -->	
	<bean id="internalJspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<!-- Maps logical view names to Facelet templates (e.g. 'search' to '/WEB-INF/search.xhtml' -->
	<bean id="faceletsViewResolver"
		class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".xhtml" />
	</bean>
	
	<!-- WebFlow -->
	<faces:resources />
	
	<!-- Webflow Scopes -->
	<bean id="scopeRegistrar" class="org.springframework.webflow.scope.ScopeRegistrar" />
	
	<!-- Executes flows: the central entry point into the Spring Web Flow system -->
	<flow:flow-executor id="flowExecutor">
		<flow:flow-execution-listeners>
			<flow:listener ref="facesContextListener" />
		</flow:flow-execution-listeners>
	</flow:flow-executor>
	
	<!-- Installs a listener that creates and releases the FacesContext for 
		each request. -->
	<bean id="facesContextListener"
		class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

Snippet 7

Above elements are just standard configuration elements from Spring Web Flow and which are nice change from the previous version of the project. With the changes to Portlet Spec 2.0 and JSF 2 most of the special configuration are not necessary anymore.

	<!-- The registry of executable flow definitions -->
	<flow:flow-registry id="flowRegistry"
		flow-builder-services="facesFlowBuilderServices">
		<flow:flow-location path="/WEB-INF/flows/techdemo/demo.xml" />
	</flow:flow-registry>

Snippet 8

One thing specific to our project of course the registry of our Web Flow to Spring, which happens with above snippet. As you can see we registered demo.xml flow definition file.

	<!-- Configures the Spring Web Flow JSF integration -->
	<faces:flow-builder-services id="facesFlowBuilderServices" />

Snippet 9

and one final one for integrating Spring Web Flow and JSF.

Challenge 3 – faces-config.xml
Naturally if we want to integrate Portal Engine and JSF, we have to do something in faces-config.xml also.

	<!-- Install Replacement Factory Objects -->
	<application>
		<!-- Enables Facelets -->
		<view-handler>org.springframework.faces.webflow.context.portlet.PortletViewHandler</view-handler>
	</application>
	<factory>
		<faces-context-factory>org.primefaces.context.PrimeFacesContextFactory</faces-context-factory>
	</factory>

Snippet 10

First thing that catches the eye, is an additional configuration for Spring Webflow and JSF integration. PortletViewHandler tell Spring Web Flow how to handle view correlation between Portal Engine and JSF.

The second entry is necessary for Primefaces to configure itself in the Portal Environment.

	<factory>
		<faces-context-factory>org.primefaces.context.PrimeFacesContextFactory</faces-context-factory>
	</factory>

Snippet 11

without this entry you will see NullPointerException in the server.log file. JSF Framework because of the complex structure of the Technology Stack, is not able to determine the order of the libraries it should initialize and it initialize the default JSF Context Factory. Unfortunately this is not working and we have to explicitly state JSF Engine to initialize the ‘PrimeFacesContextFactory’ first.

Challenge 4 – JBoss GateIn Portal – Spring Web Flow – Primefaces Integration
If you look to the screenshot with project structure, you will see a project called ‘spring-faces-patch’.

This project is quite crucial for JBoss GateIn Portal – Spring Web Flow – Primefaces integration and here is why.

I explained in the previous blog, one of the reason that I build this feasibility study project is because I find Primefaces quite powerful JSF library and I want to figure out that Primefaces will work with Bboss Portal Engine together or not. Primefaces is an Ajax rich framework, so when we try to integrate to a Portal Engine we should respect this fact.

While there is no joined effort from JBoss Gatein or Primefaces to make them compatible, there are some friction points.

Portal Spec 2.0 – JSR 286 defines that Ajax interactions in Portlet environment should act like resources requests. Out of the box JBoss GateIn Portal and Primefaces does not respect this fact. Mainly, JBoss GateIn Portal accept Ajax requests as Portlet resource requests, like CSS files or Javascript files. So we have to configure the Primefaces so that when it build it Ajax requests it should take this into count.

For this purpose I have to prepare a special ‘JbpPortlerFacesContextFactory’ and configure in the faces-config.xml in the ‘spring-faces-patch’. JSF 2 will pickup this file during start of the application and make the necessary changes so Ajax Requests URLs.

This will happen in the following class ‘JbpPortletExternalContextImpl’ and in the method ‘encodePartialActionURL’.

If we look to the implementation of this method.

	public String encodePartialActionURL(String url) {
		Assert.notNull(url);
		PortalActionURL portalActionURL = null;
		try {
			portalActionURL = new PortalActionURL(url);
		} catch(MalformedURLException e) {
			throw new FacesException(e);
		}
		MimeResponse mimeResponse = (MimeResponse) response;
		ResourceURL resourceUrl = mimeResponse.createResourceURL();
		resourceUrl.setParameters(portalActionURL.getParameters());
		return response.encodeURL(resourceUrl.toString());
	}

Snippet 12

Practically we are manipulating the Urls Primefaces tries to create and transform it to Portal Resource Urls.

        ResourceURL resourceUrl = mimeResponse.createResourceURL();

Snippet 13

This ensures that Portal Engine interprets these calls as Ajax calls and inform the Primefaces so it can create partial responses for it.

This project must stated as dependency in our ‘tech-demo’ Maven pom.xml file so during the build process it will be copied to the ‘WEB-INF/lib’ directory, so JSF2 can automatically detect the faces-config.xml file and use our implementation.

Challenge 5 – ACTION – RENDER PHASE of Portlets
One more thing that always cause problems with Portal Engine integration and JSF was always the incompatibilities between the Portlet Lifecylce and JSF Lifecycle. Mainly problem occurs because of the Action and Render phase of the Porlet Lifecyle. Portlet Specification states that user events must be processed in the Action phase of the Portlet Lifecycle and no action parameters should be transferred to the Render phase of the Porlet lifecycle.

Unfortunately JSF needs some those parameters to run its own lifecycle. Previously there is no established solution for this problem and we have to implement custom logic for it. Now JBoss GateIn developers saw this problem and implemented a standard solution for it.

For every Portlet application that we will deploy in JBoss GateIn Portal, we need a portlet.xml file and now we have to define in this file the following parameter….

	<container-runtime-option>
		<name>javax.portlet.actionScopedRequestAttributes</name>
		<value>true</value>
	</container-runtime-option>

Snippet 14

This will guarantee that any parameter that is defined in the Action phase will be transferred to the Render phase.

Challenge 6 – Javascript Libraries in GateIn (jquery.js, jquery-pluggins.js, primefaces.js, push.js)
Now we arrived to the problem that caused me the most headache.

As I previously mentioned, Primefaces is really Ajax/Javascript heavy library. For a quite long time I could not make jquery.js, jquery-pluggins.js, primefaces.js and push.js (Primefaces Atmosphere implementation) to work correctly in Jboss GateIn portal.

When I deploy the project as J2EE application in the JBoss GateIn Portal everything worked perfectly but I deployed it in Portal Engine, they were not initializing correctly.

Part of the problem was, in normal JSF application Javascript and CSS files delivered at the head part of the html document but a when a Portlet deployed to a Portal Engine it has no access to the head part of a html document with standard mechanism.

Unfortunately jQuery, Primefaces and Atmosphere javascript files were all using self calling constructors to initialize themselves and these mechanism were not functioning correctly if they are not loaded with script elements inside of the head area of the html document.

Most probably GateIn development team experienced these sort problems before and developed some standard mechanism to place portlet specific javascript files into the header part of the html page.

Before we go further details of this mechanism when I try to implement this solution, I encountered several other problems, I want to mention those and finally explain the final solution.

GateIn Portal to optimize the javascript loading (if several portlets needs the same javascript files only to load one copy of those) and to speed up page render speeds, integrated some special javascript libraries to every portal page.

This is mainly AMD library which helps loading several libraries under different aliases to prevent name collisions and delay javascript file loading at the of the page render to increase performance but unfortunately causes some problems with the above mentioned javascript libraries.

The 2nd mechanism GateIn Portal offers to load the scripts as a in the header part of html page. This one seems the ideal solution for our use case but there is one catch. All the modern javascript libraries I mentioned here are sort of AMD compatible. If they detect the existence of AMD library in the environment they try to initialize themselves with the help of the AMD and unfortunately this is not working in GateIn Portal.

Now, so how GateIn Portal organize the loading of the javascript files. There is a special configuration file called ‘gatein-resources.xml’ which should lie in the WEB-INF directory.

My first tries was to apply the ideal solution and organize the javascript files in AMD fashion with the following configuration.

 <gatein-resources
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_resources_1_3 http://www.gatein.org/xml/ns/gatein_resources_1_3"
    xmlns="http://www.gatein.org/xml/ns/gatein_resources_1_3">
  <module>
    <name>push</name>
    <script>
      <path>/javascripts/push.js</path>
    </script>
    <depends>
      <module>primefaces</module>
    </depends>
  </module>
  <module>
    <name>primefaces</name>
    <script>
      <path>/javascripts/primefaces.js</path>
    </script>
    <depends>
      <module>jquery_plugins</module>
    </depends>
  </module>
  <module>
    <name>jquery_plugins</name>
    <script>
      <path>/javascripts/jquery-plugins.js</path>
    </script>
    <depends>
      <module>jquery_1_11</module>
    </depends>
  </module>
  <module>
    <name>jquery_1_11</name>
    <script>
      <path>/javascripts/jquery_1_11.js</path>
    </script>
  </module>
  <portlet>
    <name>TechDemoPortlet</name>
    <module>
      <depends>
        <module>push</module>
      </depends>
    </module>
  </portlet>
</gatein-resources>

Snippet 15

Which defines, as you may see javascript libraries as modules that will instruct the GateIn Container to initialize those as AMD Modules.

This caused some complications, Primefaces relies heavily in Widget principles. The JSF components, when they are transformed to HTML elements during the render phase, are implemented as widgets. That means during the creation of the html page, javascript must be up and running.

Unfortunately for optimization purposes, GateIn delayed the initialization of javascript files until the end of html tree creation so it was too late for the widget components to create themselves.

So we have to go for other alternative, which is to place this libraries as raw javascripts in the html page head component with the following configuration.

<gatein-resources
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_resources_1_3 http://www.gatein.org/xml/ns/gatein_resources_1_3"
    xmlns="http://www.gatein.org/xml/ns/gatein_resources_1_3">

  <scripts>
    <name>jQuery</name>
    <script>
      <path>/javascripts/jquery_1_11.js</path>
    </script>
  </scripts>
  <scripts>
    <name>jquery-plugins</name>
    <script>
      <path>/javascripts/jquery-plugins.js</path>
    </script>
    <depends>
      <scripts>jQuery</scripts>
    </depends>
  </scripts>
  <scripts>
    <name>primefaces</name>
    <script>
      <path>/javascripts/primefaces.js</path>
    </script>
    <depends>
      <scripts>jquery-plugins</scripts>
    </depends>
  </scripts>
  <scripts>
    <name>push</name>
    <script>
      <path>/javascripts/push.js</path>
    </script>
    <depends>
      <scripts>primefaces</scripts>
    </depends>
  </scripts>
  <portlet>
    <name>TechDemoPortlet</name>
    <scripts>
      <depends>
        <scripts>push</scripts>
      </depends>
    </scripts>
  </portlet>
</gatein-resources>

Snippet 16

In this version instead of defining javascript libraries as Module we define those as simple script elements.

After some testing, I encountered some problems with this option also. These libraries are build so to detect the existence of AMD framework and change their initialization procedure accordingly. Unfortunately for some reason this was clashing with GateIn mechanisms.

So I have to modify in the javascript libraries from this

(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([ "jquery" ], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

Snippet 17

to this

(function( factory ) {
    // Browser globals
    factory( jQuery );

}(function( $ ) {

Snippet 18

which will bypass the AMD initialization mechanism and everything will initialize correctly so Primefaces Widgets can access it.

Of course to be able load my modified version of the scripts, while there is no option in Primefaces to say not to load and execute its own javascripts, I have to manipulate Primefaces artifacts. Which happens in ‘../primefaces-patch/patch-primefaces-assembly’ project.

This Maven project explodes Primefaces artifact, removes jquery.js, jquery-pluggins.js, primefaces.js, push.js and package the artifact again without it.

The ‘tech-demo’ projects Maven POM file must reference ‘patch-primefaces-assembly’ as dependeny instead of primefaces artifact.

Naturally we have to also deliver the modified version of the javascript files which we realized by copying the modified versions to the following directory ”../tech_demo/src/main/webapp/javascripts’.

One side note, I want to mention here, in the gatein-resources.xml, the following element

  <portlet>
    <name>TechDemoPortlet</name>
    <scripts>
      <depends>
        <scripts>push</scripts>
      </depends>
    </scripts>
  </portlet>

Snippet 19

tells to portal container every time this portlet is initialized it should place this scripts to part of the html document.

One more small trick that can be useful for debugging scripts in GateIn Portal, normal portal engine obfuscates and compresses the javascripts which makes them very hard to debug. If you use the following flag ‘-Dexo.product.developing=true’ during the start of the portal, javascripts would not be obfuscated and compressed.

Installation

This feasibility application developed with with JBoss GateIn Portal 6.1.0.Final which you download from the following link.

JBoss GateIn Portal 6.1.0.Final

After you unpack the downloaded package, you will see the following directory…

jboss-jpp-6.1.0/jboss-jpp-6.1/standalone/deployments

You have to place in this directory the artifact..

tech_demo-2.0-SNAPSHOT.war

and when you start the portal with the command…

./standalone.sh

(or standalone.bat in Windows machines)

in the directory…

jboss-jpp-6.1.0/jboss-jpp-6.1/bin

this would start the GateIn Portal.

If you see the following output, that means JBoss GateIn Portal started successfully….

15:52:51,293 INFO [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
15:52:51,293 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
15:52:51,294 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss Portal Platform 6.1.0 (AS 7.2.1.Final-redhat-10) started in 18856ms – Started 1740 of 1888 services (142 services are passive or on-demand)

Now you only have to attach your portlet application to the specific window in JBoss Portal GateIn, you can use the following link

Portlet Deployment

and you can access the feasibility application with the following URL.

http://localhost:8080/portal/classic/

Conclusion:
If you read the previous blog, you would see that it was a bigger fight to JBoss Portal, Spring Webflow and Primefaces to work togehter in the old technology stack, with the new version of the technology stack it became much easier. There are still some hurdles on the way but I would say a professional production quality IT project can be now developed easily on this technology stack.

I hope this feasibility study would help somebody.

Advertisements

About Mehmet Salgar

Mehmet Salgar
This entry was posted in Ajax, Asynchrounus Processing, Atmosphere, Comet, Cygwin, JBoss GateIn Portal, JBoss Portal, JSF, JSR286, Maven, Portlet, Primefaces, Software Development, Spring Web Flow and tagged , , , . Bookmark the permalink.

2 Responses to JBoss GateIn Portal, Spring Webflow and Primefaces

  1. Pingback: A working sample with JBoss Portal – Spring Webflow – Primefaces | Mehmet Salgar's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s