Showing posts with label EJB3. Show all posts
Showing posts with label EJB3. Show all posts

September 30, 2011

Service Locator & Business Delegate Design Patterns for an EJB Client

HelloClient.java - This is the EJB Client class

package info.icontraining.ejb.client;

public class HelloClient {
 
   public static void main(String[] args) {  
      System.out.println(MyBusinessDelegate.sayHello("Dinesh"));
   }
}

MyBusinessDelegate.java

package info.icontraining.ejb.client;

import java.util.Hashtable;
import javax.naming.*;

public class MyBusinessDelegate {

   public static String sayHello(String name) {

      Object obj = MyServiceLocator.getStub("MyEarApp/" 
                  + HelloUserBean.class.getSimpleName() + "/remote");
  
      HelloUser helloUser = (HelloUser) obj;
      return helloUser.sayHello(name);
   }
}

MyServiceLocator.java


package info.icontraining.ejb.client;

import java.util.Hashtable;
import javax.naming.*;

public class MyServiceLocator {

   public static Object getStub(String jndiName) {
  
      Hashtable env = new Hashtable(); 
      env.put("java.naming.factory.initial",
            "org.jnp.interfaces.NamingContextFactory");
      env.put("java.naming.factory.url.pkgs",
            "org.jboss.naming:org.jnp.interfaces"); 
      env.put("java.naming.provider.url","localhost:1099"); 

      Context context;
      Object obj = null;
     
      try {
         context = new InitialContext(env);
         obj = context.lookup(jndiName);
      } catch (NamingException e) {
         e.printStackTrace();
      }

      return obj;
   }
}

June 18, 2011

EJB3 Message-Driven Bean (MDB) - Hello World Example

0) Create an EJB Project and an EAR project according to instructions specified in the following example

1) Create a new Message-Driven Bean class in the ejbModule folder of the EJB Project created in the previous example.


package info.icontraining.mdb;


import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;


@MessageDriven
(activationConfig = {
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MDBQueue2"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "AUTO_ACKNOWLEDGE")  })


public class MyMDB implements MessageListener {

   public void onMessage(Message message) {

      System.out.println("onMessage");
      TextMessage textMessage = (TextMessage) message;
      try {
         System.out.println("Received in an EJB3 MDB: " + 
                             textMessage.getText());
      
      } catch(Throwable t) {
         t.printStackTrace();
      }
   }
}


2) The EJB3 Message-Driven Bean (MDB) acts as a JMS consumer only. It cannot be directly accessed from a client. It is given messages delivered to a particular JMS destination such as a queue or topic.

We next create a JMS Client to write messages to a JMS Queue. The JMS provider will asynchronously deliver messages to the MDB by invoking its onMessage() method. This method like a business method of an MDB. The JMS client created below is a standalone Java program.


package info.icontraining.jms.client;


import javax.jms.*;
import javax.jms.Queue;
import javax.naming.*;
import java.util.*;


public class MyMDBSenderClient {


   public static void main(String[] args) {


      QueueConnection conn = null;
      QueueSession session = null;
      Queue que;

      try {
         Hashtable props = new Hashtable();


         props.put(Context.INITIAL_CONTEXT_FACTORY, 
                   "org.jboss.naming.NamingContextFactory");
         props.put(Context.URL_PKG_PREFIXES, 
                   "jboss.naming:org.jnp.interfaces");
         props.put(Context.PROVIDER_URL, "localhost:1099");
         props.put("java.naming.rmi.security.manager", "yes");


         InitialContext iniCtx = new InitialContext(props);


         Object tmp = iniCtx.lookup("ConnectionFactory");
         QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;

         conn = qcf.createQueueConnection();
         que = (Queue) iniCtx.lookup("queue/MDBQueue2");
         session = conn.createQueueSession(false,
                                      QueueSession.AUTO_ACKNOWLEDGE);
         conn.start();


         QueueSender queueSender = session.createSender(que);
         TextMessage message = session.createTextMessage();
         message.setText("Sent from MyMDBSenderClient");
         queueSender.send(message);


         System.out.println("Message sent.");



         queueSender.close();


      } catch (NamingException e) {
         System.out.println(e.toString());
      } catch (JMSException e) {
         System.out.println("JMS Exception");
      } finally {
         if (conn != null) {
            try {
               conn.close();
            } catch (JMSException e) {
               System.out.println("JMS Exception");
            }
         }
      }
   }
}


3) Test the MDB by executing the JMS Client code created in Step-2. Check the output in the server console printed by code in the MDB's onMessage() method.

