Monday, August 29, 2016

Singleton Session Bean Basics with Example - Counter

This post shows how to create Singleton Session Bean. And will cover following topics.

1. Create Singleton Session Bean

2. Initializing and Ordering Singleton Session Bean

3. Counter Example with Hit Count



1. Create Singleton Session Bean


The javax.ejb.Singleton annotation is used to specify that the enterprise bean implementation class is a singleton session bean:



@Singleton
public class SingletonBean { ... }
 
 
In this example, A web application named Counter is created with JSF2 framework. Ad all
beans are created in this application. 
 

2. Initializing and Ordering Singleton Session Bean


Sinbleton Session bean are initialized by 2 ways:

-- EJB container (Weblogic, GlassFish, JBOSS etc) initializes the bean before 1st request comes to that client. In this way, the container will decide when the bean will initialize.


-- Another way is eager initialization. Here the class is annotated with javax.ejb.Startup annotation. The bean is initialized upon application startup. The following is the example of eager initialization.



@Startup
@Singleton
public class StatusBean {
  
    @PostConstruct
    private void init()
    {
        System.out.println("StatusBean initialized...");
    }
  
}
 
When the container startup after deployment the project containing the bean, the part of the server console output are as follows: (Here I use GlassFish Server)


Info: WEB0671: Loading application [Counter] at [/Counter]
Info: Counter was successfully deployed in 1,755 milliseconds.
Info: keepstate options resolved to true, saving appId 96493622293626880 for application Counter.
Info: EJB5181:Portable JNDI names for EJB StatusBean: [java:global/Counter/StatusBean!test.ejb.StatusBean, java:global/Counter/StatusBean]
Info: StatusBean initialized...
Info: Initializing Mojarra 2.1.6 (SNAPSHOT 20111206) for context '/Counter'
Info: WEB0671: Loading application [Counter] at [/Counter]
Info: Counter was successfully deployed in 3,495 milliseconds.
 
Sometimes multiple singleton session beans are used to initialize data for an application and therefore need to be initialized in a specific order. The javax.ejb.DependsOn annotation to declare the startup dependencies. The @DependsOn annotation can take multiple session beans name as string but there order not necessarily depends on the listing order.

To illustrate ordering of singleton session bean, I use 3 singleton session beans: PrimaryBean, SecondaryBean, TertiaryBean.

PrimaryBean is a normal singleton session bean. It has @PostConstruct annotation method and getHit() business method. There is nothing special to this bean.


@Singleton
public class PrimaryBean {
    private String name="PrimaryBean";
  
    private int hit = 0;
  
    @PostConstruct
    private void init()
    {
        System.out.println(name + " initialized...");
    }

    public int getHit() {
        hit++;
        return hit;
    }
  
}
 

The following is SecondaryBean. It uses eager initialization by using @Startup annotation. @DependsOn  annotation tells that PrimaryBean will be initialized first before SecondaryBean initialized and SecondaryBean will be initialized during application startup.


 @Startup
@Singleton
@DependsOn("PrimaryBean")
public class SecondaryBean {

    private String name="SecondaryBean";
  
    private int hit = 0;
  
    @PostConstruct
    private void init()
    {
        System.out.println(name + " initialized...");
    }

    public int getHit() {
        hit++;
        return hit;
    }
  
  
}

The following is TertiaryBean and it'll be initialized upon injection or 1st request come to the bean. The DependsOn annotation defines that PrimaryBean and SecondaryBean must be initialized before this bean. And order is not like listing their names. In this example, SecondayBean depends on PrimaryBean, so the order of initialization as follows: PrimaryBean, SecondaryBean, TertiaryBean. Here 1st two beans are initialized during application startup.


@Singleton
@DependsOn({"PrimaryBean", "SecondaryBean"})
public class TertiaryBean {
    private String name = "TertiaryBean";
  
    private int hit = 0;
  
