Sunday, January 1, 2012

JSF 2.0 Managed Bean Annotations and CDI on WebLogic 12c

WebLogic 12c now supports Java 6 so we can now try out the JSF 2.0 Managed Bean annotations together with CDI JSR-299. In this blogpost I will use OEPE 12c as my IDE and deploy everything on WebLogic 12c. Off course I will tell you my experiences to get all this working in Eclipse and WebLogic 12c.

First let's start with the JSF 2.0 Managed Bean Annotations.

We need to remove the managed bean definitions from the faces-config.xml file. Then make sure that you don't use the metadata-complete attribute ( metadata-complete="true" ) on the faces-config element, this will disable the search for JSF Managed Beans.


Then we can add the JSF Managed Bean annotations to the java class. We can use @ManagedBean ( javax.faces.bean ) together with the right scope annotation like RequestScoped, SessionScoped or ViewScoped ( CDI does not have this View Scope ). You will see this bean in the Faces Configuration View.



Next part of this blog is about CDI, this will be more tricky, it is possible but does not work so well in OEPE and WebLogic. I didn't have these problems with the same OEPE, Code and using Glassfish 3.11.

So to enable CDI we need to add a beans.xml file to the WEB-INF folder. Like this with a empty beans element, this will trigger CDI.

When we try to run the JSF application again then you probably will hit this NPE in the jboss Weld framework.


<javax.enterprise.resource.webcontainer.jsf.renderkit> <BEA-000000> <javax.faces.FacesException
javax.faces.FacesException
at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:142)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at org.apache.myfaces.extensions.validator.core.startup.ExtValLifecycleWrapper.render(ExtValLifecycleWrapper.java:79)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
Truncated. see log file for complete stacktrace
Caused By: java.lang.NullPointerException
at org.jboss.weld.el.ELCreationalContextStack.getCreationalContextStore(ELCreationalContextStack.java:33)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:47)




The solution is to remove the JSP entries and rename your files from jspx to xhtml.
From this.

<?xml version="1.0" encoding="iso-8859-1"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
          xmlns:f="http://java.sun.com/jsf/core" 
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:trh="http://myfaces.apache.org/trinidad/html"
          xmlns:tr="http://myfaces.apache.org/trinidad">
  <jsp:directive.page contentType="text/html;charset=utf-8"/>
  <f:view>
    <tr:document title="Bean and ExtVal validation">
      <tr:form>

To this, where we define the used jsf namespaces on the html element. 


Next we can try to create a new managed bean where we will use the Named annotation together with the SessionScoped annotation of javax.enterprise.context


We can also inject an EJB or a Managed Bean with the Inject annotation.


I can also replace @EJB with @Inject but then I should move my EJBs to my Dynamic Web Project else I will get an Weld error.  Probably with OEPE you have an different JPA project and this ejb.jar will be deployed together with the WAR in an EAR. 
I didn't test this but you need to enable CDI on this ejb project or EAR.

That's not all you also need to change the WebLogic Publishing mode of OEPE. This should be Publish as an exploded archive else Inject won't work. ( Thanks to Steve Button for the tip. ).

This is the error I got WELD-001408 Unsatisfied dependencies for type [DataBeanCDI] with qualifiers [@Default] at injection point [[field] @Inject private nl.amis.web.beans.DataBean.dataBeanCDI]

This is solved in the WebLogic 12c (12.1.1) patch release of March 2012, so no need for an exploded archive

And now the most annoying bug, the CDI managed beans will work only once on WebLogic 12c. When you deploy or run your application the second time then the CDI Managed bean can't be found. The solution is you need to restart the WebLogic Server. This makes development with CDI almost impossible.

This is also solved in the WebLogic 12c (12.1.1) patch release of March 2012

I also added and removed a patch which makes everything even a little better


So, I removed with the BSU utility the following patch
13603813 SU Patch [53JP]: MERGE LABEL REQUEST ON TOP OF 12.1.1. FOR CDI BUGS

and  installed

13893259 SU Patch [QPXR]: MERGE LABEL REQUEST ON TOP OF 12.1.1.0.0 FOR BUGS 13482794 13563205 13572075 13572176

Also enabling fastswap in the weblogic-application.xml ( ear project ) can help you in solving weld errors.


Here you can find my example code.