Skip to content

7. Example Application-04: rdvmedecins-pf-spring

7.1. Porting

We will now port the previous application to a Spring/Tomcat environment:

We will build upon two existing applications. We will use:

  • the [DAO] and [JPA] layers from version 02 of JSF / Spring,
  • the [web] / Primefaces layer from version 03 PF / EJB,
  • the Spring configuration files from version 02

Here, we are performing a task similar to the one done to port the JSF2 / EJB / Glassfish application to a JSF2 / Spring Tomcat environment. Therefore, we will provide fewer explanations. If necessary, the reader can refer to that port.

We are placing all the projects necessary for the porting into a new folder [rdvmedecins-pf-spring] [1]:

  • [mv-rdvmedecins-spring-dao-jpa]: the [DAO] and [JPA] layers of the JSF/Spring version 02,
  • [mv-rdvmedecins-spring-metier]: the [business] layer of version 02 JSF / Spring,
  • [mv-rdvmedecins-pf]: the [web] layer of version 03 Primefaces / EJB,
  • in [2], we load them into NetBeans,
  • in [3], the web project dependencies are no longer correct:
    • the dependencies on the [DAO], [JPA], and [business] layers must be changed to now target the Spring projects;
    • The GlassFish server provided the JSF libraries. This is no longer the case with the Tomcat server. They must therefore be added to the dependencies.

The [web] project evolves as follows:

The [pom.xml] file for the [web] layer now has the following dependencies:


<dependencies>    
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>mv-rdvmedecins-spring-metier</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>  
      <groupId>org.primefaces</groupId>  
      <artifactId>primefaces</artifactId>  
      <version>3.3</version>  
    </dependency>
  </dependencies>

Errors appear. They are caused by the EJB references in the [web] layer. Let’s first examine the [Application] bean:

We remove all the lines causing errors due to missing packages, rename [IMetier] (its name in the Spring [business] layer) to the [IMetierLocal] interface, and use Spring to instantiate it:


package beans;

import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import rdvmedecins.business.service.IMetier;

public class Application {

  // business layer
  private IMetier business;
  // errors
  private List<Error> errors = new ArrayList<Error>();
  private Boolean error = false;

  public Application() {
    try {
      // instantiate the [business] layer
      ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config-business-dao.xml");
      business = (IMetier) ctx.getBean("business");
    } catch (Throwable th) {
      // log the error
      error = true;
      errors.add(new Error(th.getClass().getName(), th.getMessage()));
      while (th.getCause() != null) {
        th = th.getCause();
        errors.add(new Error(th.getClass().getName(), th.getMessage()));
      }
      return;
    }
  }

  // getters
  public Boolean getError() {
    return error;
  }

  public List<Error> getErrors() {
    return errors;
  }

  public IBusiness getBusiness() {
    return business;
  }
}
  • lines 20-21: instantiation of the [business] layer from the Spring configuration file. This is the file used by the [business] layer [1]. We copy it into the web project [2]:
  • lines 22-31: we handle any exceptions and save their stack trace.

With that done, the [Application] bean no longer has any errors. Now let’s look at the [Form] bean [1], [2]:

We remove all the erroneous lines (imports and annotations) due to missing packages. This is enough to eliminate all errors [3].

Additionally, we need to add the getter and setter for the field


  // Application bean
private Application application;

Some of the annotations removed from the [Application] and [Form] beans declared the classes as beans with a specific scope. Now, this configuration is set in the following [faces-config.xml] file [4]:


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

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

  <application>
    <!-- the message file -->
    <resource-bundle>
      <base-name>
        messages
      </base-name>
      <var>msg</var>
    </resource-bundle>
    <message-bundle>messages</message-bundle>
  </application>
    <!-- the applicationBean bean -->
  <managed-bean>
    <managed-bean-name>applicationBean</managed-bean-name>
    <managed-bean-class>beans.Application</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>
    <!-- the bean form -->
  <managed-bean>
    <managed-bean-name>form</managed-bean-name>
    <managed-bean-class>beans.Form</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>application</property-name>
      <value>#{applicationBean}</value>
    </managed-property>
  </managed-bean>
</faces-config>

Normally, the porting is complete. However, there are still a few details to iron out. We can try running the web application.

We’ll leave it to the reader to test this new application. We can improve it slightly to handle the case where the initialization of the [Application] bean failed. We know that in this case, the following fields have been initialized:


  // errors
  private List<Error> errors = new ArrayList<Error>();
private Boolean error = false;

This scenario can be handled in the [Form] bean’s init method:


@PostConstruct
  private void init() {

    // Did the initialization succeed?
    if (application.getError()) {
      // retrieve the list of errors
      errors = application.getErrors();
      // display the error view
      setForms(false, false, true);
    }

    // cache doctors and clients
    ...
  }
  • line 5: if the [Application] bean failed to initialize,
  • line 7: retrieve the list of errors,
  • line 9: and display the error page.

Thus, if we stop the MySQL DBMS and restart the application, we now see the following page:

Image

7.2. Conclusion

Porting the PrimeFaces/EJB/GlassFish application to a PrimeFaces/Spring/Tomcat environment proved to be straightforward. The memory leak issue reported in the study of the JSF/Spring/Tomcat application (Section 4.3.5) remains.

It will be resolved in the same way.

7.3. Tests with Eclipse

We import the Maven projects into Eclipse [1]:

We run the web project [2].

We select the Tomcat server [3]. The application’s home page is then displayed in Eclipse’s internal browser [4].