Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!

JBoss

  • submit to reddit

JBoss RichFaces

By Nick Belaevski, Ilya Shaikovsky, Jay Balunas and Max Katz

18,111 Downloads · Refcard 44 of 151 (see them all)

Download
FREE PDF


The Essential JBoss RichFaces Cheat Sheet

JBoss RichFaces is a JSF component library that consists of two main parts: Ajax enabled JSF components and the CDK (Component Development Kit). It allows easy integration of Ajax capabilities into enterprise application development. This DZone Refcard is a great start for any developer looking to learn more about JBoss RichFaces. You will find plenty of examples and code samples that will help with your Rich Internet Applications. This Refcard also covers the following topics: What is RichFaces?, Basic Concepts, Controlling Traffic, Tags, Hot Tips and more.
HTML Preview
JBoss RichFaces

JBoss RichFaces

By Nick Belaevski, Ilya Shaikovsky Jay Balunas, and Max Katz

What is Richfaces?

RichFaces is a JSF component library that consists of two main parts: AJAX enabled JSF components and the CDK (Component Development Kit). RichFaces UI components are divided into two tag libraries a4j: and rich:. Both tag libraries offer out-of-the-box AJAX enabled JSF components. The CDK is a facility for creating, generating and testing you own rich JSF components (not covered in this card).

Installing Richfaces

See the RichFaces Project page for the latest version- http:// www.jboss.org/jbossrichfaces/.

Add these jar files to your WEB-INF/lib directory: richfacesapi. jar, richfaces-impl.jar, richfaces-ui.jar, commons-beanutils.jar, commons-collections.jar, commons-digester.jar, commons-logging.jar

RichFaces Filter

Update the web.xml file with the RichFaces filter:


<filter>
  <display-name>RichFaces Filter</display-name>
  <filter-name>richfaces</filter-name>
  <filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
  <filter-name>richfaces</filter-name>
  <servlet-name>Faces Servlet</servlet-name>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>

Hot Tip

The RichFaces Filter is not needed for applications that use Seam (http://seamframework.org)

Page setup

Configure RichFaces namespaces and taglibs in your XHTML and JSP pages.

Facelets
xmlns:a4j=”http://richfaces.org/a4j”
xmlns:rich=”http://richfaces.org/rich”
JSP
<%@ taglib uri=”http://richfaces.org/a4j” prefix=”a4j”%>
<%@ taglib uri=”http://richfaces.org/rich” prefix=”rich”%>

Hot Tip

Use JBoss Tools for rapid project setup - http://www.jboss.org/tools

Basic Concepts

Sending an AJAX request

a4j:support

Sends an AJAX request based on a DHTML event supported by the parent component. In this example, the AJAX request will be triggered after the user types a character in the text box:

a4j:support

<h:inputText value=”#{echoBean.text}”>
  <a4j:support event=”onkeyup” action=”#{echoBean.count}”
	              reRender=”echo, cnt”/>
</h:inputText>
<h:outputText id=”echo” value=”Echo: #{echoBean.text}”/>
<h:outputText id=”cnt” value=”Count: #{echoBean.textCount}”/></td>

a4j:support can be attached to any html tag that supports DHTML events, such as:

</table>

a4j:commandButton, a4j:commandLink

Similar to h:commandButton and h:commandLink but with two major differences. They trigger an AJAX request and allow partial JSF component tree rendering.

The request goes through the standard JSF life cyle. During the Render Response, only components whose client ids are listed in the reRender attribute (echo, count) are rendered back the the browser.
a4j:support

<h:selectOneRadio value=”#{colorBean.color}”>
  <f:selectItems value=”#{colorBean.colorList}” />
  <a4j:support event=”onclick” reRender=”id” />
</h:selectOneRadio></td>
	
a4j:commandButton, a4j:commandLink

<h:inputText value=”#{echoBean.text}”/>
  <h:outputText id=“echo” value=“Echo: #{echoBean.text}”/>
  <h:outputText id=“cnt” value=“Count: #{echoBean.textCount}”/>
  <a4j:commandButton value=“Submit” action=“#{echoBean.count}”
     reRender=“echo, cnt”/>

Basic Concepts, continued

When the response is received, the browser DOM is updated with the new data i.e ‘RichFaces is neat’ and ‘17’.

New Data

a4j:commandLink works exactly the same but renders a link instead of a button.

a4j:poll

Enables independent periodic polling of the server via an AJAX request. Polling interval is defined by the interval attribute and enable/disable polling is configured via enabled attribute (true|fase).

a4j:poll

<a4j:poll id=”poll” interval=”500” enabled=”#{pollBean.enabled}”
reRender=”now” />
  <a4j:commandButton value=”Start” reRender=”poll”
	 action=”#{pollBean.start}” />
  <a4j:commandButton value=”Stop” reRender=”poll”
	 action=”#{pollBean.stop}” />
  <h:outputText id=”now” value=”#{pollBean.now}” />

a4j:poll

public class PollBean {
	private Boolean enabled=false; // setter and getter
	public void start () {enabled = true;}
	public void stop () {enabled = false;}
	public Date getNow () {return new Date();}
}

a4j:jsFunction

Allows sending an AJAX request directly from any JavaScript function (built-in or custom).

a4j:jsFunction

<td onmouseover=”setdrink(‘Espresso’)”
    onmouseout=”setdrink(‘’)”>Espresso</td>
...
<h:outputText id=”drink” value=”I like #{bean.drink}” />
<a4j:jsFunction name=”setdrink” reRender=”drink”>
<a4j:actionparam name=”param1” assignTo=”#{bean.drink}”/>
</a4j:jsFunction>

When the mouse hovers or leaves a drink, the setdrink() JavaScript function is called. The function is defined by an a4j:jsFunction tag which sets up the AJAX call. It can call listeners and perform partial page rendering. The drink parameter is passed to the server via a4j:actionparam tag.

a4j:push

a4j:push works similarly to a4j:poll; however, in order to check the presence of a message in a queue, it only makes a minimal HEAD request(ping-like) to the server without invoking the JSF life cycle. If a message exists, a sandard JSF request is sent to the server.

Partial view (page) rendering

There are two ways to perform partial view rendering when AJAX requests return.

ReRender attribute

Most RichFaces components support the reRender attribute to define the set of client ids to reRender.

Attribute Can bind to
reRender/td> Set, Collection, Array, comma-delimited String

ReRender can be set statically as in the examples above or with EL:


<a4j:commandLink reRender=”#{bean.renderControls}”/>

Basic Concepts, continued

It’s also possible to point to parent components to rerender all child components:


<a4j:commandLink value=”Submit” reRender=”panel” />
<h:panelGrid id=”panel”>
   <h:outputText />
   <h:dataTable>...</h:dataTable>
</h:panelGrid>

In the example above the child components of the outputPanel will be rerendered when the commandLink is submitted.

a4j:outputPanel

All child components of an a4j:outputPanel will be rerendered automatically for any AJAX request.


<a4j:commandLink value=”Submit” />
<a4j:outputPanel ajaxRendered=”true”>
   <h:outputText/>
   <h:dataTable></h:dataTable>
</a4j:outputPanel>

In the example above the child components of the outputPanel will be rerendered when the commandLink is submitted.

Hot Tip

If ajaxRendered=”false” (default) the a4j:outputPanel behaves just like h:panelGroup.

To limit rendering to only components set in the reRender attribute, set limitToList=”true”. In this example, only h:panelGrid will be rendered:


<a4j:commandLink reRender=”panel” limitToList=”true”/>
<h:panelGrid id=”panel”>
<h:dataTable>...</h:dataTable>
   </h:panelGrid>
<a4j:outputPanel ajaxRendered=”true”>
   lt;h:dataTable>...</h:dataTable>
</a4j:outputPanel>

Deciding what to process on the server

When an AJAX request is sent to the server, the full HTML form is always submitted. However, once on the server we can decide what components to decode or process during the Apply Request, Process Validations and Update Model phases. Selecting which components to process is important in validation. For example, when validating a component (field) via AJAX, we don’t want to process other components in the form (in order not to display error messages for components where input hasn’t been entered yet). Controlling what is processed will help us with that.

The simplest way to control what is processed on the server is to define an AJAX region using the a4j:region tag (by default the whole page is an AJAX region).


<h:inputText>
  <a4j:support event=”onblur” />
</h:inputText>
<a4j:region>
  <h:inputText>
    <a4j:support event=”onblur” />
  </h:inputText>
</a4j:region>

When the user leaves the 2nd input component (onblur event), an AJAX request will be sent where only this input field will be processed on the server. All other components outside this region will not be processed (no conversion/validation, update model, etc). It’s also possible to nest regions:


<a4j:region>
  ...
  <a4j:region>
    ...
  </a4j:region>
</a4j:region>

Basic Concepts, continued

When the request is invoked from the inner region, only components in the inner region will be processed. When invoked from outer region, all components (including inner region) will be processed.

When sending a request from a region, processing is limited to components inside this region. To limit rendering to a region, the renderRegionOnly attribute can be used:


<a4j:region renderRegionOnly=”true”>
   <h:inputText />
   <a4j:commandButton reRender=”panel”/>
   <h:panelGrid id=”panel”>
</a4j:region>
<a4j:outputPanel ajaxRendered=”true”>
   <h:dataTable></h:dataTable>
</a4j:outputPanel>

When the AJAX request is sent from the region, rendering will be limited to components inside that region only because renderRegionOnly=”true”. Otherwise, components inside a4j:outputPanel would be rendered as well.

To process a single input or action component, instead of wrapping inside a4j:region, it’s possible to use the ajaxSingle attribute:

<h:inputText> <a4j:support event=”onblur” ajaxSingle=”true”/> <<

When using ajaxSingle=”true” and a need arises to process additional components on a page, the process attribute is used to include id’s of components to be processed.


<h:inputText>
   <a4j:support event=”onblur” ajaxSingle=”true” process=”mobile”/>
</h:inputText>
<h:inputText id=”mobile”/>


The process can also point to an EL expression or container
component id in which case all components inside the
container will be processed.


When just validating form fields, it is usually not necessary
to go through the Update Model and Invoke Application
phases. Setting bypassUpdates=”true”, will skip these phases,
improving response time, and allowing you to perform
validation without changing the model’s state.


<h:inputText>
  <a4j:support event=”onblur” ajaxSingle=”true”
bypassUpdates=”true”/>
</h:inputText>

JavaScript interactions

RichFaces components send an AJAX request and do partial page rendering without writing any direct JavaScript code. If you need to use custom JavaScript functions, the following attributes can be used to trigger them.

Tag Attributte Description
a4j:commandButton,
a4j:commandLink,
a4j:support,
a4j:poll,
a4j:jsFunction
onbeforedomupdate: JavaScript code to be invoked after
response is received but before browser DOM update
oncomplete: JavaScript code to be invoked after browser DOM
updatedata. Allows to get the additional data from the server
during an AJAX call. Value is serialized in JSON format.
a4j:commandButton,
a4j:commandLink
onclick: JavaScript code to be invoked before AJAX request is sent.
a4j:support,
a4j:poll
onsubmit: JavaScript code to be invoked before AJAX request is sent.

Controlling Traffic

Flooding a server with small requests can cripple a web application, and any dependent services like databases.

Controlling Traffic, continued
Richfaces 3.3.0.GA and Higher

Queues can be defined using the<a4j:queue .../> component and are referred to as Named or Unnamed queues. Unnamed queues are also referred to as Default queues because components within a specified scope will use an unnamed queue by default.

Notable Attributes

Attribute Description
name Optional Attribute that determines if this is a named or unnamed queue
sizeExceededBehavior When the size limit reached: dropNext, DropNew, fireNext, fireNew
ignoreDupResponses If true then responses from the server will be ignored if there are queued evens of the same type waiting.
requestDelay Time in ms. events should wait in the queue incase more events of the same type are fired
Event Triggers onRequestDequeue, onRequestQueue, onSizeExeeded, onSubmit

Other notable attributes include: disabled, id, binding, status, size, timeout.

Named Queues

Named queues will only be used by components that reference them by name as below:


<a4j:queue name=”fooQueue” ... />
	<h:inputText … >
<a4j:support eventsQueue=”fooQueue” .../>
</h:inputText>

Unnamed Queues

Unnamed queues are used to avoid having to specifically reference named queues for every component.

Queue Scope Description
Global All views of the application will have a view scoped queue that does not need to be defined and that all components will use.
View Components within the parent will use this queue
Form Component within the parent or will use this queue

Global Queue

To enable the global queue for an application you must add this to the web.xml file.


<context-param>
<param-name>org.richfaces.queue.global.enabled</param-name>
  <param-value>true</param-value>
</context-param>

It is possible to disable or adjust the global queue’s settings in a particular view by referencing it by its name.


<a4j:queue name=”org.richfaces.global_queue” disabled=”true”... />

View Scoped Default Queues

Defined the <a4j:queue> as a child to the <f:view>.


<f:view>
  ...
  <a4j:queue ... />

Hot Tip

Performance Tips:

  • Control the number of requests sent to the server.
  • Limit the size of regions that are updated per request using <a4j:region/>
  • Cache or optimize database access for AJAX requests
  • Don’t forget to refresh the page when needed

Controlling Traffic, continued

Form Scoped Default Queue

This can be useful for separating behavior and grouping requests in templates.


<h:form>
   ...
<a4j:queue ... />
      ...


A4j:* Tags

The a4j:* tags provide core AJAX components that allow developers to augment existing components and provide plumbing for custom AJAX behavior.

a4j:repeat

This component is just like ui:repeat from Facelets, but also allows AJAX updates for particular rows. In the example below the component is used to output a list of numbers together with controls to change (the value is updated for the clicked row only):


<a4j:repeat value=”#{items}” var=”item”>
	<h:outputText value=”#{item.value} “ id=”value”/>
	<a4j:commandLink action=”#{item.inc}” value=” +1 “
reRender=”value”/>
  </a4j:repeat>

#{items} could be any of the supported JSF data models. var identifies a request-scoped variable where the data for each iteration step is exposed. No markup is rendered by the component itself so a4j:repeat cannot serve as a target for reRender.

The component can be updated fully (by usual means) or partially. In order to get full control over partial updates you should use the ajaxKeys attribute. This attribute points to a set of model keys identifying the element sequence in iteration. The first element has Integer(0) key, the second – Integer(1) key, etc. Updates of nested components will be limited to these elements.

a4j:include

Defines page areas that can be updated by AJAX according to application navigation rules. It has a viewId attribute defining the identifier of the view to include:


<a4j:include viewId=”/first.xhtml” /> 

One handy usage of a4j:include is for building multi-page wizards. Ajax4jsf command components put inside the included page (e.g. first.xhtml for our case) will navigate users to another wizard page via AJAX:


<a4j:commandButton action=”next” value=”To next page” />

(The “next” action should be defined in the faces-config.xml navigation rules for this to work). Setting ajaxRendered true will cause a4j:include content to be updated on every AJAX request, not only by navigation. Currently, a4j:include cannot be created dynamically using Java code.

a4j:keepAlive

Allows you to keep bean state (e.g. for request scoped beans) between requests:


<a4j:keepAlive beanName=”searchBean” />

Standard JSF state saving is used so in order to be portable

a4j:* Components, continued

it is recommended that bean class implements either java. io.Serializable or javax.faces.component.StateHolder.

a4j:keepAlive cannot be created programmatically using Java. Mark managed bean classes using the org.ajax4jsf. model.KeepAlive annotation in order to keep their states.JBoss Seam’s page scope provides a more powerful analog to ths behavior.

a4j:loadXXX
RichFaces provides several ways to load bundles, scripts, and styles into your application.

Tag Description
a4j:loadBundle a4j:loadBundle loads a resource bundle localized for the locale of the current view
a4j:loadScript loads an external JavaScript file into the current view
a4j:loadStyle loads an external .css file into the current view

a4j:status
Used to display the current status of AJAX requests such as “loading...” text and images. The component uses “start” and “stop” facets to define behavior. It is also possible to invoke Javascript or set styles based on status mode changes.

a4j:actionparam
Adds additional request parameters and behavior to command components (like a4j:commandLink or h:commandLink). This component can also add actionListeners that will be fired after the model has been updated.

rich:* tags

The rich: tags are ready-made or self-contained components. They don’t require any additional wiring or page control components to function.

Input Tags

Tag Description
rich:calendar Advanced Date and Time input with many options such as
inline/popup, locale, and custom date and time patterns.
rich:editor A complete WYSIWYG editor component that supports
HTML and Seam Text
rich:inplaceInput Inline inconspicuous input fields
rich:inputNumberSlider min/max values slider

Components include: comboBox, fileUpload, inplaceSelect, inputNumberSpinner

Output Tags

Tag Description
rich:modalPanel Blocks interactions with the rest of the page while active
rich:panelMenu Collapsable grouped panels with subgroup support
rich:progressBar AJAX polling of server state
rich:tabPanel Tabbed panel with client, server, or ajax switching
rich:toolBar Complex content and settings

Components include: paint2D, panel, panelBar,simpleTogglePanel, togglePanel, toolTip

Data Grids, Lists, and Tables

RichFaces has support for AJAX-based data scrolling, complex cell content, grid/list/table formats, filtering, sorting, etc....

rich:* Tags, continued

Tag Description
rich:dataTable Supports complex content, AJAX updates, sortable, and filterable columns
rich:extendedDataTable Adds scrollable data, row selection options, adjustable column locations, and row/column grouping
rich:dataGrid Complex grid rendering of grouped data from a model

Complex Content Sample

Tags Table

Menus

Hierarchical menus available in RichFaces include:

Tag Description Menus
rich:contextMenu Based on page location
and can be attached to
most components link
images, labels, etc...
rich:dropDownMenu Classic application style
menu that supports
icons and submenus.

Components include: rich:menItem, rich:menuGroup,rich:menuSeparator

Trees

RichFaces has tree displays that support many options such as switching (AJAX client or server), drag-drop and are dynamically generated from data models.

Tag Description Menus2
rich:tree Core parent component for a tree
rich:treeNode Creates sets of tree elements
rich:treeNodeAdaptor Defines data model sources for trees
rich:recursiveTree NodeAdaptor Adds recursive node definition from models

Selects

Provides visually appealing list manipulation options for the UI.

Tag Description Menus3
rich:listShuttle Advanced data list manipulation (figure x)
rich:orderingList Visually manipulate a lists order

Validation Tags

AJAX endabled validation including hibernate validation.

Tag Description
rich:ajaxValidator Event triggered validation without updating the model- this skips all JSF phases except validation.
rich:beanValidator Validate individual input fields using hibernate validators in your bean/model classes
rich:graphValidator Validate whole subtree of components using hibernate validators. can also validate the whole bean after model updates.

Drag-Drop

Allows many component types to support drag and drop features.

Tag Description
rich:dragSupport Add as a child to components you want to drag.
righ:dropSupport Define components that support dropped items.
rich:dragIndicator Allows for custom visualizations while dragging an item.
rich:dndParam To pass parameters during a drag-n-drop action.

Miscellaneous

Tag Description
rich:componentControl Attach triggers to call JS API functions on the components after defined events.
rich:effect Scriptaculous visual effect support
rich:gmap Embed GoogleMaps with custom controls
rich:hotKey Define events triggered by hot key (example: alt-z)
rich:insert Display and format files from the file system
rich:virtualEarth Embed Virtual Earth images and controls

Components include: rich:message, rich:messages, rich:jQuery

Skinning

Using out-of-the-box skins

RichFaces ships with a number of built-in skins.

Out-of-the-box Skins
default, classic, emeraldTown, blueSky, ruby, wine, deepMarine, sakura, plain, default, laguna*, glassx*, darkx*
* Require a separate jar file to function

Add the org.richfaces.SKIN context parameter to web.xml and set the skin name.


<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>blueSky</param-value>
</context-param>

Sample blueSky skin Sample ruby skin
sample 1 sample 2

Using skin property values on the page

You can use skinBean implicit object to use any value from the skin file on your page.


<h:commandButton value=”Next”
  style=”backgroundcolor:#{
skinBean.
  tabBackgroundColor}”/>