EJB3 Stateless Session Bean with Remote access - Hello World Example

0) Refer to the EJB3 Stateless Session Bean with Local access at this link

1) In the HelloUser.java interface of the above example, replace the @Local annotation with the @Remote annotation


package info.icontraining.session;


import javax.ejb.Remote;
@Remote
public interface HelloUser {
   public String sayHello(String name);
}


2) The client in this case will not a Servlet (since the servlet object in the above example, exists in the same JVM heap as the EJB3 Session bean object, so it is not a remote object). We shall instead create a standalone Java application that executes outside the Application Server in a differente JVM Heap, effectively making the EJB Client a remote client.

Also, ensure that the EJB Project is present in the Build Path of the HelloClient Java Project. Right-click on the HelloClient Java project and select the "Java Build Path" option. Select the "Projects" tab and select add the EJB Project by clicking on the "Add..." button.

HelloClient.java


package com.yesm.client;



import java.util.Hashtable;
import javax.naming.*;
import info.icontraining.session.*;



public class HelloClient {
   public static void main(String[] args) {

      Hashtable env = new Hashtable();
      env.put("java.naming.factory.initial",
              "org.jnp.interfaces.NamingContextFactory");
      env.put("java.naming.factory.url.pkgs",
              "org.jboss.naming:org.jnp.interfaces");
      env.put("java.naming.provider.url","localhost:1099");

      Context context = null;

      try {
         context = new InitialContext(env);

         HelloUser helloUser = (HelloUser) context.lookup("MyEarApp/" +
                        HelloUserBean.class.getSimpleName() + "/remote");
         System.out.println(helloUser.sayHello("Dinesh"));
      } catch (NamingException e) {
         e.printStackTrace();
      }
   }
}


3) Deploy the EAR (Enterprise Application) according to instructions specified in the above example. Once the EAR is deployed, execute the EJB Client code to test remote accessibility of the EJB3 Stateless Session Bean.

June 1, 2011

EJB3 Entity Beans - Hello World Example

0) Download the Oracle Database 10g Express Edition and setup according to instructions on this link

1) Create a new Java Project named JPAdemo, in Eclipse. Click Finish.

Add the Oracle JDBC driver jar(ojdbc14.jar) to the build path of the project. This jar file is present at the following path of the Oracle installation - %ORACLE_HOME%\app\oracle\product\10.2.0\server\jdbc\lib

Also, add all the jars files present in the JBoss-4.2.2GA application server at the following paths:
- %JBOSS_HOME%\lib
- %JBOSS_HOME%\server\default\lib

2) Create a new class, Message.java in the src folder of the project. This class is the Entity Bean or the persistent class / entity according to the Java Persistence API (JPA) terminology.
The annotations in this class are equivalent to the configurations in the hibernate mapping files of the Hibernate persistence framework.


package info.icontraining.entity;


import javax.persistence.*;


@Entity
@Table(name="MESSAGES_TABLE_JPA")
public class Message {


    @Id
    @GeneratedValue
    @Column(name="MESSAGE_ID")
    private Long id;

    @Column(name="MESSAGE_TEXT")
    private String text;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="NEXT_MESSAGE_ID")
    private Message nextMessage;

    private Message() { }

    public Message(String text) {
        this.text = text;
    }


    public Long getId() {
        return id;
    }


    public void setId(Long id) {
        this.id = id;
    }


    public String getText() {
        return text;
    }


    public void setText(String text) {
        this.text = text;
    }


    public Message getNextMessage() {
        return nextMessage;
    }


    public void setNextMessage(Message nextMessage) {
        this.nextMessage = nextMessage;
    }
}


3) Create another class - Client.java - within the src folder. This class contains code to persist entities (or persistent objects) to the database table and retrieve data into persistent objects from the database table.


package info.icontraining.client;


import java.util.List;
import info.icontraining.entity.*;


import javax.persistence.*;


public class Client {


