16 March 2011

Tutorial: JSF 2.0 and JPA 2.0 with WebLogic Server using NetBeans

The NetBeans team have produced a new tutorial demonstrating using JSF 2.0, JPA 2.0 with WebLogic Server 10.3.4 and NetBeans 7.0.   The application uses the JPA entity and JSF page generation wizards to quickly produce a working application based on a sample schema.

 Developing an Enterprise Application for Oracle WebLogic Server

From the WebLogic Server perspective, this tutorial demonstrates some of the nice integration points NetBeans now has with WebLogic Server.

For instance, the tutorial shows how NetBeans discovers and presents the set of WebLogic Server supplied JSF shared-libraries to the developer to select from.


It shows the resulting automatic configuration of the weblogic deployment descriptor to reference the chosen shared library, and finally it shows the automatic deployment that of the selected JSF shared library that NetBeans performs if necessary.  


This all goes to make the use of JSF with WebLogic Server very straight forward.


The tutorial also highlights the simple approach NetBeans exposes for developers to Enable JPA 2.0 on the target WebLogic Server domain that is being used for the application.


All together this is a tutorial well worth taking a look at and stepping through to look at the generated code and pages.

10 March 2011

JSF with Managed Beans and Dependency Injection and WebLogic Server

A question appears from time to time on various forums postings regarding the use of dependency injection within JSF Managed Beans when running on WebLogic Sever.  The usual problem reported is that the dependency injection simply does not work. 

A recent example of this is here:

http://forums.oracle.com/forums/thread.jspa?messageID=9418272&tstart=0#9418272

The Short Story

The short story is that WebLogic Server does indeed support the use of dependency injection, within Managed Beans in JSF applications.  The simplest way to get it to work is to use the documented mechanism of deploying and using the WebLogic Server supplied JSF shared-library, in which the WebLogic Server specific implementation of the com.sun.faces.spi.InjectionProvider class is supplied, and automatically configured as the InjectionProvider implementation on the Web container.

It is this WebLogic Server specific class -- com.bea.faces.WeblogicInjectionProvider – in which the actual dependency injection calls are realized.  Without this class being present, the dependency injection calls from JSF essentially become NOOPs.

See the documentation for more detailed instructions on how to deploy the JSF shared-library to WebLogic Server and reference it within applications.

Configuring JSF and JSTL Libraries
http://download.oracle.com/docs/cd/E17904_01/web.1111/e13712/configurejsfandjtsl.htm#i163440

The Longer Story

To provide support for multiple versions of JSF, WebLogic Server uses its it’s shared-library mechanism.  In a WebLogic Server installation, there are a set of “deployable-libraries” provided that can be deployed as libraries to a WebLogic Server domain to extend its base functionality, in this specific instance by providing a JSF runtime.

deployable-libraries 

The JSF 2.0 shared-library is represented by the jsf-2.0.war archive.  This archive contains the standard JSF and JSTL jar files, plus an additional library wls.jsf.di.jar

jsf-2.0.war

The wls.jsf.di.jar library contains a single class com.bea.faces.WeblogicInjectionProvider, which is the WebLogic Server specific implementation of the com.sun.faces.spi.InjectionProvider interface required to support dependency inject from JSF. 

Furthermore, WebLogic Server detects when JSF is present in a web application by examining if the “jsf” shared-library is referenced, or if the Faces Servlet is configured, and automatically sets the ServletContext parameter com.sun.faces.injectionProvider parameter to the com.bea.faces.WebLogicInjectionProvider class to specify the InjectionProvider to use.

** See http://blogs.sun.com/rlubke/entry/jsf_ri_1_2_and for the details of this standard JSF SPI mechanism.

wls.jsf.di.jar 

public class com.bea.faces.WeblogicInjectionProvider implements com.sun.faces.spi.InjectionProvider {


    public com.bea.faces.WeblogicInjectionProvider();


    public void inject(java.lang.Object)  throws com.sun.faces.spi.InjectionProviderException;


    public void invokePostConstruct(java.lang.Object)  throws com.sun.faces.spi.InjectionProviderException;


    public void invokePreDestroy(java.lang.Object) throws com.sun.faces.spi.InjectionProviderException;


}






Thus without this wls.jsf.di.jar library and the com.bea.faces.WeblogicInjectionProvider class it contains that implements the JSF dependency injection SPI, any dependencies declared in the JSF application are not able to be fulfilled.




Using WebLogic Server JSF Shared Libraries



The simplest way to use dependency injection in JSF with WebLogic Server is to follow the documented approach for deploying and using JSF shared-library as referenced above.  Once the shared-library is deployed, applications use it by providing a reference in a weblogic deployment descriptor to the JSF library.  At runtime, WebLogic Server will arrange to have the contents of the shared-library made available for the application to use.



For deployment of shared-libraries to WebLogic Server, the standard tools such as the console, or the weblogic.Deployer utility are used, specifying the deployment type as a library.



console-library



Screen shot 2011-03-10 at 1.26.17 PM



With the JSF shared-library deployed to WebLogic Server, applications can reference it using a weblogic deployment descriptor.