    @PostConstruct
    private void init()
    {
        System.out.println(name + " initialized...");
    }

    public int getHit() {
        hit++;
        return hit;
    }
  
  
}
 
After deployment and startup the server, the part of the server console output are as follows:
Info: EJB5181:Portable JNDI names for EJB PrimaryBean: [java:global/Counter/PrimaryBean!test.ejb.PrimaryBean, java:global/Counter/PrimaryBean]
Info: EJB5181:Portable JNDI names for EJB SecondaryBean: [java:global/Counter/SecondaryBean!test.ejb.SecondaryBean, java:global/Counter/SecondaryBean]
Info: EJB5181:Portable JNDI names for EJB TertiaryBean: [java:global/Counter/TertiaryBean!test.ejb.TertiaryBean, java:global/Counter/TertiaryBean]
Info: EJB5181:Portable JNDI names for EJB StatusBean: [java:global/Counter/StatusBean!test.ejb.StatusBean, java:global/Counter/StatusBean]

Info: PrimaryBean initialized...
Info: SecondaryBean initialized...

Info: StatusBean initialized...
Info: Initializing Mojarra 2.1.6 (SNAPSHOT 20111206) for context '/Counter'
Info: WEB0671: Loading application [Counter] at [/Counter]
Info: Counter was successfully deployed in 3,139 milliseconds.
 
Here TertiaryBean is not initialized because it has no @Startup annotation.

3. Counter Example with Hit Count

Now I'll test these 3 beans - PrimaryBean, SecondaryBean, TertiaryBean by calling getHit() methods of the particular bean. The count of the specific bean will be exist during the whole application life. Therefore i've created Facelets XHTML Template.xhtml and it's client BeanTest.xhtml which has 3 buttons to call 3 beans getHit() methods. The JSF manged bean TestBean.java is used by BeanTest.xhtml. TestBean.java references the beans through dependency injection. The output is as follows:





Template.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
        <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
        <title>Counter - A singleton Session Bean Example.</title>
    </h:head>

    <h:body>

        <div id="top" class="top">
            <ui:insert name="top">Top</ui:insert>
        </div>

        <div id="content" class="center_content">
            <ui:insert name="content">Content</ui:insert>
        </div>

    </h:body>

</html>
 

BeanTest.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">

    <body>

        <ui:composition template="./Template.xhtml">

            <ui:define name="top">
                Test Singleton Bean
            </ui:define>

            <ui:define name="content">
                <h:form>
                   
                    <h:panelGrid columns="1">
                       
                        <h:panelGroup>
                            <h:commandButton value="Test Primary Bean" action="#{testBean.PrimaryBean()}"/>
                            <h:commandButton value="Test Seconday Bean" action="#{testBean.SecondaryBean()}"/>
                            <h:commandButton value="Test Tertiary Bean" action="#{testBean.TertiaryBean()}"/>
                        </h:panelGroup>
                       
                        <h:outputText value="#{testBean.message}"/>
                       
                    </h:panelGrid>
                   
                </h:form>
            </ui:define>

        </ui:composition>

    </body>
</html>
 

TestBean.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.request;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import test.ejb.PrimaryBean;
import test.ejb.SecondaryBean;
import test.ejb.TertiaryBean;

/**
 *
 * @author Dell
 */
@ManagedBean
@RequestScoped
public class TestBean {

    @EJB
    private TertiaryBean tBean;
   
    @EJB
    private PrimaryBean pBean;
   
    @EJB
    private SecondaryBean sBean;
   
    private String message;
   
    /** Creates a new instance of TestBean */
    public TestBean() {
    }
   
    public void PrimaryBean()
    {
        message = "Primary Bean Clicked: " + pBean.getHit() + " times.";
    }
   
    public void SecondaryBean()
    {
        message = "Secondary Bean Clicked: " + sBean.getHit() + " times.";
    }
   
    public void TertiaryBean()
    {
        message = "Tertiary Bean Clicked: " + tBean.getHit() + " times.";
    }