    public static void main(String[] args) {

        EntityManagerFactory emf = 
               Persistence.createEntityManagerFactory("JPAdemo");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        Message msg = new Message("Hello World");
        em.persist(msg);

        tx.commit();
        em.close();

        EntityManager newEm = emf.createEntityManager();
        EntityTransaction newTx = newEm.getTransaction();

        newTx.begin();

        List msgs = newEm.createQuery
           ("select m from Message m order by m.text asc").getResultList();

        System.out.println(msgs.size() + " messages found.");

        for(Object m: msgs) {
            Message loadedMsg = (Message)m;
            System.out.println(loadedMsg.getText());
        }

        newTx.commit();
        newEm.close();

        emf.close();
    }
}


4) Add the following XML configuration file, named persistence.xml within the src\META-INF folder


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
   <persistence-unit name="JPAdemo">
      <properties>
        <property name="hibernate.archive.autodetection" value="class,hbm" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.connection.driver_class" 
                          value="oracle.jdbc.OracleDriver" />
        <property name="hibernate.connection.url" 
                          value="jdbc:oracle:thin:@localhost:1521:xe" />
        <property name="hibernate.connection.username" value="xxxxx" />
        <property name="hibernate.connection.password" value="xxxxx" />
        <property name="hibernate.dialect" 
                          value="org.hibernate.dialect.Oracle9Dialect" />
        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.generate_statistics" value="true" />
        <property name="cache.provider_class" 
                          value="org.hibernate.cache.NoCacheProvider" />
      </properties>
   </persistence-unit>
</persistence>


5) Run the Client.java class as a standalone Java program to test the Entity Bean

May 31, 2011

EJB3 Stateful Session Bean - Hello World Example

0) To setup an EJB3 project within an Enterprise Application (EAR) and deploy it to the JBoss Application Server, visit this link

1) In the MyEJBProject, create two classes - Account.java and AccountBean.java - within the ejbModule folder

Account.java


package info.icontraining.session;


import javax.ejb.*;


@Remote
public interface Account {


  public float deposit(float amount);
  public float withdraw(float amount);
  
  @Remove 
  public void remove();


}


AccountBean.java


package info.icontraining.session;


import javax.ejb.*;


@Stateful(name="AccountBean")
@Remote(Account.class)  
public class AccountBean implements Account {
   
    float balance = 0;


    public float deposit(float amount){
        balance += amount;
        return balance;
    }
 
    public float withdraw(float amount){
        balance -= amount;
        return balance;
    }

    @Remove  
    public void remove() {
        balance = 0;
    }
}


2) Within the web application, create two JSPs - accountForm.jsp and accountDetails.jsp - within the WebContent folder

accountForm.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1" %>


<html>
<body>


<h1><p align="center">Bank Transaction Form</p></h1>
<hr/><br/>

<form action="accountDetails.jsp" method="post">
  <table align="center"> 
   <tr><td>Enter the amount: <input type="text" name="amt" size="10"></td></tr>
   <tr><td><b>Select your choice:</b></td></tr>
   <tr><td><input type="radio" name="operation" value ="dep">Deposit</td></tr>
   <tr><td><input type="radio" name="operation" value ="with">Withdraw<br/></td></tr>
   <tr><td><input type="radio" name="operation" value ="balance">Check Balance<br/></td></tr>
   <tr><td><input type="submit" value="Submit"><input type="reset" value="Reset"></td></tr>
  </table>
</form>


</body>
</html>



accountDetails.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1" %>
<%@ page import="info.icontraining.session.*, javax.naming.*"%>


 <%!
     public Account account = null;
     float bal=0;


     public void jspInit() {
         try {
            InitialContext ic = new InitialContext();
            account = (Account) ic.lookup("MyEarApp/AccountBean/remote");
            System.out.println("Loaded Account Bean");
         } catch (Exception ex) {
            System.out.println("Error: "+ ex.getMessage());
         }
     }
    
     public void jspDestroy() {
        account = null;
     }
%>


   <%
    try {
       String s1 = request.getParameter("amt");
       String s2 = request.getParameter("operation");


       if (s1.equals("")) s1=null;
       
       if ( s1 != null) {
           Float amt  = new Float(s1);
                
           if(s2.equals("dep")) {
               bal=account.deposit(amt.floatValue());
               out.println("Balance is: " + bal);
               out.println("<br/><a href=accountForm.jsp>Go back</a>");


           } else if(s2.equals("with")) {
               bal=account.withdraw(amt.floatValue());
               out.println("Balance is: " + bal);
               out.println("<br/><a href=accountForm.jsp>Go back</a>");
           
           } else {        
   %>
             <p>Please select your choice</p>
                
   <%
           }
    } else {
   
           if (account != null) {  
   %>
           <p><b>Your Current Balance is:</b> <%= bal%><br/>
           <% out.println("<br/><a href=accountForm.jsp>Go back</a>"); %>
           <p>
   <%     
           }
     }
  } catch (Exception e) {
       e.printStackTrace();
  }