sample 3

The button color is set according to the current skin[Ruby].s

Loading different skins at runtime

You can define an applications skin with EL expression like this:


<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>#(skinBean.currentSkin)</param-value>
</context-param>

Define a session scoped skinBean and manage its currentSkin property at runtime with your skin names values. Every time a page is rendered, RichFaces will resolve the value in #{skinBean.currentSkin} to get the current skin. Changing Skins should not be done via AJAX but with a full page refresh. A full page refresh will ensure that all CSS links are correctly updated based on the new skin

Hot Tip

Advanced Skinning Features

  • Create custom skins, or extend the default skins
  • Override or extend styles per page as needed
  • Automatically skin the standard JSF components
  • Plug'n'Skin feature used to generate whole new skins using Maven archetypes

Customizing redefined CSS classes

Under the hood all RichFaces components are equipped with a set of predefined rich-* CSS classes that can be extended to allow customization of a components style (see documentation for details). By modifying these CSS classes you can update all components that use them such as:


.rich-input-text {
   color: red;
}

Project links for more information or questions:

Project page (http://www.jboss.org/jbossrichfaces)
Documentation (http://jboss.org/jbossrichfaces/docs)

About The Author

Photo of author Nick Belaevski

NickBelaevski

Nick Belaevski Nick Belaevski is the team leader of the RichFaces project working for Exadel Inc. He has more than four years of experience in development of middleware products including JBoss Tools and RichFaces.

Projects: RichFaces

Photo of author Ilya Shaikovski

Ilya Shaikovski

Ilya Shaikovsky is the Exadel product manager working on the RichFaces project since Exadel began ajax4jsf. He’s responsible for requirements gathering, specification development, JSF related product analysis and supporting RichFaces and JSF related technologies for business applications. Prior to this he worked on the Exadel Studio Pro product.

Projects: RichFaces

Photo of author Jay Balunas

Jay Balunas

Jay Balunas works as the RichFaces Project Lead and core developer at JBoss, a division of Red Hat. He has been architecting and developing enterprise applications for over ten years specializing in web tier frameworks, UI design, and integration. Jay blogs about Seam, RichFaces, and other technologies at http://in.relation.to/Bloggers/Jay

Projects: RichFaces, Seam Framework, and JBoss Tattletale

Photo of author Max Katz

Max Katz

Max Katz is a senior system engineer at Exadel. He is the author of “Practical Rich- Faces” (Apress). He has been involved with RichFaces since its inception. He has written numerous articles, provided training, and presented at many conferences and webinars about RichFaces. Max blogs about RichFaces and RIA technologies at http://mkblog.exadel.com.

Projects: RichFaces

Recommended Book

PracticalRichFaces

JBoss RichFaces is a rich JSF component library that helps developers quickly develop next–generation web applications. Practical RichFaces describes how to best take advantage of RichFaces, the integration of the Ajax4jsf and RichFaces libraries, to create a flexible and powerful programs. Assuming some JSF background, it shows you how you can radically reduce programming time and effort to create rich AJAX based applications.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting Started with JBoss Enterprise Application Platform 5

By Scott Marlow, Jaikiran Pai, Shelly McGowan, Brian Stansberry and Len DiMaggio

15,335 Downloads · Refcard 97 of 151 (see them all)

Download
FREE PDF


The Essential JBoss EAP 5 Cheat Sheet

JBoss Enterprise Application Platform 5 is an open source implementation of the Java EE suite of services. This DZone Refcard provides an in-depth introduction to JBoss Enterprise Application Platform 5. It comprises a set of offerings for enterprise customers who are looking for preconfigured profiles of JBoss Enterprise Middleware components that have been tested and certified together to provide an integrated experience. We take you all the way from installation to the deployment of your application. This Refcard is a must have for both users starting out with Java EE as well as senior architects.
HTML Preview
Getting Started With JBoss Enterprise Application Platform 5

Getting Started with JBoss Enterprise Application Platform 5

By Scott Marlow, Jaikiran Pai, Shelly McGowan, Brian Stansberry, and Len DiMaggio

WHAT IS JBOSS EAP 5?

JBoss Enterprise Application Platform is an open source implementation of the Java EE suite of services. It comprises a set of offerings for enterprise customers who are looking for preconfigured profiles of JBoss Enterprise Middleware components that have been tested and certified together to provide an integrated experience. Its easy-to-use server architecture and high flexibility makes JBoss the ideal choice for users just starting out with Java EE, as well as senior architects looking for a customizable middleware platform.

Because it is Java-based, JBoss Enterprise Application Platform is cross platform, easy to install and use on any operating system that supports Java. The readily available source code is a powerful learning tool to debug the server and understand it. It also gives you the flexibility to create customized versions for your personal or business use.

Visit the http://www.jboss.com/products/community-enterprise/ website to download JBoss Enterprise Application Platform 5.

INSTALLING JBOSS EAP 5

1. Installation using the Graphical Installer

The graphical installer will guide you through the installation steps. Invoke the installer using the command:


java -jar enterprise-installer-5.0.1.GA.jar

2. Installation using the Zip Distribution

Use the unzip command:


unzip jboss-eap-5.0.1.GA.zip

Use the same steps to install optional native package:


unzip jboss-eap-native-5.0.1.GA-<operating-system>-<arch>.zip

DIRECTORY STRUCTURE

Contents of jboss-as:

Directory Description
bin Contains startup, shutdown and other system-specific scripts. All entry point JAR files and start scripts are here.
client JAR files used by external Java client applications. Choose JAR files as required or use jbossall-client.jar
common/lib Shared JAR files common to profiles are here.
docs XML DTD and schemas for reference. Also example configuration files for setting up datasources (e.g. MySQL, Oracle, PostgreSQL).
lib Contains server startup JARs and not intended to hold application JAR files.
server Contains the JBoss server profile sets.

DIRECTORY STRUCTURE

JBoss EAP 5 configuration profiles are located within the jboss-as/server directory (specified with "run -c PROFILE" ):

default JavaEE 5 server profile. Has most frequently used EE services. Default does not include JAXR, IIOP, clustering services.
all Bundles all services (including clustering and RMI/IIOP).
production based on "all" profile, tuned for production; with log verbosity reduced, deployment scanning every 60 seconds, and memory usage tuned to accommodate production deployment requirements, configured to require authorization checks.
standard based on 'all' profile and is a fully certified Java EE 5 configuration.
web lightweight configuration created around JBoss Web and provides services required for web application deployment and a subset of Java EE technologies. Does not include JBoss Transaction JTS or XTS, Enterprise Java Bean 1.x or 2.x capabilities, JBoss Messaging, JCA, or JBoss IIOP
minimal Bare minimum required to start. Includes logging, JNDI and URL deployment scanner. Use JMX/JBoss to start your own services. No web container, EJB or JMS support is included.

ADMINISTRATION

To start the JBoss EAP server, simply change to the EAP_DIST/ jboss-as/bin directory. Set the environment variable JAVA_ HOME. Execute the run.bat (for Windows) or run.sh (for Linux, Unix, Mac OSX) script, as appropriate for your operating system.

Administering your JBoss EAP 5 server instance is easy with the administration consoles provided in this distribution. Once the server is started, simply point your browser to:


http://localhost:8080

This brings you to the consoles to manage your instance as well as links to on-line resource references.

Use the Administration Console for managing and monitoring a server instance. Deploy, undeploy, and update enterprise applications, persist configuration changes for Datasources, JMS topics and queues, Connection Factories, and Service Binding Manager, monitor standard JVM metrics, and view statistics and invoke operations on many other components.

The JMX Console provides a server view. It lists all registered services (MBeans). Administration Console shares the same username/password as JMX console.

Command-line scripts are available in the jboss-as/bin directory. In addition to scripts for starting and stopping the server, JBoss provides a command line tool that allows for interaction with a remote server instance. This tool is called twiddle (for twiddling bits via JMX) and is located in the bin directory. Twiddle is a command execution tool, not a general command shell. Run using the twiddle.sh/twiddle.bat scripts, and passing in a -h(-- help) argument provides the basic syntax, and --help-commands shows commands. Twiddle defaults to the localhost at port 1099 to lookup the default jmx/rmi/RMIAdaptor binding of the RMIAdaptor service as the connector for communicating with the JMX server. To connect to a different server/port combination, can use the -s (--server) option:


$ ./twiddle.sh -s servername serverinfo -d jboss
$ ./twiddle.sh -s servername:1099 serverinfo -d jboss

MANAGEMENT

The JBoss Operations Network (JON) management platform delivers centralized systems management that allows you to:

  • Coordinate stages of application’s life-cycle datasources and messaging services
  • Expose cohesive view of middleware components through complex environments
  • Improve operational efficiency/reliability through visibility into production availability and performance
  • Configure and roll out applications across complex environments through a single tool

APPLICATION DEPLOYMENT

There are multiple ways to deploy applications to JBoss:

Simplest way

  • Choose the server profile to which you want to deploy the application (let's consider the "default" server profile in this example)
  • Copy your application (for example: .war or .ear or a .jar file) to JBOSS_HOME/server/<profilename>/deploy folder.
  • Start the server:

./run.sh

  • JBoss will deploy your application when it boots up.
  • That's it!

Hot Tip

This approach does not require the server to be started when you are deploying your application. If you want to undeploy the application then just move (or delete) the application from the deploy folder. You can develop simple scripts (like an Ant script) to deploy the application to JBoss. All it takes is a file copy command.

Using the admin console

  • Start the server

./run.sh

  • On the left hand side of the admin console page, under JBoss AS -> Applications, select the type of application you want to deploy. Let's consider a web application (.war) in this example
  • Click the "Web Application (WAR)" link
  • In the right side section, under the "Summary" tab, click on "Add a new resource" button

  • "Browse" to the .war file to deploy (e.g. /home/me/myapp.war)
  • If you want to deploy the application in exploded format (instead of an archive) then select "Yes" radio button for "Deploy Exploded" option Click on the "Continue" button
  • On successful deployment, you will see your application listed in the Summary tab
  • To undeploy the application, click on the "Delete" button next to the application you want to undeploy, in the "Summary" tab

Hot deployment

JBoss has a built-in hot deployer which can:

  • Detect new applications in the deploy folder and trigger an application deployment
  • Detect an application which was removed from the deploy folder and trigger an application undeployment
  • Detect that the deployment descriptor of an application (for example, the web.xml of .war or application.xml of .ear) has changed and trigger an application redeployment

Hot Tip

The hot deployer is configured to run every X milliseconds. This value can be changed by changing the "scanPeriod" attribute in JBOSS_HOME/server/lt;profilename>/deploy/ hdscanner-jboss-beans.xml:

<!-- Hotdeployment of applications -->
<bean name="DScanner" class="org.jboss.system.server.profileservice
.hotdeploy.HDScanner">
<property name="deployer"><inject bean="ProfileServiceDeployer"/></property>
<property name="profileService"><inject bean="ProfileService"/></property>
<property name="scanPeriod">5000</property>
<property name="scanThreadName">HDScanner</property>
</bean>

To disable hot deployment, remove the hdscanner-jboss-beans. xml from the deploy folder or rename it to hdscanner-jbossbeans. xml.bak (.bak files are ignored).

Clustering

Getting started with JBoss clustering is very simple. If two JBoss server instances using the all configuration are started on the same network, those servers will detect each other and automatically form a cluster.

Initial Preparation

Preparing a set of servers to act as a JBoss cluster involves a few simple steps:

  • Install JBoss on all your servers.
  • For each node, determine the address to bind sockets to.
  • Ensure multicast is working. Make sure each server's networking configuration supports multicast and that multicast support is enabled for any switches or routers between your servers. JBoss clustering also offers nondefault configuration options that do not use multicast.
  • Determine a unique integer "ServerPeerID" for each node. JBoss Messaging requires that each node in a cluster has a unique integer id, known as a "ServerPeerID", that should remain consistent across server restarts. A simple 1, 2, 3, ..., x naming scheme is fine.

Launching Your Cluster

We'll look at two scenarios for doing this. In each scenario we'll be creating a two node cluster, where the ServerPeerID for the first node is 1 and for the second node is 2.

Scenario 1: Nodes on Separate Machines

On node1, to launch JBoss:


$ ./run.sh -c all -b 192.168.0.101 -Djboss.messaging.ServerPeerID=1

On node2, it's the same except for a different -b value and ServerPeerID:


$ ./run.sh -c all -b 192.168.0.102 -Djboss.messaging.ServerPeerID=2

The -c switch says to use the all config, which includes clustering support. The -b switch sets the address on which sockets will be bound. The -D switch sets the system property from which JBoss Messaging gets its unique id.

Scenario 2: Two Nodes on a Single, Non-Multihomed, Machine

Running multiple nodes on a single machine that only has a single IP address is a common scenario in a development environment. You need to be sure each server instance has its own work area. One way to do this is to simply make copies of the all configuration. For example, assuming the root of the JBoss distribution was unzipped to /var/jboss, you could:


$ cd /var/jboss/server
$ cp -r all node1
$ cp -r all node2

Two processes can't bind sockets to the same address and port, so we'll have to tell JBoss to use different ports for the two instances. This can be done by setting the jboss.service. binding.set system property.

To launch the first instance, open a console window and:


$ ./run.sh -c node1 -b 192.168.0.101 -Djboss.messaging.ServerPeerID=1 \
-Djboss.service.binding.set=ports-default

For the second instance, in a second console window:


$ ./run.sh -c node2 -b 192.168.0.101 -Djboss.messaging.ServerPeerID=2 \
-Djboss.service.binding.set=ports-01

This tells the ServiceBindingManager on the first node to use the standard set of ports (e.g. JNDI on 1099). The second node uses the “ports-01" binding set, with which by default each port has an offset of 100 from the standard port number (e.g. JNDI on 1199).

Web Application Clustering Quick Start

Web application clustering involves two aspects: setting up an HTTP load balancer and telling JBoss to make the application’s user sessions HA. How to do the former depends on what load balancer you choose (mod_cluster is a good choice); the latter couldn't be simpler – just add the <distributable/> to your application’s web.xml.

EJB3 Session Bean Clustering Quick Start

To add load balancing and failover capabilities to your EJB3 session beans, simply add the org.jboss.ejb3.annotation. Clustered annotation to the bean class for your stateful or stateless bean:


@javax.ejb.Stateful
@org.jboss.ejb3.annotation.Clustered
public class MyBean implements MySessionInt {
	public void test() {
		// Do something cool
	}
}

PERFORMANCE AND TUNING

Identify peak application workload and difference from normal workload. In understanding peak workloads, don’t go by averages as the peaks may be much more than the averages calculated over a period. Start testing with a low load and increase until expected peak load. Tune until target performance is achieved. There are a number of possible performance optimizations. Always load test before and after making changes to verify the intended effect. Make one change at a time so it's clear what change has what effect.

Use OS monitoring tools to identify system performance bottlenecks. In a multiple machine installation, find the machine(s) that are the bottleneck.

Instrument the application for performance measurement (make optional for production ). Also, turn on container call statistics and Hibernate statistics.

Taking successive thread dumps indicates what is going on. Do this prior/after hitting a performance wall. Generate a thread dump once a minute over a five minute performance problem and compare your findings. Use "jps -l" command to get the Java process ids and then run the “jstack ProcessID" command (generates the thread dump.)

The HotSpot Java Virtual Machine contains other information gathering tools which can help tune applications. More information is in http://java.sun.com/javase/technologies/hotspot/.

jmap generates a memory heap dump file that can easily be read by the Eclipse Memory Analyzer tool (http://www.eclipse.org/mat/). jstat shows details of the memory space.

Clustering Tuning

Ensuring Adequate Network Buffers

Inadequately sized network buffers can cause lost packets. Steps to increase max buffer sizes are OS specific. For Linux change /etc/sysctl.conf file:


# Allow a 25MB UDP receive buffer for JGroups
net.core.rmem_max = 26214400
# Allow a 1MB UDP send buffer for JGroups
net.core.wmem_max = 1048576

Isolating Intra-Cluster Traffic

isolate intra-cluster traffic from external request traffic. This requires multiple NICs on your server machines, with request traffic coming in on one NIC and intra-cluster traffic using another.


./run.sh -c all -b 10.0.0.104 -Djgroups.bind_addr=192.168.100.104

JGroups Message Bundling

Message bundling queues small messages until a configurable number of bytes have accumulated, then sent as a large message. Use of bundling can have significant performance benefits for high-volume asynchronous session replication. However, it is not enabled by default, as bundling can add significant latency to other types of intra-cluster traffic, particularly clustered Hibernate/JPA Second Level Cache traffic.

To use a JGroups channel with message bundling enabled, edit the <JBoss_Home>/server/<profilename>/deploy/cluster/ jboss-cache-manager.sar/META-INF/jboss-cache-jboss-beans. xml file. For example, for the cache used by default for web sessions:


. . .
<!-- Standard cache used for web sessions -->
<entry><key>standard-session-cache</key>
<value>
	<bean name="StandardSessionCacheConfig" class="org.jboss.cache.config.
	Configuration">
. . .
<!-- Replace standard 'udp' JGroups stack with one that uses message
bundling -->
	<property name="multiplexerStack">udp-async</property>
. . .

For FIELD granularity web sessions, in the same file the same change can be made to the cache configuration with the fieldgranularity- session-cache key. For EJB3 stateful session beans, in the same file the same change can be made to the cache configuration with the sfsb-cache key.

Enabling Buddy Replication for Session Caches

In a cluster of more than two nodes, you can improve performance by enabling "buddy replication" in the web session and stateful session bean caches. With buddy replication, instead of replicating a copy of sessions to all nodes in the cluster, a copy is only replicated to a configurable number of "buddy" nodes.

Buddy replication is enabled by editing the <JBoss_Home>/ server/<profilename>/deploy/cluster/jboss-cache-manager. sar/META-INF/jboss-cache-jboss-beans.xml file. For example, for the cache used by default for web sessions:


. . .
<!-- Standard cache used for web sessions -->
<entry><key>standard-session-cache</key>
<value>
	<bean name="StandardSessionCacheConfig" class="org.jboss.cache.config.
	Configuration">
. . .
<property name="buddyReplicationConfig">
	<bean class="org.jboss.cache.config.BuddyReplicationConfig">
<!-- Just set to true to turn on buddy replication -->
	<property name="enabled">true</property>
. . .

For FIELD granularity web sessions, in the same file the same change can be made to the cache configuration with the fieldgranularity- session-cache key. For EJB3 stateful session beans, in the same file the same change can be made to the cache configuration with the sfsb-cache key.

Reducing the Volume of Web Session Replication

Reducing the amount data being replicated can obviously improve performance. This can be accomplished both by avoiding replication when a request hasn't actually updated the session and by limiting replication to only the session data that has actually changed. See the discussion of replicationtrigger and replication-granularity in "http://www.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5.0.0/html/Administration_And_Configuration_Guide/clustering-http-state.html" for how to configure your application to limit the amount of data replicated.

Monitoring JGroups via JMX

When clustering services create a JGroups Channel to use for intra-cluster communication, the JMX console will include the following:

jboss.jgroups:cluster=<cluster_name>,protocol=UDP,type=protocol Statistics on two thread pools used to carry incoming messages up the channel’s protocol stack.

jboss.jgroups:cluster=<cluster_name>,protocol=UNICAST,type=protocol Information on lossless, ordered delivery of unicast (i.e. point-to-point) messages.

jboss.jgroups:cluster=<cluster_name>,protocol=NAKACK,type=protocol Information on lossless, ordered delivery of multicast (i.e. point-to-multipoint) messages.

jboss.jgroups:cluster=<cluster_name>,protocol=FC,type=protocol Information on ensuring fast message senders do not overwhelm slow receivers.

Web deployer

Other key configurations required for performance tuning of your Enterprise Application Platform include the <JBoss_ Home>/server/<your_configuration>/deployers/jbossweb. deployer/server.xml file that sets your HTTP requests pool.

Thread pool

JBoss Enterprise Application Platform 5 has a robust thread pooling, that should be sized appropriately. The server has a jboss-service.xml file in the <JBoss_Home>/server/<your_ configuration>/conf directory that defines the system thread pool. There is a setting that defines the behavior if there isn't a thread available in the pool for execution. The default is to allow the calling thread to execute the task. You can monitor the queue depth of the system thread pool through the JMX Console, and determine from that if you need to make the pool larger.

TROUBLESHOOTING

Startup problems

If you are having trouble starting JBoss, the first thing to check is the JAVA_HOME environment variable. This should point to the home of your JDK (or JRE installation). For example, if your JDK is installed at /opt/Java/jdk1.5.0 then JAVA_HOME should be set as follows:


JAVA_HOME=/opt/Java/jdk1.5.0

On Windows OS, if your JDK installation is at C:/Java/jdk1.5.0, you can set it as follows:


set JAVA_HOME=C:/Java/jdkl.5.0

Hot Tip

It's highly recommended not to install JBoss or Java in a folder containing a space in its path. For example, do not install Java at C:/Program Files/Java/jdk1.5.0 on Windows OS.

Logs

JBoss by default is configured to log messages to the JBOSS_HOME/server/<servername>/log server.log file. This file can be checked for any exceptions or other informational logging. Logging levels can be controlled in JBOSS_HOME/ server/<servername>/conf/jboss-log4j.xml

Thread dumps

Sometimes, if you notice that the application is not responding, you can generate thread dumps to check what each thread is currently doing. Thread dumps can be generated in multiple ways - 2 of which are explained below:

From jmx-console

  • Access jmx-console (http://localhost:8080/jmx-console)
  • Look for the jboss.system:type=ServerInfo MBean and click on the link
  • On the page that comes up, look for the listThreadDump operation and click on the Invoke button

Using Twiddle:

  • From the command prompt, cd to JBOSS_HOME/bin folder
  • Run the following command:
    • ./twiddle.sh invoke "jboss.system:type=ServerInfo" listThreadDump > threads.html
    • Note: Use twiddle.bat for Windows OS

This command will generate the thread dump and redirect the output to threads.html (you can redirect it to any file of your choice)

It's best to generate multiple thread dumps between a span of few seconds and compare those thread dumps to find any blocked threads.

Reporting problems

Also, search the community forums to see if someone else is experiencing the same problem. The forums are at link http://community.jboss.org/. You can also obtain a support contract via http://www.jboss.com/services/subscriptions/ and then access https://www.redhat.com/wapps/sso/jboss/login.html?redirect=http%3A%2F%2Fsupport.redhat.com%2Fjbossnetwork

Search for existing issues that also report the same problem. Access the JIRA issue search via link https://jira.jboss.org/jira/secure/IssueNavigator.jspa

When filling in the JIRA, be as precise as possible when reporting the bug. Include as much information as possible. Include the steps needed to reproduce the problem.

If possible, create a standalone test case that reproduces the bug that can be attached to a JIRA issue. The JIRA issue is more likely to be fixed if a unit test is attached (or at least a test case). Even better is if a solution, in the form of a patch (output of doing "svn diff > fix.patch"), is attached.

JBOSS EAP 5 VS AS 5

The focus of the JBoss AS project is continuous innovation - fueled by Open Source community collaboration - on the bleeding edge of Java Middleware. Quickly bringing emerging standards and technology into the mainstream through it's large user base and active community. This focus implies continuous change and a rapid release cycle with minor releases every one or two months and major releases every six months. Red Hat does not provide support for JBoss community projects.

Red Hat does provide world-class support, consulting and training for the JBoss Enterprise Platforms. JBoss Enterprise Platforms balance innovation with enterprise class stability by integrating the best of Open Source projects like JBoss AS. The JBoss Enterprise Platforms are certified against a broad range of Operating Systems, Databases and other 3rd party applications and tools; meet very strict industry security standards; are pre-tuned and secured by default so are ready to support your business critical applications and services.

Red Hat recommends JBoss projects as a place to get involved in shaping the Open Source middleware landscape and as a way to understand how the technology landscape is evolving. Red Hat recommends JBoss Enterprise Platforms for demanding business critical production workloads where security, performance, reliability and long-term, world-class support are imperative.

See this link for information on training http://www.jboss.com/services/training/

About The Authors

Scott Marlow

Core Engineer on the JBoss AS team. Over 20 years experience building enterprise development software, from database server to developer tools (such as PowerBuilder and four different application servers). Five years experience contributing to JBoss OSS projects { Application Server, Clustering, JGroups, JBoss Cache, Hibernate }. Scott enjoys coaching and playing soccer in his spare time.

Jaikiran Pai

Employed at RedHat and is part of the JBoss EJB3 development team. Jaikiran completed his graduation in 2004 and started working in a software company in Pune, India. In his role as a software developer, he was part of projects which involved Java and JavaEE. During this period, he developed interest in JBoss Application Server and started spending his spare time in JBoss community forums. In 2009, Jaikiran was offered a job at RedHat to be part of his favourite project - JBoss Application Server.

Jaikiran can often be found either at the JBoss forums or at his other favourite place http://www.javaranch.com/. Occasionally, Jaikiran blogs at http://www.jaitechwriteups.blogspot.com/

Shelly McGowan

Member of the JBoss Application Server development team. She has several years of software development experience most recently on Java Enterprise Edition technologies such as EJB and EJB 3 persistence.

Brian Stansberry

My background is in International Business and East Asian Studies, with a B.A. from Michigan State and an M.A. from Stanford. Before getting bitten by the software bug, I had a successful career in corporate finance in the semiconductor industry. Part of that oddly enough involved web application and other types of software development. But since I realized in the late 1990s that my true interest was in software, not finance, I've focused on server-side development and Java. I started working on JBoss in 2003 and joined the company in 2005. My other main interests are China (I speak Mandarin Chinese and visit China regularly) and hanging out with my family. I live in St. Louis, MO.

Expertise: JBoss AS Clustering JBoss AS in general JBoss Cache PojoCache JGroups mod_cluster

Occupation: Lead, JBoss AS Clustering

Len DiMaggio

JBoss middleware QE engineer and team lead. Len is a frequent contributor to JBoss blogs and DZone (http://soa.dzone.com/users/ldimaggi).

Recommended Book

JBoss AS5 Development

This book will kick-start your productivity and help you to master JBoss AS development. The author's experience with JBoss enables him to share insights on JBoss AS development, in a clear and friendly way. By the end of the book, you will have the confidence to apply all the newest programming techniques to your JBoss applications.



JBoss in Action

JBoss in Action is the first book to focus on teaching readers in detail how to use the JBoss application server. Unlike other titles about JBoss, the authors of JBoss in Action go deeper into the advanced features and configuration of the server. In particular, it focuses on enterprise-class topics, such as high availability, security, and performance.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: JBoss Application Server 7 is here!

Today, JBoss released the 7th version of their free, open-source Java EE-based application server. As JBoss' Lead Technical Director Mark Little states,It's taken us a while to get here and we've taken some pretty drastic and innovative steps along the...

0 replies - 19931 views - 07/12/11 by Ross Jernigan in Daily Dose

Mastering Portals with a Portlet Bridge

By Wesley Hales

6,758 Downloads · Refcard 132 of 151 (see them all)

Download
FREE PDF


The Essential JBoss Portlet Bridge Cheat Sheet

Portals have long been a thorn in the side of many developers who want to stay cutting edge, but most focus on the needs of the enterprise. About 99% of the time, a portal is the only answer for aggregating many applications into a single UI. A portlet bridge allows you to run application frameworks like JSF in a portal environment without worrying about the underlying portlet API or portlet concepts. Portlet bridge is a must-have mediator when working with portals, and it allows developers to learn a new technology painlessly. This Refcard provides specific configurations for the JBoss Portlet Bridge.
HTML Preview
Mastering Portals with a Portlet Bridge

Mastering Portals with a Portlet Bridge

By Wesley Hales

ABOUT PORTLET BRIDGES

Portals have long been a thorn in the side of many developers who want to stay cutting edge—but must focus on the needs of the enterprise. And 99% of the time, a portal is the only answer for aggregating many applications into one UI.

A portlet bridge allows you to run application frameworks like JSF in a portal environment without worrying about the underlying portlet API or portlet concepts.

The JSR-301/329 portlet bridge boasts ease of transition, ease of initiation, and seamless mappings from JSF to the portal environment. Overall, a portlet bridge is a must-have mediator when working with portals, and it allows developers to learn a new technology painlessly.

ABOUT THE JBOSS PORTLET BRIDGE

This refcard shows specific configurations for the JBoss Portlet Bridge. The JBoss Portlet Bridge is a non-final draft implementation of the JSR-329 specification which supports the JSF 1.2 and 2.0 runtime within a JSR 168 or 286 portlet and with added enhancements to support other web frameworks (such as Seam and RichFaces).

The project follows the spec from JSR-301 to JSR-329 and now maintains an alpha version (3.0) compatible with JSF 2.0 and RichFaces 4.0.

Versions

Since this portlet bridge spans four different JSRs and supports two additional JSF frameworks, understanding versions can be a little daunting. i.e. Just because the portlet bridge is versioned at 2.0 does not mean it covers the JSF 2.0 specification.

JBoss Portlet Bridge Latest Versions Compatible Frameworks
2.1.0.FINAL JSR-286 Portlets, JSF 1.2, RichFaces 3.3.3.FINAL,Seam 2.2.1.CR2
3.0.0.ALPHA SR-286 Portlets, JSF 2.0, RichFaces 4.0

IN THE BEGINNING, THERE WERE PORTLETS

It would only be fair (and cruel in some states) if I gave you a brief primer on portal and portlet technologies. There will come a day when you will need to understand what an ActionRequest is and what you can pull from your FacesContext.ExternalContext() while running as a JSF portlet.

Portal Terminology

Portal

Hosts the presentation layer for personalization, single sign on and content aggregation.

Portlet Container

A portal can host multiple portlet containers, and each portlet container has its own runtime environment.

Portal Page: Aggregation of portlets, organized and displayed on a single page.

Portlet: A portlet is a Java technology-based web component, managed by a portlet container, that processes requests and generates dynamic content.

Portlet Instance: A portlet instance can be placed on multiple pages and will show the same state in regards to the current mode.

Portlets vs. Servlets

Most rookie portlet developers have their roots in the servlet world. So it’s important to know the key differences in what you’re about to dive into from what you’ve been dealing with. Portlets generate a portion or “fragment” of the HTML page they’re being displayed upon. This is the first big bullet point in understanding differences between servlets and portlets. UI wise, they cannot make use of the same html (for instance the standard <html> <head> <title> and <body> are forbidden in the portlet markup). The job of writing these tags belongs to the Portal Page and not you, the developer.

Points To Remember
  • Portlet URLs, which are used as links to other pages within your Portlet window, are dynamically pre-generated by the Portlet code and passed into the markup.
  • Although servlets and portlets are in some respects similar, their containers and lifecycles differ.
  • On the front end, portlets are HTML fragments that compose a larger page which they are unaware of. Servlets provide the entire page.
  • Portlets cannot be accessed by use of a single URL, the way in which servlets are accessed. Instead, the URL points to the page where many portlets may be contained.
  • The portal request paradigm is completely different. There are two requests instead of one. This is talked about in the next section.
  • You now have mode and state buttons that allow you to “minimize” or “maximize” the portlet window or enter “help” mode.
  • Portlets support two scopes within the session (PORTLET_SCOPE and APPLICATION_SCOPE). This allows for cases like sharing data from one portlet to another.
  • Portlets are not allowed to set character encoding on the response, set HTTP headers, or manipulate the URL of the client request to the portal.
Portlet Lifecycle

Once you wrap your head around the fact that there are two requests and the Portal sends them for you, the rest is a piece of cake. What I’m about to explain makes total sense, but it’s a huge change from the way things are done in a Servlet-based web app. In the Servlet world, a Servlet owns the process of receiving an entire web request and rendering output at the same time in one big response. In the Portlet world, the Portal receives the web request then makes separate calls to individual portlets. This separation allows for a different lifecycle method to be introduced in Portlets. The two requests are called Action and Render, and each have their own request and response. You must first keep in mind that when you click a link or submit button in the portlet window, it has been generated by the portal API. Thus, the portal needs to control/remember things like which window is sending the request, modes, parameters, window states, etc. So when an Action link is clicked, the portal will get this information and run processAction() along with a few other methods in your portlet. You are guaranteed that this action will be complete before the rendering phase starts. Once this is done, the portal now needs to re-render the page along with all the other portlets on that page. The best thing to keep in mind is portlets may be asked to render, even when the user is not interacting with them. Conceptually, this makes sense to have the two requests. However, developers have been naturally forced to do both of these things at the same time in the servlet world.

In most cases, when converting an existing servlet based application to a portlet, you must use a portlet bridge so that URLs are generated for the portlet world—along with other framework functionality.

GIVING PORTLETS A SECOND CHANCE

If You Skipped The First Page...

It’s okay because the portlet bridge is created to mask all of those hairy details from the developer so you only have to worry about your web application. You can now take your existing JSF-based application and plug it into a portal painlessly.

Getting Started

Use the following maven archetype command:


mvn archetype:generate
-DarchetypeCatalog=http://bit.ly/jbossportletbridge

frame 1

Choose from the available projects and you will have everything you need to start developing a new portlet. If you are moving an existing application to a portlet, this will serve as a reference point for configuration.

Archetype Options

You will also see other configuration options like “makeremotable” and “richfaces-javascript-namespace” in the archetype generate phase.

Option Purpose
make-remotable Boolean property that will create the configuration for running this portlet remotely over WSRP
richfaces-javascriptnamespace Boolean property that allows for namespacing dynamically generated RichFaces javascript.

CONFIGURATION

The portlet bridge is a mediator between your web application and the portal worlds. It is not a portlet. So here we will review the changes you must make to convert your current JSF application into a portlet.

Core JSF Portlet Setup

portlet.xml

The following config is the backbone of your portlet. It shows where the supplied GenericFacesPortlet is and which JSF pages to render when clicking on the mode buttons (i.e. help, edit, etc...).


<portlet>
<portlet-name>yourPortletName</portlet-name>
<portlet-class>
	javax.portlet.faces.GenericFacesPortlet
</portlet-class>
<init-param>
	<name>javax.portlet.faces.defaultViewId.view</name>
	<value>/welcome.xhtml</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.defaultViewId.edit</name>
	<value>/jsf/edit.xhtml</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.defaultViewId.help</name>
	<value>/jsf/help.xhtml</value>
</init-param>

When preserveActionParams is set to TRUE, the bridge must maintain any request parameters assigned during the portlet’s action request. You should set this as true if your application is not receiving request parameters that were set when a button or link was clicked.


<init-param>
	<name>javax.portlet.faces.preserveActionParams</name>
	<value>true</value>
</init-param>

faces-config.xml

The PortletViewHandler ensures that each JSF portlet instance is properly namespaced. Your application will use a combined portal and JSF namespace.


<faces-config>
<application>
	<view-handler>
	  org.jboss.portletbridge.application.PortletViewHandler
	</view-handler>
	<state-manager>org.jboss.portletbridge.application.
PortletStateManager</state-manager>
</application>

web.xml

The following setting tells your portlet to use the FaceletPortletViewHandler when using RichFaces.


<context-param>
	<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
	<param-value>org.jboss.portletbridge.application.
FaceletPortletViewHandler</param-value>
</context-param>

ALWAYS_DELEGATE Indicates the bridge should not render the view itself but rather always delegate the rendering. This is the default setting for Facelets. If strictly using .jsp, then set the following to NEVER_DELEGATE.


<context-param>
	<param-name>javax.portlet.faces.RENDER_POLICY</param-name>
	<param-value>
	   ALWAYS_DELEGATE
	</param-value>
</context-param>

RichFaces Portlet Configuration

web.xml

RichFaces maintains dynamic scripts and styles that are injected in the page at render. The recommended settings for a portal environment are:


<context-param>
	<param-name>org.richfaces.LoadStyleStrategy</param-name>
	<param-value>DEFAULT</param-value>
</context-param>
<context-param>
	<param-name>org.richfaces.LoadScriptStrategy</param-name>
	<param-value>ALL</param-value>
</context-param>

RichFaces does not account for multiple components on the same portal page by default. This following parameter renders all RichFaces component javascript to be portal friendly.


<context-param>
	<param-name>org.jboss.portletbridge.WRAP_SCRIPTS</param-name>
	<param-value>true</param-value>
</context-param>

Seam automatically configures your Ajax4JSF/RichFaces Filter, so if you are running a Seam portlet, you do not need the following Filter config.


<filter>
	<display-name>Ajax4jsf Filter</display-name>
	<filter-name>ajax4jsf</filter-name>
	<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>

	<filter-mapping>
	<filter-name>ajax4jsf</filter-name>
	<servlet-name>FacesServlet</servlet-name>
	<dispatcher>FORWARD</dispatcher>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Seam Portlet Configuration

Hot Tip

It’s important to remember that your portlet may be rendered many times. Since Seam page actions are performed on the RenderRequest, you should only define your navigation in pages.xml.

The SeamExceptionHandler is used to clean Seam contexts and transactions after errors.


<context-param>
	<param-name>org.jboss.portletbridge.ExceptionHandler</param-name>
	<param-value>
	  org.jboss.portletbridge.SeamExceptionHandlerImpl
	</param-value>
</context-param>

USING PORTLET 2.0 COORDINATION WITH JSF

Portlet container

Portlet 2.0 coordination gives us two ways to communicate between portlets (events and public render parameters). This means you can deploy a JSF 2 war and another JSF 1.2/Seam 2 ear and they can send events and messages to each other.

One very important thing to note before using either of the following mechanisms is that you must have the proper 2.0 schema and xsd definition at the top of your portlet.xml.


<portlet-app xmlns=”http://java.sun.com/xml/ns/portlet/portletapp_
2_0.xsd”
	version=”2.0”
	xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation=”http://java.sun.com/xml/ns/portlet/
portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd”>

Hot Tip

Portlet events and public render parameters cannot be set during Ajax requests.

Sending and Receiving Events

The bridge is designed by default to defer to normal portlet processing when sending events. You should set the following parameters allowing portlet events to be sent directly to the bridge (autoDispatchEvents) and which class should process received portlet events (bridgeEventHandler).


<init-param>
	<name>javax.portlet.faces.autoDispatchEvents</name>
	<value>true</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.bridgeEventHandler</name>
	<value>org.foo.eventhandler</value>
</init-param>

For now, you must dispatch the event in the JSF or Seam backing bean. Future versions of the bridge should automate the dispatching and consuming of events.


if (response instanceof StateAwareResponse) {
	StateAwareResponse stateResponse = (StateAwareResponse)
response;
	stateResponse.setEvent(Foo.QNAME, new Bar());
}

Then you must also create the event handler class by implementing the BridgeEventHandler interface to process the event payload.


public class BookingEventHandler implements BridgeEventHandler
  {
public EventNavigationResult handleEvent(FacesContext context,
Event event)
	{
		//process event payload here
	}
  }

Public Render Parameters

Public Render Parameters (or PRPs) are one of the most powerful and simple Portlet 2.0 features. Several portlets (JSF or not) can share the same render parameters. This feature can be used to present a cohesive UI to the user across all portlets on the page (i.e., using an employee ID to display relative data).

The bridge maps a render parameter to a backing bean using settings in your faces-config.xml and portlet.xml. A clear and working example can be found below.

You must define the following init params in your portlet.xml.


<init-param>
<name>javax.portlet.faces.bridgePublicRenderParameterHandler</name>
<value>org.foo.PRPHandler</value>
</init-param>
...
<supported-public-render-parameter>hotelName</supported-publicrender-
parameter>


Create a managed bean and public-parameter-mapping in your faces-config.xml. This should be a simple bean that you can bind the passed parameter to a string with getter and setter.


<managed-bean>
	<managed-bean-name>bookingPRP</managed-bean-name>
	<managed-bean-class>your.class.Name</managed-bean-class>
	<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<application>
  <application-extension>
	 <bridge:public-parameter-mappings>
	   <bridge:public-parameter-mapping>
		 <parameter>portletName:hotelName</parameter>
		 <model-el>#{bookingPRP.hotelName}</model-el>
	   </bridge:public-parameter-mapping>
	 </bridge:public-parameter-mappings>
  </application-extension>
</application>

Hot Tip

The <parameter> must contain the name of your portlet followed by the parameter name defined in <supportedpublic- render-parameter> from the portlet.xml.

You can set the public render parameter in the JSF or Seam backing bean as follows:


if (response instanceof StateAwareResponse) {
	StateAwareResponse stateResponse = (StateAwareResponse) response;
	stateResponse.setRenderParameter(“hotelName”,selectedHotel.
getName());
}

And finally, in the receiving portlet, you must also implement the BridgePublicRenderParameterHandler interface to process any updates from the received parameter.


public void processUpdates(FacesContext context)
{
ELContext elContext = context.getELContext();
BookingPRPBean bean = (BookingPRPBean) elContext.getELResolver().
getValue(elContext, null, “bookingPRP”);
if(null != bean){
  //Do something with bean.getHotelName());
} else {
}
}

Hot Tip

You can find a working example using all coordination features running on JSF 1.2, RichFaces and Seam here: http://bit.ly/seambooking

SERVING JSF RESOURCES, THE PORTLET WAY

The below example shows how to create a simple bean that uses the portlet resource serving mechanism within a JSF portlet.

By creating a simple class (and defining it in your faces-config.xml) that implements the java.util.Map interface, you can create a “ResourceBean” that will make life much easier on the UI.


public String get(Object key) {
	FacesContext facesContext = FacesContext.getCurrentInstance();
	String url = null;
	if(null == key){
		url = null;
	} else if(null != facesContext){
		url = facesContext.getApplication().getViewHandler().
 getResourceURL(facesContext, key.toString());
		url = facesContext.getExternalContext().encodeResourceURL(url);
	} else {
		url = key.toString();
	}
	  return url;
	}
}

From here, you can serve images and other resources based in your web application by using:


#{resource[‘/img/the-path-to-my-image.png’]}

The source for this example can be found here: http://bit.ly/resourcebean

DEVELOPER TIPS & TRICKS

Excluding Attributes from the Bridge Request Scope

When your application uses request attributes on a per request basis and you do not want that particular attribute to be managed in the extended bridge request scope, you must use the following configuration in your faces-config.xml. Below you will see that any attribute namespaced as foo.bar or any attribute beginning with foo.baz(wildcard) will be excluded from the bridge request scope and only be used per that application’s request.


<application>
<application-extension>
  <bridge:excluded-attributes>
	<bridge:excluded-attribute>foo.bar</bridge:excludedattribute>
attribute>
	<bridge:excluded-attribute>foo.baz.*</bridge:excludedattribute>
attribute>
	</bridge:excluded-attributes>
</application-extension>
</application>

Hot Tip

“From The Spec...” To support Faces, the bridge is responsible for encoding portlet (action) responses in a manner that allows it (and Faces) to reestablish the request environment that existed at the end of the corresponding action phase during subsequent render requests that are identified as pertaining to that action (or event). The term used to describe the scope of this managed data is the bridge request scope.

Supporting PortletMode Changes

A PortletMode represents a distinct render path within an application. There are three standard modes: view, edit and help. The bridge’s ExternalContext.encodeActionURL recognizes the query string parameter javax.portlet.faces.PortletMode and uses this parameter’s value to set the portlet mode on the underlying portlet actionURL or response. Once processed, it then removes this parameter from the query string. This means the following navigation rule causes one to render the \edit.jspx viewId in the portlet edit mode:


<navigation-rule>
	<from-view-id>/register.jspx</from-view-id>
	<navigation-case>
	   <from-outcome>edit</from-outcome>
	   <to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit</
to-view-id>
   </navigation-case>
</navigation-rule>

Hot Tip

PortletMode changes require an ActionRequest, so they cannot change modes during an Ajax or ResourceRequest.

Navigating to a mode’s last viewId

By default a mode change will start in the mode’s default view without any (prior) existing state. One common portlet pattern when returning to the mode one left after entering another mode (e.g.. view -> edit -> view) is to return to the last view (and state) of this origin mode. The bridge will explicitly encode the necessary information so that when returning to a prior mode it can target the appropriate view and restore the appropriate state. The session attributes maintained by the bridge are intended to be used by developers to navigate back from a mode to the last location and state of a prior mode. As such, a developer needs to describe a dynamic navigation: “from view X return to the last view of mode y”. This is most easily expressed via an EL expression. E.g.


<navigation-rule>
	<from-view-id>/edit.jspx*</from-view-id>
	<navigation-case>
	  <from-outcome>view</from-outcome>
	  <to-view-id>#{sessionScope[‘javax.portlet.faces.viewIdHistory.
  view’]}</to-view-id>
	</navigation-case>
</navigation-rule>


Hot Tip

You should always wildcard your viewId’s as shown in the above from-view-id. Developers are encouraged to use such wildcarding to ensure they execute properly in the broadest set of bridge implementations.

Clearing The View History When Changing Portlet Modes

By default, the bridge remembers the view history when you switch to a different portlet mode (like “Help” or “Edit”). You can use the following parameter in your portlet.xml to use the default viewId each time you switch modes.


<init-param>
	<name>javax.portlet.faces.extension.resetModeViewId</name>
	<value>true</value>
</init-param>

General Error Handling

Hot Tip

If you’re developing a Seam portlet, you can continue to use pages.xml for all error handling.

The following configuration may be used to handle exceptions. This is also useful for handling session timeout and ViewExpiredExceptions. Pay attention to the location element. It must contain the /faces/ mapping to work properly.


<error-page>
	<exception-type>javax.servlet.ServletException</exception-type>
	<location>/faces/error.xhtml</location>
</error-page>
<error-page>
	<exception-type>javax.faces.application.ViewExpiredException</
exception-type>
	<location>/faces/error.xhtml</location>
</error-page>

Custom Ajax Error Handling

By default, error handling is sent to a standard servlet page for Ajax requests. To handle the error inside the portlet, use the following javascript:


<script type=”text/javascript”>
  A4J.AJAX.onError = function(req,status,message){
	window.alert(“Custom onError handler “+message);
  }
  A4J.AJAX.onExpired = function(loc,expiredMsg){
	if(window.confirm(“Custom onExpired handler “+expiredMsg+” for a
location: “+loc)){
		return loc;
	} else {
		return false;
	}
  }
</script>

Also, add the following to web.xml.


<context-param>
	<param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
	<param-value>true</param-value>
</context-param>

Hot Tip

Remember to provide a link to the normal flow of your JSF application from your error page. Otherwise, the same error page will be displayed forever.

Communication Between Your Portlets

There are roughly 4 different ways to send messages, events, and parameters between portlets which are contained in different ears/wars or contained in the same war. The Portlet Container does not care if you have 2 portlets in the same war or if they are separated, because each portlet has a different HttpSession.

Of course, with the Portlet 2.0 spec, the recommended way to share a parameter or event payload between 2 or more portlets are the Section 3.4.2, “Public Render Parameters” and Section 3.4.1, “Sending and Receiving Events” mechanisms. This allows you to decouple your application from surgically managing objects in the PortletSession.APPLICATION_SCOPE.

But, if these do not meet your use case or you have a different strategy, you can use one of the following methods.

Storing Components in PortletSession.APPLICATION_SCOPE

Sometimes, it makes sense to store your Seam components in the portlet APPLICATION_SCOPE. By default, these objects are stored in the PORTLET_SCOPE; but with the annotation below, you can fish this class out of the PortletSession and use its values in other portlets across different Seam applications.


@PortletScope(PortletScope.ScopeType.APPLICATION_SCOPE)

Then you would pull the statefull object from the session:


YourSessionClass yourSessionClass = (YourSessionClass)
getRenderRequest().getAttribute(“javax.portlet.p./default/
seamproject/seamprojectPortletWindow?textHolder”);

Using the PortletSession

If you need to access the PortletSession to simply share a parameter/value across multiple portlets, you can use the following to do so.


Object objSession = FacesContext.getCurrentInstance().
getExternalContext().

getSession(false);
try
{
	if (objSession instanceof PortletSession)
	{
		PortletSession portalSession = (PortletSession)objSession;
		portalSession.setAttribute(“your parameter name”,”parameter
value”,PortletSession.APPLICATION_SCOPE);
	…
	
Then, in your JSP or Facelets page, you can use:
#{httpSessionScope[‘your parameter name’]}

Linking to Portlet/JSF Pages Using h:outputink

For linking to any JSF/Facelets page within your portlet web application, you may use the following.


<h:outputLink value=”#{facesContext.externalContext.
				requestContextPath}/home.xhtml”>
<f:param name=”javax.portlet.faces.ViewLink” value=”true”/>
navigate to the test page
</h:outputLink>

Redirecting to an External Page or Resource

To link to a non JSF view (i.e. jboss.org), you can use the following parameter.


<h:commandLink actionListener=”#{yourBean.yourListenr}”>
<f:param name=”javax.portlet.faces.DirectLink” value=”true”/>
navigate to the test page
</h:commandLink>

Then in your backing bean, you must call a redirect().


FacesContext.getCurrentInstance().
		getExternalContext().redirect(“http://www.jboss.org”);

Using Provided EL Variables

All EL variables found in the JSR-329 (Portlet 2.0) specification are available in the JBoss Portlet Bridge. For example, you can use the following to edit the portlet preferences on the UI.


<h:form>
  <h:inputText id=”pref” required=”true” value=”#{mutablePortletPrefe
rencesValues[‘userName’].value}” />
  <h:commandButton actionListener=”#{myBean.savePref}” value=”Save
Preferences” />
</h:form>

Then in your backing bean, you must call the PortletPreferences.store() method.


Object request = FacesContext.getCurrentInstance().
getExternalContext().getRequest();
PortletRequest portletRequest = (PortletRequest)request;
if (request instanceof PortletRequest) {
   try {
	 PortletPreferences portletPreferences = portletRequest.
										getPreferences();
	portletPreferences.store();

Remote Portlet Navigation Using Portlet Events

When you send events, you can also leverage the EventNavigationResult and return a JSF navigation rule. For example, by returning:


new EventNavigationResult(“fromAction”,”Outcome”);

The fromAction can be a wildcard “/*” or a nav rule defined in your faces-config.xml and outcome can be the from-outcome node defined in the faces-config.xml navigation rule.

CONCLUSION

With all the bitter sweetness that JSF and portal technologies offer, the portlet bridge does a good job of keeping everything in check. It also gives you possibilities that may not have been thought of when your JSF app was first created. Some examples are integration of legacy applications to leverage existing investments and the ability to develop newer frameworks and technologies without regression.

About The Authors

By Wesley Hales

By Wesley Hales

Wesley Hales is a software developer on several projects at JBoss, by Red Hat. He is the co-founder of the JBoss Portlet Bridge project, a senior developer on GateIn, and serves as the JBoss representative on the JSR 301 & 329 specifications.

Before working for Red Hat, Wesley focused mainly on web framework and UI-related technologies, thus leading to committer roles for Apache, Mozilla, and JBoss. Wesley produces a series of screencasts on vimeo for each bimonthly release of the bridge. He has written a host of articles on infoq.com and posts occasional tutorials to his blog on jroller.com.

For his sins, he evangelizes portlet and portlet bridge technologies at most major conferences including Jazoon, AjaxWorld, JUDCon, DevNexus and whichever ones a daring enough to have a portal talk in their schedule.

Recommended Book

Portlets in Action

Portlets in Action is a comprehensive guide for Java developers with minimal or no experience working with portlets. Fully exploring the Portlet 2.0 API and using widely adopted frameworks like Spring 3.0 Portlet MVC, Hibernate, and DWR, it teaches you portal and portlet development by walking you through a Book Catalog portlet and Book Portal examples. The example Book Catalog Portlet, developed incrementally in each chapter of the book, incorporates most key portlet features, and the accompanying source code can be easily adapted and reused by readers. The example Book Portal application introduces you to the challenges faced in developing web portals.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose - Seam 3 Goes Beta

JBoss' grand, all-encompassing Java development framework is nearly finished.  This weekend, the 3.0 version reached Beta 1 status.  It is the first release to have all of the Seam modules (Drools, Errai, Servlet, JBoss ESB, etc.) bundled into a single...

0 replies - 27562 views - 01/31/11 by Mitchell Pronsc... in Daily Dose

Daily Dose - Eclipse 3.7 and 4.1 Hit Milestone 4

Eclipse 3.7 "Indigo" and Eclipse 4.1, which is still aimed at early adopters, received new features in milestone 4 this week.  For both Eclipse versions, the milestone brings Equinox updates for the OSGi R4.3 spec, memory usage upgrades for p2, and...

0 replies - 22618 views - 12/14/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - Red Hat Acquires Makara

With their Apache-licensed DeltaCloud project and now with today's acquisition of a Cloud tech startup called Makara, RedHat is building a broad foundation for its position in the PaaS sphere.  I wrote about the emergence of Makara early this year and I was...

0 replies - 17554 views - 12/01/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - Eclipse Believes There is Hope for Java 8

Last month, Eclipse Executive Director Mike Milinkovich stated his reservations about the Jigsaw brand of modularity in Java 8.  It is now a surprise that Eclipse is supporting the new JSR for Java 8.  It was originally thought that the Jigsaw modularity...

2 replies - 23260 views - 11/24/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - U.S. Dept. of Justice Receives Complaint About Oracle Tactics

"Oracle’s position appears to be the most onerous and draconian of any major hardware manufacturer," claims Claudia Betzner, the executive director of the US Service Industry Association (SIA).   That was a quote from the SIA's recent letter to...

0 replies - 24225 views - 11/19/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - Seam 3 Goes Beta!

The first beta for JBoss' Seam 3.0 framework is now available.  It requires Weld 1.0.1 Beta 1+ and JBoss logging instead of SLF4J.  This release includes an early integration of Seam Managed Transactions, an input field container component, and a bugfix for...

1 replies - 17431 views - 11/04/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - GWT 2.1 RC1 Adds 2.2 Features

Developers are getting GWT (Google Web Toolkit) features that were originally planned for version 2.2 by downloading the 2.1 RC1 version, which was just released.  GWT 2.1 features a Model-View-Presenter framework that introduces the concepts of Activities...

0 replies - 20616 views - 10/13/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - Apache Celebrates its Millionth Code Commit

lucene/ r1000000 yonik SOLR-2128: full param substitution for function queriesThis was the 1,000,000th commit at the Apache Foundation this week contributed by Yonik Seeley, the creator of Apache Solr.  The commit was to Solr's parent project, Lucene. ...

0 replies - 15579 views - 09/23/10 by Mitchell Pronsc... in Daily Dose

Daily Dose - Solaris 10 Update Arrives Ahead of OpenWorld

They couldn't wait ten more days for Oracle OpenWorld to release an update to the Solaris 10 operating system.  Oracle has quietly released the update along with new Solaris Cluster software and Solaris Studio development tools.  John Fowler explains the...

0 replies - 15130 views - 09/13/10 by Mitchell Pronsc... in Daily Dose

Getting Started with Infinispan

By Manik Surtani

6,834 Downloads · Refcard 115 of 151 (see them all)

Download
FREE PDF


The Essential Infinispan Cheat Sheet

Infinispan is an open source data grid platform from JBoss. Data grids are commonly used as low-latency, highly-available and elastic data storage backends, often as NoSQL solutions. Data grids are often used in addition to traditional databases, as a distributed cache for fast data access. Infinispan is LGPL licensed and is backed by an active, open and welcoming developer and user community! This DZone Refcard covers everything from Operational Modes and JVM Languages on Infinispan, to XML Schemas and Migrating from other Data Grid Systems.
HTML Preview
Getting started with Infinispan

Getting started with Infinispan

By Manik Surtani

OPEN SOURCE DATA GRIDS

What is Infinispan?

Infinispan is an open source data grid platform. Data grids are commonly used as low-latency, highly-available and elastic data storage backends, often as NoSQL solutions.

Data grids are often used in addition to traditional databases, as a distributed cache for fast data access.

Hot Tip

Infinispan is LGPL licensed and is backed by an active, open and welcoming developer and user community!

For more information, visit http://www.infinispan.org

How can I get it?

The best way to use Infinispan in your project is via Maven. Infinispan’s Maven coordinates are:

Hot Tip

<dependencies> … <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-core</artifactId> <version>LATEST_INFINISPAN_VERSION</version> </dependency> … </dependencies>

However you would need to add the JBoss community projects Maven repository to your list of repositories to be able to locate and use Infinispan artifacts.


<repositories>
  …
  <repository>
    <id>jboss.org</id>
      <url>http://repository.jboss.org/nexus/content/groups/
      public</url>
    <releases><enabled>true</enabled></releases>
    <snapshots><enabled>true</enabled></snapshots>
  </repository>
  …
</repositories>

I don’t use Maven. Where can I download binaries?

If you do not use Maven, or wish to run an Infinispan server (rather than in embedded, peer-to-peer mode), you can also download compiled binaries from http://www.jboss.org/infinispan/downloads

OPERATIONAL MODES

Client/server or peer-to-peer?

There are two ways in which you can interact with Infinispan. One is in embedded mode, where you start an Infinispan instance within your JVM. The other is client/server mode, where you start a remote Infinispan instance and connect to it using a client connector.

Your choice on which mode of interaction to use will depend on a number of factors, including whether you are using Infinispan as a clustering toolkit to cluster your own framework, whether you intend to use Infinispan to cache database lookups, or whether you plan to interact with Infinispan from a non-JVM environment. These are discussed in more detail at http://community.jboss.org/wiki/ InfinispanServerModules

Embedded (p2p) mode

When used in this mode, Infinispan instances reside within your JVM alongside your code. You start up multiple instances of your application on different servers and each one starts and initializes an Infinispan instance. These Infinispan instances discover each other, form a data grid, and start sharing and distributing data.

This mode is what you will want to use if you are building an application or a framework that needs to be cluster-aware, or if you need an in-memory distributed cache to front a database or some other expensive data source.

A practical example

To see this in action, make sure the Infinispan libraries are available to your code—either via Maven, as above, or via downloading the zipped distribution and extracting the jar files.

Hot Tip

Infinispan’s core construct is an instance of the Cache interface. Extending java.util.Map, Cache exposes simple methods to store and retrieve objects.

Starting Infinispan instances from your code is simple. To start a local, non-clustered cache instance:


DefaultCacheManager m = new DefaultCacheManager();
Cache c = m.getCache();
c.put(“hello”, “world”);

To start a cluster-aware instance capable of detecting neighboring instances on the same local area network and sharing state between them:


GlobalConfiguration globalConf = GlobalConfiguration.
getClusteredDefault();
Configuration cfg = new Configuration();
Cfg.setCacheMode(Configuration.CacheMode.DIST_SYNC);
DefaultCacheManager m = new DefaultCacheManager(globalConf, cfg);
Cache c = m.getCache();
c.put(“hello”, “world”);
c.containsKey(“hello”); // returns true
c.get(“hello”); // returns “world”
c.remove(“hello”); // returns “world”

This can also be done using a configuration file:


String configFile = “/path/to/my/infinispan_config.xml”;
DefaultCacheManager m = new DefaultCacheManager(configFile);
Cache c = m.getCache();
c.put(“hello”, “world”);
c.containsKey(“hello”); // returns true
c.get(“hello”); // returns “world”
c.remove(“hello”); // returns “world”

Embedded Infinispan and other JVM languages

Since Infinispan complies to Java byte code, it can be used by other JVM languages as well, such as Jython, JRuby, Scala and Groovy, provided the necessary libraries are available on the classpath. Here is an example of starting an embedded Infinispan instance in a Groovy console:


groovy:000> import org.infinispan.* [import org.infinispan.*]
groovy:000> import org.infinispan.manager.* [import org.infinispan.*, import org.infinispan.manager.*]
groovy:000> m = new DefaultCacheManager() org.infinispan.manager.DefaultCacheManager@1a8fa0d1@Address:null
groovy:000> c = m.getCache() Cache ‘___defaultcache’@574813774
groovy:000> c.put(“hello”, “world”) null
groovy:000> c.get(“hello”) world
groovy:000> c.remove(“hello”) world

Client/server mode

You may not always want Infinispan instances to reside in the same JVM as your application. Sometimes this is for security, sometimes for architectural reasons to maintain a separate data layer, but this can also be because your client application is not on a JVM platform. For example, .NET or C++ clients can also make use of Infinispan if Infinispan is run as a remote server.

Hot Tip

A good discussion of remote data storage architectures using data grids can be found here: http://java.dzone.com/articles/data-service-datafabric

Infinispan comes with several different server endpoints, speaking a variety of protocols. Here is a comparison of the protocols that can be used with Infinispan:

server comparison

STARTING AN INFINISPAN SERVER

Starting an Infinispan server is pretty easy. You need to download and unzip the Infinispan distribution and use the startServer script. E.g.,


$ bin/startServer.sh -r hotrod

The script takes in a set of switches to control the endpoint behavior:


$ bin/startServer.sh --help
usage: startServer [options]
options:
-h, --help Show this help message
-V, --version Show version information
-- Stop processing options
-p, --port=<num> TCP port number to listen on (default: 11211 for
Memcached, 11311 for Hot Rod and 8181 for WebSocket server)
-l, --host=<host or ip> Interface to listen on (default: 127.0.0.1,
localhost)
-m, --master_threads=<num> Number of threads accepting incoming
connections (default: unlimited while resources are available)
-t, --work_threads=<num> Number of threads processing incoming
requests and sending responses (default: unlimited while resources
are available)
-c, --cache_config=<filename> Cache configuration file (default:
creates cache with default values)
-r, --protocol= Protocol to understand by the server. This is
a mandatory option and you should choose one of these options:
[memcached|hotrod|websocket]
-i, --idle_timeout=<num> Idle read timeout, in seconds, used to
detect stale connections (default: -1). If no new messages have been
read within this time, the server disconnects the channel. Passing
-1 disables idle timeout.
-n, --tcp_no_delay=[true|false] TCP no delay flag switch (default:
true).
-s, --send_buf_size=<num> Send buffer size (default: as defined by
the OS).
-e, --recv_buf_size=<num> Receive buffer size (default: as defined
by the OS).
-o, --proxy_host=<host or ip> Host address to expose in topology
information sent to clients. If not present, it defaults to
configured host. Servers that do not transmit topology information
ignore this setting.
-x, --proxy_port= <num> Port to expose in topology information sent
to clients. If not present, it defaults to configured port. Servers
that do not transmit topology information

Starting the REST endpoint

Infinispan ships a REST endpoint as a web archive (.WAR file). To start the REST endpoint, simply deploy this WAR file in a servlet container of your choice, such as JBoss Application Server or Apache Tomcat.

Connecting using Java

You have a choice of protocols and clients you can use if connecting from a Java application.

If using the REST endpoint, all you need is a simple HTTP client library, such as Apache’s HTTPClient.

First, you need to make sure you have Apache HTTPClient in your classpath — by declaring it as a Maven dependency or by downloading the jars. Also make sure you have the Infinispan REST module deployed and available.

Now you can connect t o the REST endpoint:


HttpClient client = new HttpClient();
String cacheName =”___defaultcache”;
String key = “hello”;
String url = “http://infinispan_host/infinispan-server-rest/rest/” +
cacheName + “/” + key;

// Storing data
PutMethod put = new PutMethod(url);
put.setRequestHeader(“Content-type”, “text/plain”);
put.setRequestBody(“world”);
client.executeMethod(put);

// Retrieving data
GetMethod get = new GetMethod(url);
client.executeMethod(get);
System.out.printf(“Value of key %s is %s”, key, get.
getResponseBodyAsString());

If you choose to use the memcached protocol, the SpyMemcached library can be used. Again, you would need to make sure you have SpyMemcached in your classpath.


InetSocketAddress addr = new InetSocketAddress(“infinispan_host”,
portNum);
MemcachedClient c=new MemcachedClient(addr);
// Storing data
String key = “hello”
c.set(key, -1, “world”);
// Retrieving data
String result = c.get(key);
System.out.printf(“Value of key %s is %s”, key, result);

Finally, if you wish to use Hot Rod, you would need to declare a dependency on Infinispan’s Hot Rod Java client library:


<dependencies>
  …
  <dependency>
  <groupId>org.infinispan</groupId>
  <artifactId>infinispan-client-hotrod</artifactId>
  <version>LATEST_INFINISPAN_VERSION</version>
  </dependency>
  …
</dependency>

The Hot Rod client jar files are also included in the Infinispan zipped distribution.

Using the client is very much like using the embedded API:


RemoteCacheManager rcm = new RemoteCacheManager(“infinispan_host”);
RemoteCache rc = rcm.getCache();
String key = “hello”;

// Storing data
rc.put(key, “world”);

// Retrieving data
System.out.printf(“Value of key %s is %s”, key, rc.get(key));

Connecting using non-JVM platforms

Infinispan supports connecting to the data grid from non-Java platforms. The simplest option is to use the REST endpoint. Here is an example of connecting to the Infinispan REST endpoint using a Python script:


import httplib

cache_name = “___defaultcache”
key = “hello”

// Storing data
conn = httplib.HTTPConnection(“infinispan_host”)
conn.request(“PUT”, “/infinispan-server-rest/rest/%s/%s” % (cache_
name, key), “world”, {“Content-Type”: “text/plain”})

// Retrieving data
conn = httplib.HTTPConnection(“infinispan_host”)
conn.request(“GET”, “/infinispan-server-rest/rest/%s/%s” % (cache_
name, key))
print “Value of key %s is %s” % (key, conn.getresponse().read())

If running the memcached endpoint, it is possible for clients to connect using any existing memcached client library. This example uses the memcached library for Python:


import memcache

conn = memcache.Client([“infinispan_host”])
key = “hello”

// Storing data
conn.set(key, “world”)

// Retrieving data
print “Value of key %s is %s” % (key, conn.get(key))

Hot Rod, too, can be used from non-JVM platforms. However, as of September 2010, the only known client libraries for Hot Rod are written in Java.

Hot Tip

The protocol specification is published online and the community is encouraged to write more client implementations for Hot Rod. The Java client can be used as a reference implementation, as its source code is open and publicly available

.Load-balancing server endpoints

Infinispan’s endpoints support load balancing and failover to some degree. Different endpoints offer different degrees of support.

The REST endpoint is the simplest, delegating all load balancing and failover responsibility to an external HTTP load balancer. Software load balancers such as mod_cluster and hardware load balancers could be used. You should refer to your servlet container documentation for details on load balancing. The memcached endpoint — like all memcached servers — delegates the task of load balancing and failover to the memcached client. Most memcached client libraries have support for load balancing and failover, provided they are initialized with a static list of servers to connect to.

Hot Rod provides the most flexibility in terms of load balancing and failover.

Hot Tip

The Hot Rod protocol has been designed specifically with load balancing and failover in mind.

Clients can be written to take advantage of the server topology that is provided to clients and regularly kept up-to-date. Clients can even be made aware of hash functions used on the back-end, so routing requests to a cluster of back-end nodes can be done in an intelligent fashion to minimize latency and remote lookup on the back-end. The reference implementation Java client makes use of such features and provides built-in load-balancing, failover, discovery of new backend nodes, as well as intelligent routing of requests. More details on the Java client can be found online.

ANATOMY OF AN INFINISPAN CONFIGURATION FILE

Infinispan’s configuration file is written in XML. Sensible defaults are used throughout, and the simplest configuration file contains just the following:


<infinispan />

This defines local, non-clustered caches using defaults throughout.

A basic clustered configuration looks like:


<infinispan>
 <global>
	<transport />
 </global>

 <default>
	<clustering mode=”R”>
		<sync />
	</clustering>
 </default>
</infinispan>

The default configuration is used as a template configuration when calling DefaultCacheManager.getCache(). When calling DefaultCacheManager.getCache(cacheName), a clone of the default configuration is made. E.g.:


DefaultCacheManager cm =
new DefaultCacheManager(“configuration.xml”);

// returns the default cache
Cache cache = cm.getCache();

// returns a new cache, with a configuration cloned from the default>
Cache anotherCache = cm.getCache(“another”);

You can also name caches in your configuration file, such as:


<infinispan>
	<global>
		<transport />
	</global>

	<default>
		<clustering mode=”R”>
	  		<sync />
		</clustering>
	</default>

	<namedCache name=”asyncCache”>
		<clustering mode=”R”>
	 		 <async />
		</clustering>
	</namedCache>
</infinispan>

With this configuration, DefaultCacheManager.getCache() would return a simple, synchronously replicated cache.

DefaultCacheManager.getCache(“asyncCache”) would, however, return an asynchronously replicated cache.


DefaultCacheManager cm = new DefaultCacheManager(“configuration.
xml”);

// returns the default cache – one that is synchronously replicated!
Cache cache = cm.getCache();

// returns an asynchronously replicated cache
Cache asyncCache = cm.getCache(“asyncCache”);

Named caches are hierarchical too, so they all inherit from the default. In the example below, the cache named “transactional” extends from the default cache. As such, the cache named “transactional” will also be synchronously replicated.


<infinispan>
  <global>
	<transport />
  </global>

  <default>
<clustering mode=”R”>
		<sync />
</clustering>
  </default>

  <namedCache name=”transactional”>
<transaction
	transactionManagerLookupClass=”org.infinispan.transaction.lookup.
GenericTransactionManagerLookup”/>
  </namedCache>
</infinispan>


DefaultCacheManager cm = new DefaultCacheManager(“configuration.
xml”);

// returns the default cache – one that is synchronously replicated!
Cache cache = cm.getCcahe();

// returns an transactional, synchronously replicated cache
Cache txCache = cm.getCache(“transactional”);

XML Schemas

Infinspan makes use of an XML schema to validate configuration files.

The schema is packaged with the infinispan-core.jar archive, and is also available online at http://www.infinispan.org/ schemas/infinispan-config-4.0.xsd

Typically, you would start your XML file with the following declaration:


<?xml version=”1.0” encoding=”UTF-8”?>
<infinispan
	xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation=”urn:infinispan:config:4.0 http://www.
infinispan.org/schemas/infinispan-config-4.0.xsd”
	xmlns=”urn:infinispan:config:4.0”>
… Your Infinispan configuration …
</infinispan>

If you were to start your configuration file with a reference to this XML schema, XML authoring tools will help validate your configuration file.

Hot Tip

Some tools even provide autocomplete suggestions!

For example:

config

Commonly used configuration elements

Global selection

Element Name Element Description
transport This element configures the transport used for network communications across the cluster.
serialization Serialization and marshalling settings
shutdown This element specifies behavior when the JVM running the cache instance shuts down.
globalJmxStatistics This element specifies whether global statistics are gathered and reported via JMX for all caches under this cache manager.
replicationQueueScheduledExecutor Configuration for the scheduled executor service used to periodically flush replication queues, used if asynchronous clustering is enabled along with useReplQueue being set to true.
asyncTransportExecutor Configuration for the executor service used for asynchronous work on the Transport, including asynchronous marshalling and Cache ‘async operations’ such as Cache.putAsync().
evictionScheduledExecutor Configuration for the scheduled executor service used to periodically run eviction cleanup tasks.
asyncListenerExecutor Configuration for the executor service used to emit notifications to asynchronous listeners.

Default/NamedCache sections

Element Name Element Description
transaction Defines transactional (JTA) characteristics of the cache.
invocationBatching Defines whether invocation batching is allowed in this cache instance, and sets up internals accordingly to allow use of this API.
loaders Holds the configuration for cache loaders and stores.
clustering Defines clustered characteristics of the cache.
lazyDeserialization A mechanism by which serialization and deserialization of objects is deferred until the point in time in which they are used and needed. This typically means that any deserialization happens using the thread context class loader of the invocation that requires deserialization, and is an effective mechanism to provide classloader isolation.
deadlockDetection This element configures deadlock detection.
eviction This element controls the eviction settings for the cache.
customInterceptors Configures custom interceptors to be added to the cache.
unsafe Allows you to tune various unsafe or non-standard characteristics. Certain operations such as Cache.put() that are supposed to return the previous value associated with the specified key according to the java.util.Map contract will not fulfill this contract if unsafe toggle is turned on. Use with care. See details at http://www.jboss.org/ community/wiki/infinispantechnicalfaqs
jmxStatistics This element specifies whether cache statistics are gathered and reported via JMX.
locking Defines the local, in-VM locking and concurrency characteristics of the cache.
indexing Configures indexing of entries in the cache for searching. Note that infinispan-query.jar and its dependencies needs to be available if this option is to be used.
expiration This element controls the default expiration settings for entries in the cache.

MIGRATING FROM OTHER DATA GRID OR CACHE SYSTEMS

Infinispan provides a number of tools to help you migrate configurations from EHCache, Oracle Coherence and even JBoss Cache to Infinispan. These command-line tools help in the migration process.


$ bin/importConfig.sh
Missing ‘source’, cannot proceed
Usage:
importConfig [-source <the file to be transformed>] [-destination
<where to store resulting XML>] [-type <the type of the source,
possible values being: [Coherence35x, Ehcache1x, JBossCache3x] >]

Further, Infinispan’s Cache interface is compliant with JSR-107 (JCACHE), which means applications written against other JSR-107-like caches will work with minimal modifications.

More information

Please visit http://community.jboss.org/wiki/Infinispan for more detailed information on Infinispan, including an easy-touse configuration reference.

About The Authors

Photo of author By MANIK SURTANI

MANIK SURTANI

MANIK SURTANI, is a Principal Software Engineer and core JBoss research and development engineer at Red Hat. He is the founder of the Infinispan project, which he currently leads along with the JBoss Cache project. His interests lie in cloud and distributed computing, autonomous systems, and highly-available computing.

Manik has a background in artificial intelligence and neural networks, a field that he left behind when he moved from academic circles to the commercial world. Since then, he worked with Java-related technologies at a start-up company that focused on knowledge management and information exchange. He also worked as a technical lead focusing on e-commerce applications on large Java EE and peer-to-peer technology for a London-based consultancy. Manik is a strong proponent of open source development methodologies, ethos, and collaborative processes, and has been involved in open source since his first forays into computing.

Recommended Book

Hibernate Search in action

Good search capability is one of the primary demands of a business application. Engines like Lucene provide a great starting point, but with complex applications it can be tricky to implement. It’s tough to keep the index up to date, deal with the mismatch between the index structure and the domain model, handle querying conflicts, and so on.

Hibernate Search is an enterprise search tool based on Hibernate Core and Apache Lucene. It provides full text search capabilities for Hibernate-based applications without the infrastructural code required by other search engines. With this free, open-source technology, you can quickly add high-powered search features in an intelligent, maintainable way.

Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose - Virgo M4 Prepares for Equinox Upgrade

The first beta of the Virgo Web Server (formerly the Spring dm Server) is getting very close now that the Eclipse Foundation released the fourth milestone recently.  M4 features various build and test improvements along with several bugfixes.  OSGi...

0 replies - 16010 views - 09/07/10 by Mitchell Pronsc... in Daily Dose