    public String getMessage() {
        return message;
    }
   
   
}

 

Saturday, August 20, 2016

Quick Solution: Scheduler / Background Job in a Web Application

 EJB available? Use @Schedule

If your environment happen to support EJB (e.g. WildFly, JBoss AS/EAP, TomEE, GlassFish, etc), then use @Schedule instead.
 


@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }
 
    @Schedule(hour="*", minute="*", second="2", persistent=false)
    public void someSecondlylyJob() {
        // Do your job here which should run every 2 seconds of a minute.
    } 

} 
 
 


Yes, that's really all. The container will automatically pickup and manage it.

EJB unavailable? Use ScheduledExecutorService

If your environment doesn't support EJB (i.e. not a real Java EE server, e.g. Tomcat, Jetty, etc), use ScheduledExecutorService. This can be initiated by a ServletContextListener. Here's a kickoff example:


@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}


Where the job classes look like this:
 
 
public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
 
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

} 
 
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}
 

Do not ever think about using java.util.Timer/java.lang.Thread in Java EE

Never directly use java.util.Timer and/or java.lang.Thread in Java EE. This is recipe for trouble.

Shopping Cart Example with EJB 3 and GlassFish 3 - Stateful Session Bean and Remote Client

The cart example represents the operations of a shopping cart in online bookstore. This example uses

1. Java Enterprise Application (Cart)

2. Remote Business Interface (Cart.java)

3. Session Bean Class (CartBean.java)

4. Two Helper classes (BookException.java and IdVerifier.java)

5. A servlet client (CartClient.java)


Before continue this post, please go through previous post of Enterprise Application with EJB and Dependency Injection.


1. Java Enterprise Application (Cart)



Create Java EE application using  NetBeans. File -> New Project -> Java EE -> Enterprise Application. And name it Cart. And choose GlassFish server. This will create 3 nodes in Projects explorer: Cart, Cart-ejb, Cart-war.


2. Remote Business Interface (Cart.java)

Create Cart.java in cart.ejb package under Cart-ejb node.
Cart.java is a plain java interface that defines all business methods implemented in the bean class. If a bean class implements a single interface, this interface is assumed to be business interface. Otherwise if bean class implements more than 1 interface then the business interface must be explicitly annotated. The business  interface can be annotated with @Remote (javax.ejb.Remote) or @Local (javax.ejb.Local). If not annotated anything, the interface is local. 

In this example, the interface is remote. The following interfaces are excluded when any bean class implements more than 1 interface: java.io.Serializable , java.io.Externalizable and any inteface under javax.exjb package.

The source code of Cart.java interface:


package cart.ejb;

import cart.util.BookException;
import java.util.List;
import javax.ejb.Remote;

/**
 *
 * @author Khan.Ashik
 */
@Remote
public interface Cart {
   
    public void initialize(String person) throws BookException;
   
    public void initialize(String person, String id) throws BookException;
   
    public void addBook(String title);
   
    public void removeBook(String title) throws BookException;
   
    public List<String> getContents();
   
    public void remove();
   
}


3. Session Bean Class (CartBean.java)

Create CartBean.java in cart.ejb package under Cart-ejb node.

■ The class is annotated with @Stateful  and implements the methods of Cart.java interface.

■ Since it is a stateful session bean, it can implement any optional lifecycle callback methods annotated  with @POstConstruct, @PreDestroy, @PostActivate and @PrePassivate.

■ It also can implment any optional business method annotated @Remove.



The source code of CartBean.java class:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.ejb;

import cart.util.BookException;
import cart.util.IdVerifier;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remove;
import javax.ejb.Stateful;

/**
 *
 * @author Khan.Ashik
 */
@Stateful
public class CartBean implements Cart{

    List<String> contents;
    String customerId;
    String customerName;
   
