We're pleased to announce that 3.3.1.Final of Portlet Bridge was released just before the holidays. In all the holiday madness I forgot to make the release announcement!
Some highlights from the release:
For full details of what was contained in the release, check out the release notes.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.1.Final</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.1.Final</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.1.Final</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.3.0.Final of Portlet Bridge is now available!
As there were no issues to be resolved for 3.3.0.Final, this is essentially a respin of 3.3.0.CR1 with an updated version number.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.Final</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.Final</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.Final</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
With the latest release of the Arquillian Portal Extension, 1.1.0.Alpha1, we can now use Arquillian Warp to test the server side behavior of our JSF portlets! I'm very excited by this as it has been something I've wanted, and worked to achieve, for a while now.
To be able to take advantage of all this goodness, we need to add the Portlet extension for Warp to our build:
<dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-portal-warp-jsf</artifactId> <version>1.1.0.Alpha1</version> </dependency>
Currently this version of the Arquillian Portal Extension will bring with it Arquillian Warp 1.0.0.Alpha5. When a new version is released, it would be possible to take advantage of the new features it provides by directly importing the Warp BOM ahead of the above dependency. Of course that is providing that no Warp APIs changed which result in the Portal extension to break!
Ok, so lets create a JSF portlet to test this puppy out!
Here's a simple JSF page we can use:
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xml:lang="en" lang="en"> <h:head></h:head> <h:body> <h:form> <h:inputText id="input" value="#{bean.text}" /> <h:commandButton id="submit" value="Ok" action="#{bean.action}" /> </h:form> </h:body> </f:view>
And the JSF bean that it uses:
@ManagedBean @RequestScoped public class Bean { private String text = "original"; public String getText() { return text; } public void setText(String value) { this.text = value; } public String action() { return null; } }
We have a simple form with one field, that doesn't really do much, but we don't need it to to show the benefit of Warp and JSF portlets.
Now the fun part, writing the test!
Annotated on the test class we need to specify we're using Arquillian, Warp, and the Portal extension. For this we need:
@RunWith(Arquillian.class) @WarpTest @PortalTest
Obviously you need to define the @Deployment method, including our bean and JSF page into the test archive, along with Portlet Bridge:
@Deployment public static PortletArchive createDeployment() { PortletArchive archive = ShrinkWrap.create(PortletArchive.class, "JSFPortletWarp.war"); File[] libs = Maven.resolver() .loadPomFromFile("pom.xml") .resolve("org.jboss.portletbridge:portletbridge-impl") .withTransitivity() .asFile(); archive.createFacesPortlet("JsfFormSubmit", "JSF Form Portlet", "form.xhtml") .addAsWebResource("form.xhtml", "form.xhtml") .addClass(Bean.class) .addAsLibraries(libs); return archive; }
We need to be able to access the input field and submit button in the browser, so we use Graphene:
@FindByJQuery("[id$=':input']") private WebElement inputField; @FindByJQuery("[id$=':submit']") private WebElement submitButton;
We use the JQuery FindBy from Graphene as JSF prefixes the ids we specified on the JSF page with auto generated ones. With the above id selector, we're saying that we know the id ends with that text, but it could start with anything.
And of course we need to inject Drone, for controlling the browser, and the URL to the portlet instance:
@Drone WebDriver browser; @ArquillianResource @PortalURL URL portalURL;
Now we get to the most interesting bit, actually using Warp in a test on a JSF portlet!
For our test we're going to set some new text into the input field, and then verify that the JSF Update Model Values lifecycle phase correctly sets the new value onto our bean:
@RunAsClient @Test public void testSettingValue() { browser.navigate().to(portalURL); Warp .initiate(new Activity() { public void perform() { inputField.clear(); inputField.sendKeys("modified"); submitButton.click(); } }) .observe(request().index(1)) .inspect(new Inspection() { private static final long serialVersionUID = 1L; @ManagedProperty("#{bean}") Bean bean; @PortletPhase(ACTION) @BeforePhase(Phase.UPDATE_MODEL_VALUES) public void testBeanValueBeforeUpdate() { assertEquals("original", bean.getText()); } @PortletPhase(ACTION) @AfterPhase(Phase.UPDATE_MODEL_VALUES) public void testBeanValueAfterUpdate() { assertEquals("modified", bean.getText()); } }); }
Wow, that looks complicated! Well it does seem that way when you first look at writing a Warp test, but once you've done it a few times you get the hang of it.
Here's an explanation of what we're doing above in the test method:
Line 4 - Navigates to the portlet page in the browser. This isn't done as part of a Warp Activity because we're not Inspecting anything as a result of rendering the portlet, but that is certainly something you could do.
Lines 9-11 - Update the input field to the new value and then submit the form in the browser. This is defined as part of a Warp Activity, meaning that when these browser actions have completed Warp will look for requests that occur as a result of what we did in the browser, to run the Inspection against.
Line 14 - Define a Warp group, as we only want to perform an Inspection against a specific request. NB: The GateIn portlet container will cause two requests to occur as a result of a form submission: one for the ActionRequest and another for the RenderRequest.
Line 14 - This group will observe the first request that Warp encounters, which in this case will be the ActionRequest. NB: The GateIn portlet container will cause two requests to occur as a result of a form submission: one for the ActionRequest and another for the RenderRequest.
Lines 15-16 - Create a new Inspection to be passed to the server for execution. At present it is necessary to manually add the serial version id, but this is planned to be fixed in a future Warp release.
Lines 18-19 - Injects the JSF bean into our Inspection. It's possible to inject Portlet request and response objects, JSF beans, or JSF objects (such as FacesContext) into an Inspection.
Line 21 - This Inspection method will run during the ActionRequest, specified by @PortletPhase(ACTION), and before the JSF Update Model Values lifecycle phase
Line 26 - This inspection method will run during the ActionRequest as well, but after the JSF Update Model Values lifecycle phase
For examples of other ways to use Warp with Portlets, you can take a look here and here.
With the latest Arquillian Portal Extension it opens up new ways to test JSF portlets, without ever having to deploy them to a portal!
We're pleased to announce that 3.3.0.CR1 of Portlet Bridge is now available!
Full details of what is contained within the release can be found in the Release Notes.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.CR1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.CR1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.CR1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.3.0.Beta2 of Portlet Bridge is now available!
Full details of what is contained within the release can be found in the Release Notes.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.Beta2</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.Beta2</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.Beta2</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.3.0.Beta1 of Portlet Bridge is now available!
Full details of what is contained within the release can be found in the Release Notes.
Previously, the Faces ViewRoot was stored in the Bridge Request Scope on completion of a RenderRequest, which is used to reconstitute the state of the portlet in JSF for future rendering. That behavior made it more performant when re-rendering a portlet repeatedly without the data being altered, but it does pose problems when developing more modern JSF 2 portlets.
The default behavior, from this release, is that any data will not be retained for use on any subsequent re-rendering of the portlet page. It's possible to revert to the previous behavior by setting the following context param in web.xml:
<context-param> <param-name>org.jboss.portletbridge.BRIDGE_SCOPE_PRESERVED_POST_RENDER</param-name> <param-value>true</param-value> </context-param>
Full details on these configuration settings can be found in the documentation.
Previously, the Portlet Bridge would prefix all JSF Component Ids with a full namespace generated by the PortletResponse. The default behavior from this release mean that we shorten those namespace prefixes to a level where will still be unique, but significantly improve the readability of the generated portlet content as well as reduce the amount of data being transmitted between the client and server.
It's possible to revert to the old behavior of the long namespaces by setting the following context param in web.xml:
<context-param> <param-name>org.jboss.portletbridge.COMPONENT_NAMESPACE_SHORTENED</param-name> <param-value>false</param-value> </context-param>
Full details on these configuration settings can be found in the documentation.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.Beta1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.Beta1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.Beta1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.3.0.Alpha3 of Portlet Bridge is now available!
Full details of what is contained within the release can be found in the Release Notes.
Previously, any updates to JSF Managed Beans or attributes on the Faces Context were stored in the Bridge Request Scope, which is used to reconstitute the state of the portlet in JSF for future rendering. That default behavior is a relic of the most recent Bridge specification, which is based on JSF 1.2! In a world where Ajax requests are more prevalent, it makes sense to provide some flexibility around how data is retained during an Ajax request.
The default behavior, from this release, is that any data updated during an Ajax request will not be retained for use on any subsequent re-rendering of the portlet page. It's possible to revert to the previous behavior by setting the following context param in web.xml:
<context-param> <param-name>org.jboss.portletbridge.BRIDGE_SCOPE_ENABLED_ON_AJAX_REQUEST</param-name> <param-value>true</param-value> </context-param>
As part of this change we also added a new parameter that can be used to disable the saving of Faces Messages during an Ajax request. This setting only applies of the above context parameter is set to true, and can be controlled with:
<context-param> <param-name>org.jboss.portletbridge.FACES_MESSAGES_STORED_ON_AJAX_REQUEST</param-name> <param-value>false</param-value> </context-param>
This setting can be beneficial when you want to prevent messages from an Ajax request being rendered to the portlet again on a re-render of the portlet.
Full details on these configuration settings can be found in the documentation.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.Alpha3</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.Alpha3</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.Alpha3</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.3.0.Alpha1 of Portlet Bridge is now available!
Full details of what is contained within the release can be found in the Release Notes.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.3.0.Alpha1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.3.0.Alpha1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.3.0.Alpha1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
With the release of the CDI portlet integration library, we can now take advantage of the vast benefits to using CDI with JSF inside our portlets with the Portlet Bridge!
In addition to the usual Portlet Bridge dependencies, to enable your portlet for CDI we need to:
<dependency> <groupId>org.gatein</groupId> <artifactId>cdi-portlet-integration</artifactId> <version>1.0.2.Final</version> </dependency>
<filter> <filter-name>PortletCDIFilter</filter-name> <filter-class>org.gatein.cdi.PortletCDIFilter</filter-class> <lifecycle>ACTION_PHASE</lifecycle> <lifecycle>EVENT_PHASE</lifecycle> <lifecycle>RENDER_PHASE</lifecycle> <lifecycle>RESOURCE_PHASE</lifecycle> </filter> <filter-mapping> <filter-name>PortletCDIFilter</filter-name> <portlet-name>yourPortletName</portlet-name> </filter-mapping>
The PortletCDIFilter only wraps the incoming portlet request for CDI to be able to use it. If your application code utilizes frameworks that need to act on the portlet response, you may need to use the PortletCDIResponseFilter instead, which wraps both the request and response.
Beans with this scope do not behave the same in a portlet as regular JSF. In a portlet, any modified content of a Bean that is set during an ActionRequest will not be available in any other phase of the portlet lifecycle, including RenderRequest. Therefore its recommended to not use this scope for your CDI beans within a JSF portlet, instead we recommend using the new @PortletLifecycleScoped that is provided by GateIn 3.6.0.Final. This new scope retains the Bean instance from ActionRequest to RenderRequest, allowing you to set data you want to use for rendering the portlet within an action.
Transient conversations act the same as if the Bean was annotated with @RequestScoped. Therefore they are also not recommended for use in making data available for the rendering of a JSF portlet.
Long running conversations do work as expected within a JSF portlet, though there are a couple of caveats to be aware of:
Lastly there are the two new scopes provided within GateIn 3.6.0.Final, @PortletLifecycleScoped and @PortletRedisplayScoped. Both of these scopes are usable by JSF portlets and are able to interact with other CDI scoped beans without problem. These scopes will be discussed in upcoming blog posts on GateIn.
Hopefully this post has helped point out some common pitfalls to watch out for when developing a JSF portlet that uses CDI!
We're pleased to announce that 3.2.0.Final of Portlet Bridge is now available!
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.Final</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.Final</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.Final</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.2.0.CR1 of Portlet Bridge is now available!
Full details of all the changes can be found in the release notes
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.CR1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.CR1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.CR1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.2.0.Beta2 of Portlet Bridge is now available!
Full details of all the changes can be found in the release notes
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.Beta2</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.Beta2</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.Beta2</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.2.0.Beta1 of Portlet Bridge is now available!
Full details of all the changes can be found in the release notes
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.Beta1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.Beta1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.Beta1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with Portlet Bridge, please get in touch.
We're pleased to announce that 3.2.0.Alpha2 of Portlet Bridge is now available!
Full details of all the changes can be found in the release notes
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.Alpha2</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.Alpha2</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.Alpha2</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with JBoss Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with JBoss Portlet Bridge, please get in touch.
We're pleased to announce that 3.2.0.Alpha1 of Portlet Bridge is now available!
Many fixes to how resource urls are generated for RichFaces 4 portlets which resolves problems such as with icons for rich:tree
Full details of all the changes can be found in the release notes
To enable CDI in a JSF2 portlet we've created a separate integration library that you'll need to include in your archive. The Maven dependency is:
<dependency> <groupId>org.gatein</groupId> <artifactId>cdi-portlet-integration</artifactId> <version>1.0.0.Alpha2</version> </dependency>
All details of how to add the Portlet Filter for CDI to your portlet.xml and what restrictions there may be on vanilla CDI can be found in our docs.
It's important to note that this library is for use with CDI 1.0 containers.
For a JSF2 only portlet:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-api</artifactId> <version>3.2.0.Alpha1</version> </dependency> <dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-impl</artifactId> <version>3.2.0.Alpha1</version> <scope>runtime</scope> </dependency>
For a RichFaces 4 portlet you need the above as well as:
<dependency> <groupId>org.jboss.portletbridge</groupId> <artifactId>portletbridge-extension-richfaces</artifactId> <version>3.2.0.Alpha1</version> <scope>runtime</scope> </dependency>
One of the best ways to hear about the latest releases and changes with JBoss Portlet Bridge is to follow us on Twitter (@portletbridge).
As always, if you have any questions about or issues with JBoss Portlet Bridge, please get in touch.