%>


3) Deploy the Enterprise Application comprising of the EJB Project and the Web Application.
Type the following URL in the browser and test the stateful session bean:

http://localhost:8080/MyEarApp/accountForm.jsp

EJB3 Stateless Session Bean - Hello World Example

1) Open Eclipse. Go to File > New > Project ...
Select EJB > EJB Project
Name the Project as MyEJBProject. Click Next.
Ensure that "EJB Module" with "3.0" as the version & "Java" with "5.0" as the version, checkboxes are ticked. Click Next. Click Finish.

2) In the MyEJBProject, create the following pieces of code within the ejbModule folder

HelloUser.java interface


package info.icontraining.session;


import javax.ejb.Local;


@Local  
public interface HelloUser {
      public String sayHello(String name);
}


HelloUserBean.java class



package info.icontraining.session;


import javax.ejb.Stateless;


@Stateless
public class HelloUserBean implements HelloUser {

      public String sayHello(String name) {
           return "Hello " + name + "! Welcome to EJB 3!";
      }
}


3) In your web application project (this is a different project compared to the EJB project just created above), add the following servlet code and configure it in the web.xml file

HelloUserClient.java servlet class


package info.icontraining.ejb.client;


import javax.naming.*;
import info.icontraining.session.*;
import java.io.*;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.*;


public class HelloUserClient extends HttpServlet {


   public void doGet(HttpServletRequest req, HttpServletResponse res) 
                   throws ServletException, IOException {

       Hashtable env = new Hashtable(); 
       env.put("java.naming.factory.initial", 
                       "org.jnp.interfaces.NamingContextFactory");
       env.put("java.naming.factory.url.pkgs", 
                       "org.jboss.naming:org.jnp.interfaces"); 
       env.put("java.naming.provider.url","localhost:1099"); 


       PrintWriter out = res.getWriter();

       Context context;
       try {
           context = new InitialContext(env);

           HelloUser helloUser = (HelloUser) context.lookup("MyEarApp/" 
+ HelloUserBean.class.getSimpleName() + "/local");

           out.println(helloUser.sayHello("Dinesh"));

       } catch (NamingException e) {
           e.printStackTrace();
       }
   }      
}


web.xml configuration


<servlet>
    <servlet-name>HelloUserClient</servlet-name>
    <servlet-class>info.icontraining.ejb.client.HelloUserClient</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HelloUserClient</servlet-name>
    <url-pattern>/helloUserClient</url-pattern>
</servlet-mapping>


4) Right-click on the Web Application Project and select the "Properties" menu item.
Select "Java Build Path" from the options on the left.
Click on the "Projects" Tab.
Click the "Add..." button; Tick the "MyEJBProject" checkbox. Click OK. Again, click OK.
Any build errors in the Web Application project / servlet class will get removed.

5) Click on the "File" menu item at the top.
Select New > Project ...
Choose "J2EE" and then "Enterprise Application Project". Click Next.
Name the project as "MyEarApp". Click Next.
Check the "MyEJBProject" and the Web Application Project as the 2 modules to be added within the Enterprise Application Project. Also, check the "Generate Deployment Descriptor" option.
Click Finish.

Note: In Eclipse Helios, after creating the Enterprise Application Project, right click on the project, select Properties. In the pop-up window, select "Deployment Assembly" on the left. Then click on the "Add..." button and select choose Project and click Next. Select the 2 projects - the EJB Project (MyEJBProject) and the web application project together (by pressing down the CTRL key). Click Finish.

6) Open the application.xml file within the new created EAR project - MyEarApp - within the EarContent/META-INF folder.
Modify the <context-root> element of the web application to /MyEarApp

7) Deploy the MyEarApp project to the JBoss Application Server and test the EJB by typing the following URL in the browser:

http://localhost:8080/MyEarApp/helloUserClient