    @Override
    public void initialize(String person) throws BookException {
        if(person==null)
        {
            throw new BookException("Null person not aalowed.");
        }
        else
        {
            customerName = person;
        }
        customerId = "0";
        contents = new ArrayList<String>();
    }

    @Override
    public void initialize(String person, String id) throws BookException {
        if(person==null)
        {
            throw new BookException("Null person not aalowed.");
        }
        else
        {
            customerName = person;           
        }
       
        IdVerifier idChecker = new IdVerifier();
       
        if(idChecker.validate(id))
        {
            customerId = id;
        }
        else
        {
            throw new BookException("Invalid Id: " + id);
        }
       
       
        contents = new ArrayList<String>();
    }

    @Override
    public void addBook(String title) {
        contents.add(title);
    }

    @Override
    public void removeBook(String title) throws BookException {
        boolean result = contents.remove(title);
       
        if(result==false)
        {
            throw new BookException("\"" + title + "\" not in the cart.");
        }
    }

    @Override
    public List<String> getContents() {
        return contents;
    }

    @Remove
    public void remove() {
        contents = null;
    }
   
}


4. Helper Classes (BookException.java and IdVerifier.java)

Create BookException.java and IdVerifier.java in cart.util package under Cart-ejb node.

CartBean has 2 helper classes. BookException is thrown by removeBook method and IdVerifier validates the customer Id.

The source code of BookException.java class:

package cart.util;

/**
 *
 * @author Khan.Ashik
 */
public class BookException extends Exception{

    public BookException() {
    }

    public BookException(String message) {
        super(message);
    }
   
   
   
}

The source code of IdVerifier.java class:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.util;

/**
 *
 * @author Khan.Ashik
 */
public class IdVerifier {

    public IdVerifier() {
    }
   
    public boolean validate(String id)
    {
        boolean result = true;
       
        for(int i=0; i        {
            if(Character.isDigit(id.charAt(i))==false)
            {
                result = false;
            }
        }
        return result;
    }
}


4. Servlet Client (CartClient.java)

Create CartClient.java in cart.client package under Cart-war node.

Here we inject CartBean by annotating  @EJB to Cart interface to get a new reference to the enterprise bean.

The code snippet is:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.client;

import cart.ejb.Cart;
import cart.util.BookException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Khan.Ashik
 */
@WebServlet(name="CartServlet", urlPatterns="/clientServlet")
public class CartClient extends HttpServlet{

    @EJB
    private Cart cart;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       
        PrintWriter writer = resp.getWriter();
        try {
            cart.initialize("MY BOOK", "123");
            cart.addBook("Head First");
            cart.addBook("Bean Developer");
            cart.addBook("Street Show");
           
            List bookList = cart.getContents();
           
            Iterator iterator = bookList.iterator();
           
            while(iterator.hasNext())
            {
                String title = iterator.next();
                writer.write("Retrieving book title from cart: " + title+"\n");
            }
           
            writer.write("Removing \"MY BOOK\" from cart\n");
           
            cart.removeBook("MY BOOK");
           
            cart.remove();
           
           
           
        } catch (BookException ex) {
            writer.write("Caught a BookException: " + ex.getMessage());
           
        } catch (Exception ex) {
            writer.write("Caught an unexpected exception!");
            ex.printStackTrace();
           
        }
    }
   
   
   
}


Deploy and run the application. Go to servlet URL to get the output of the bean.

And thats all about this example.









Sunday, August 7, 2016

Enterprise Application with EJB and Dependency Injection

Here we'll see a simple JAVA EE application named converter. The purpose of converter is to calculate currency conversions between dollar, taka and ringit. The converter application consists of an enterprise bean, which performs the calculations, and a web client.

Platforms:

1. GlassFish Server

2. NetBeans


Overview:

1. Create Enterprise Application: Converter
2. Create the enterprise bean: ConverterBean.
3. Create the web client.
4. Deploy converter.ear into the server.
5. Using a browser, run the web client.