An example weblogic.xml deployment descriptor referencing the deployed JSF@2.0 shared-library is shown below.




<?xml version="1.0" encoding="UTF-8"?>


<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">


  <jsp-descriptor>


    <keepgenerated>true</keepgenerated>


  </jsp-descriptor>


  <context-root>/WLS-JSF-EJB-DI-WEB</context-root>


    


  <library-ref>


    <library-name>jsf</library-name>


    <specification-version>2.0</specification-version>


    <implementation-version>1.0.0.0_2-0-2</implementation-version>


  </library-ref>  


  


</weblogic-web-app>




This is the documented and supported approach and is what we recommend based on the current architecture we use to support JSF.



Embedding JSF within a Web Application



A common arrangement for applications using JSF, is to provide the JSF jar files within the web archive itself, so that they are always available when the application is deployed.  It is this case typically where problems surface with dependency injection not working, since the WeblogicInjectionProvider class provider is not present, resulting in a NOOP when dependency injection calls are made.



If this embedding approach is to be used, then the undocumented (and daresay unsupported at this time) approach to getting dependency injection to work in JSF, is to extract the wls.jsf.di.jar file from the jsf-1.2.war or jsf-2.0.war files from a WebLogic Server installation, and put it into the WEB-INF/lib directory of the web application, alongside the JSF jars.  When the application is deployed, the WeblogicInjectionProvider will be available.  This works because the web application initialization code we have, in addition to looking at the shared-library references, also checks to see whether the Faces Servlet -- javax.faces.webapp.FacesServlet -- is configured in web.xml.  If so, it sets the InjectionProvider property appropriately on the ServletContext of the web application, delegating the dependency injection operations to the WeblogicInjectionProvider.



A Simple Example



Right, with that explained (hopefully) lets take a look at a simple example in NetBeans.



Here is a Java EE project with two modules: WLS-JSF-EJB-DI-WEB and WLS-JSF-EJB-DI-EJB:



netbeans-app



In WLS-JSF-EJB-DI-EJB there is a single EJB 3.0 stateless session bean defined as follows:




package oracle.com.demo.ejb;


 


import javax.ejb.Local;


 


@Local


public interface DateTimeLocal {


    String getCurrentDateTime();


    String getCurrentTime();


    String getCurrentDate();


    int getDateStyle();


    int getTimeStyle();


    void setDateStyle(int style);


    void setTimeStyle(int style); 


}




This purpose of this EJB is to return a formatted string representing the current date and time.  The formatting of the date is controlled via the DateStyle and TimeStyle properties.



In  the WLS-JSF-EJB-DI-WEB module, there is a single DateTimeManagedBean class, annotated with @ManagedBean (no faces-config.xml here!) and a single JSF facelet that uses the Managed Bean to displays the formatted date and time.  It also allows the user to change the formatting, again via the Managed Bean.



The Managed Bean class uses an @EJB annotation to inject an instance of the DateTimeLocal EJB, and then delegates all work to it, in order obtain the appropriately formatted date and time string. 




package oracle.com.demo.web.beans;


 


import javax.ejb.EJB;


import javax.faces.bean.ManagedBean;


import oracle.com.demo.ejb.DateTimeLocal;


 


@ManagedBean


public class DateTimeManagedBean {


    


    @EJB


    DateTimeLocal dateTimeEJB;


    


    public int getDateStyle() {


        return dateTimeEJB.getDateStyle();


    }


    


    public int getTimeStyle() {


        return dateTimeEJB.getTimeStyle();


    }


    


    public void setDateStyle(int style) {


        dateTimeEJB.setDateStyle(style);


    }


    


    public void setTimeStyle(int style) {


        dateTimeEJB.setTimeStyle(style);


    }    


    


    public String getCurrentDateTime() {


        return dateTimeEJB.getCurrentDateTime();


    }


    


    public String getCurrentDate() {


        return dateTimeEJB.getCurrentDate();


    }


    


    public String getCurrentTime() {


        return String.format("%s", dateTimeEJB.getCurrentTime());


    }


 


    public String applyFormats() {


        return "index.xhtml"; // 


    }


    


}



 









The index.xhtml facelet uses the Managed Bean to sets and apply the formatting properties and obtain the current date and time in the desired format.



Finally, a weblogic.xml file is provided in the WEB-INF directory that specifies the use of the jsf#2.0 shared-library. 



** NetBeans offers great support for WebLogic here.  When you add the “JSF Framework” to a project that is configured to run on WebLogic Server, NetBeans automatically offers you the choice of JSF implementations it is aware of on the server and generates the weblogic.xml file.  It will also transparently deploy the specified JSF shared-library to the target WebLogic Server domain if it is not already deployed. 



When deployed to WebLogic Server 10.3.4, the resulting page looks like this:



app1 



Changing the format properties and applying them, the Managed Bean gets updated, which in turn makes the changes on the DateTimeLocal EJB, which ultimately returns the date and time in the specified format:



 app2



This simple application demonstrates the successful use of JSF with a Managed Bean, which injects and uses an EJB 3.0 stateless session bean.



I creates this sample application to assist an OTN question that was asked – the project can be be downloaded from here: http://bit.ly/wlsjsfejb.