1. Create Enterprise Application: Converter.
Go to File->New Project (Ctrl + Shift + N) and follow following steps.










After clicking Finish, three project nodes will be created:  Converter, Converter-ejb, Converter-war.

2. Now i'll create a class named ConverterBean under Converter-ejb node. This is an Enterprise Bean by @Stateless annotation. This class implements 2 business methods dollarToTaka and takaToRingit. Because the enterprise bean class doesn't implement a business interface, the enterprise bean exposes a local, no-interface view. The public methods in the enterprise bean class are available to clients that obtain a reference to ConverterBean. The source code is as follows:




package converter.ejb;

import java.math.BigDecimal;
import javax.ejb.Stateless;


@Stateless
public class ConverterBean {
    private BigDecimal takaRate = new BigDecimal("80");
    private BigDecimal ringitrRate = new BigDecimal("0.054");
   
    public BigDecimal dollarToTaka(BigDecimal dollars)
    {
        BigDecimal result = dollars.multiply(takaRate);
       
        return result.setScale(2, BigDecimal.ROUND_UP);
    }
   
    public BigDecimal takaToRingit(BigDecimal taka)
    {
        BigDecimal result = taka.multiply(ringitrRate);
       
        return result.setScale(2, BigDecimal.ROUND_UP);
    }
}


3. Now i'll create a servlet named ConverterServlet and modify the index.jsp under Converter-war node. A JAVA servlet is a web component that responds to HTTP request.

The main part of ConverterServlet class is that it uses dependency injection to obtain a reference to ConverterBean. The javax.ejb.EJB annotation is added to the declaration of the private member variable converterBean, which is of type ConverterBean. ConverterBean exposes a local, no-interface view, so the enterprise bean implementation class is the variable type. 

The source code of ConverterServlet is as follows:




 package com.servlets;

import converter.ejb.ConverterBean;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
@WebServlet(name="ConverterServlet", urlPatterns="/convert")
public class ConverterServlet extends HttpServlet {

    @EJB
    ConverterBean converterBean;
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("Invalid Access");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        RequestDispatcher dispatcher =  req.getRequestDispatcher("index.jsp");
       
        String dollarText = req.getParameter("dollar");
        if(dollarText.isEmpty() || dollarText==null)
        {
            req.setAttribute("error", "Please Give Dollar Amount");
            dispatcher.forward(req, resp);
        }
       
        try
        {
            BigDecimal dollar = new BigDecimal(dollarText);
           
            BigDecimal taka = converterBean.dollarToTaka(dollar);
           
            BigDecimal ringit = converterBean.takaToRingit(taka);
           
            req.setAttribute("dollar", dollar);
            req.setAttribute("taka", taka);
            req.setAttribute("ringit", ringit);
            //System.out.println(dollar + "~" + taka  + "~" + ringit);
        }
       
        catch(Exception e)
        {
            req.setAttribute("error", "Number Required"); 
            //e.printStackTrace();
            //System.out.println(e.getMessage());
        }
       
       
        dispatcher.forward(req, resp);
    }
   
}

The index.jsp file is as follows:




<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Convert Currency</title>
    </head>
    <body>
        <h1>Convert Currency!</h1>
      
        <form action="./convert" method="post">
          
            <table>
              
                <tr>
                    <td>Dollar: </td>
                    <td><input type="text" name="dollar" value="${dollar}"/>${error}</td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="Convert"/>
                    </td>
                </tr>
                <tr>
                    <td>
                        Taka:
                    </td>
                    <td>
                        ${taka}
                    </td>
                </tr>
                <tr>
                    <td>
                        Ringit:
                    </td>
                    <td>
                        ${ringit}
                    </td>
                </tr>
              
            </table>

              
          
        </form>
    </body>
</html>

4. Now clean and build the Converter to create Converter.ear and deploy it into GlassFish Server.

5. Run using default port i.e  http://localhost:8080/Converter-war/ And test the application.






That's all about this example.