June 26, 2011

Creating a JSP custom tag in a custom tag library (TLD)

To create your own JSP tag described in your own custom Tag Library Descriptor (TLD), do the following steps,

1) Create a Java class that will do the work of the tag when the tag is encountered in the JSP - MyTagHandler.java - in the src folder of the web application

package info.icontraining.jsp;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class MyTagHandler extends SimpleTagSupport {

   private String value;
 
   public void setValue(String value) {
      this.value = value;
   }
 
   public String getValue() {
      return this.value;
   }
 
   public void doTag() throws JspException, IOException {
      getJspContext().getOut().write("Output from tag: ");
      getJspContext().getOut().write("Value is " + getValue());
   }
}

2) Create a TLD file - mytld.tld - in the WebContent/WEB-INF folder of the web application with the following configuration for the tag

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

<taglib 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-jsptaglibrary_2_1.xsd"
    version="2.1">
    
    <description>Test description</description>
    <display-name>My TLD</display-name>
    <tlib-version>1.1</tlib-version>
    <short-name>mine</short-name>
    <uri>myUriForMyTLD</uri>
    
    <tag>
        <description>My Tag Description</description>
        <name>testTag</name>
        <tag-class>info.icontraining.jsp.MyTagHandler</tag-class>
        <body-content>empty</body-content>
        <attribute>
              <description>My attribute description</description>
              <name>value</name>
              <required>true</required>
              <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>

3) Create a JSP - myTagTest.jsp - and add it to the WebContent folder of the web application with the following code

<%@ taglib prefix="mine" uri="myUriForMyTLD" %>

<html>
<body>

<mine:testTag value="something" />

</body>
</html>

4) Test the code with the following URL in the browser,

http://localhost:8080/WebAppName/myTagTest.jsp

The include directive, JSP include action and JSP forward action

JSP Include Directive

The JSP include directive allows including another, outside JSP file (containing text or code) into a JSP. This allows creating modular pages and avoid duplication of content across JSPs. The insertion of the outside JSP content is done during the translation of the JSP to a Java class by the Container.

1) Create a JSP - includeDirectiveTest.jsp - in the WebContent folder of the web application

<html>
<body>

<%@ include file="header.jsp"  %>

This is the body<br/>

<%@ include file="footer.jsp"  %>

</body>
</html>

2) Create 2 JSPs - header.jsp & footer.jsp - also in the WebContent folder of the web application

header.jsp
This is the header<br/>

footer.jsp
This is the footer<br/>

3) Test the code with the following URL in the browser:

http://localhost:8080/WebAppName/includeDirectiveTest.jsp

JSP Include Action

The JSP include action works similar to the include directive with a fundamental difference - instead of inserting the contents of the included outside JSP into the including JSP (at translation time), the JSP include action inserts the response from the included JSP at runtime.

1) Create a new JSP - includeActionTest.jsp - in the WebContent folder of the web application

<html>
<body>
<jsp:include page="header.jsp" />

This is the body<br/>

<jsp:include page="footer.jsp" />

</body>
</html>

2) Test the code with the following URL in the browser:

http://localhost:8080/WebAppName/includeActionTest.jsp


JSP Forward Action

The JSP forward action forwards the request from one JSP page to another.

Similar to the JSP include action, the JSP forward action creates a RequestDispatcher with the page attribute value as an argument to the RequestDispatcher and then invokes the forward() method on the RequestDispatcher.

1) Create a JSP - forwardActionTest.jsp - in the WebContent folder of the web application

<html>
<body>
<jsp:forward page="anotherJsp.jsp" />

</body>
</html>

2) Test the code with the following URL in the browser:

http://localhost:8080/WebAppName/forwardActionTest.jsp

Accessing the forwardActionTest.jsp will cause anotherJsp.jsp to be rendered in the browser.

Unable to load configuration - action - struts.xml

Topic: Struts 2.1.8.1

Application Server: JBoss 4.2.2 GA

Exception:

INFO  [STDOUT] 08:42:44,593 ERROR [Dispatcher] Dispatcher initialization failed
Unable to load configuration. - action - file:/C:/jboss-4.2.2.GA/jboss-4.2.2.GA/server/default/tmp/deploy/tmp6158064408942958403Struts2Demonstration-exp.war/WEB-INF/classes/struts.xml:16:74
 at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:58)
 at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:374)
 at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:418)
 at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:190)
 at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
 at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
 at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:108)
 at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3722)
 at org.apache.catalina.core.StandardContext.start(StandardContext.java:4367)
 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:790)
 at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:770)
 at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:553)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Resolution:

The Struts 2 framework has dependencies on the following distributables:

- commons-fileupload-1.2.1.jar
- commons-io-1.3.2.jar
- commons-logging-1.0.4.jar
- commons-logging-api-1.1.jar
- freemarker-2.3.15,jar
- log4j-1.2.14.jar
- ognl-2.7.3.jar
- xwork-core-2.1.6.jar

Adding these jars to the WEB-INF/lib folder of the web application resolves this error. All these jars as as well as the Struts distribution may be downloaded from this link

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.

Difference between addHeader and setHeader methods on the HttpServletResponse

Note: To test this example, use the Firefox browser with the 'Live HTTP Headers' add-on of Mozilla installed in firefox. Access this link from firefox - https://addons.mozilla.org/en-US/firefox/addon/live-http-headers/

The setHeader() method on the HttpServletResponse object allows setting a new header/value pair in the HTTP Response message. If a header with the same name already exists, the method will overwrite the value with the new value passed in the method.

The addHeader() method, however, will not overwrite an existing header value if a header with the same name already exists. It instead just associates this value with the header as an additional value making the header have multiple values. If the header does not already exist, the addHeader() works just like the setHeader().

1) Create the HeaderTest.java servlet class within the src folder of the web application

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HeaderTest extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
  
      PrintWriter out = response.getWriter();
      response.setHeader("h1", "Hello");
      response.addHeader("h1", "Bye");
        
      response.setHeader("h2", "Hello");
      response.addHeader("h2", "Bye");
      response.setHeader("h2", "Hi");

      out.close();
   }
}


2) Configure the servlet in the web.xml file of the web application present in the WebContent/WEB-INF folder

<servlet>
   <servlet-name>headerTest</servlet-name>
   <servlet-class>info.icontraining.servlets.HeaderTest</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>headerTest</servlet-name>
   <url-pattern>/headers</url-pattern>
</servlet-mapping>


3) Test the code by accessing the following URL in the browser. Check the response headers in the screen for the Live HTTP Headers add-on for firefox.

http://localhost:8080/WebAppName/headers

Context or Application attributes on the ServletContext object

Context attributes, also called Application attribute (since context attributes are said to have applicaiton scope) are set on the ServletContext object of the Servlet API.

1) Create a Servlet class, ServletOne.java in the src folder of the web application. This Servlet contains code to set an attribute in the Application scope.

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;

public class ServletOne extends HttpServlet {
 
   public void doGet (HttpServletRequest req, HttpServletResponse res)
     throws ServletException, IOException {
   
      ServletContext sc = getServletContext();
      sc.setAttribute("testAttribute", "testValue");
   
      PrintWriter out = res.getWriter();
   
      out.println("<html><body>");
      out.println("Context Attribute Set. <br/>");
      out.print("<a href=\"two\">");
      out.println("Click to access ServletTwo</a>");
      out.println("</body></html>");
   }
}


2) Create a second Servlet Class, ServletTwo.java also in the src folder of the web application. This servlet procures the attribute set in the Application scope and prints its value.

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;

public class ServletTwo extends HttpServlet {
 
   public void doGet (HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
   
      ServletContext sc = getServletContext();
      String value = (String) sc.getAttribute("testAttribute");
   
      PrintWriter out = res.getWriter();
   
      out.println("Context Attribute procured");
      out.println("Value is = " + value);
   }
}


3) Configure both servlets in the web.xml file present within the WebContent/WEB-INF folder of the web application

<servlet>
   <servlet-name>servletOne</servlet-name>
   <servlet-class>info.icontraining.servlets.ServletOne</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>servletOne</servlet-name>
   <url-pattern>/one</url-pattern>
</servlet-mapping>
  
<servlet>
   <servlet-name>servletTwo</servlet-name>
   <servlet-class>info.icontraining.servlets.ServletTwo</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>servletTwo</servlet-name>
   <url-pattern>/two</url-pattern>
</servlet-mapping>


4) Test the code by typing the following URL in the browser

http://localhost:8080/WebAppName/one

Redirect request with the sendRedirect() method on HttpServletResponse

The sendRedirect() method on the response object (HttpServletResponse) redirects a request received by the Servlet / web component to another Servlet / web component or URL. The URL may be for a component within the same web application or outside it.

This is in contrast to the RequestDispatcher 's request dispatching that can only internally dispatch a request from one servlet / web component to another one within the same web application.

1) Create a servlet class that contains the re-direction code, in the src folder of the web application

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;

public class YahooServlet extends HttpServlet {

   public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    
      res.sendRedirect("http://www.yahoo.com");
   }
}


2) Configure the servlet within the web.xml file present in the WebContent/WEB-INF folder of the web application

<servlet>
   <servlet-name>yahooServlet</servlet-name>
   <servlet-class>info.icontraining.servlets.YahooServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>yahooServlet</servlet-name>
   <url-pattern>/yahoo</url-pattern>
</servlet-mapping>


3) Test the code by typing the following URL in the browser,

http://localhost:8080/WebAppName/yahoo

June 12, 2011

Writing binary content to the HTTP response from a Servlet

The getWriter() method on the HttpServletResponse object returns a PrintWriter object which is used for writing text data to the response. When binary data has to be returned in the response (for example, a file download), the getOutputStream() method may be invoked on the response object. The following code example demonstrates the same.

1) Create the Servlet class in the src folder of the web application as follows,

package info.icontraining.servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class BinaryResponseServlet extends HttpServlet{

   public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

      response.setContentType("application/pdf");

      InputStream is = getServletContext().getResourceAsStream("/WEB-INF/test.pdf");
      OutputStream outs = response.getOutputStream();

      int inByte = 0;
      while ((inByte = is.read()) != -1) {   
         outs.write(inByte);
      }

      outs.flush();
      outs.close();
      is.close();
   }
}


2) Configure the servlet in the web.xml file present in the WebContent/WEB-INF folder of the web application

<servlet>
    <servlet-name>binaryResponse</servlet-name>
    <servlet-class>info.icontraining.servlets.BinaryResponseServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>binaryResponse</servlet-name>
    <url-pattern>/downloadFile</url-pattern>
</servlet-mapping>


3) Add the binary file (in this case any pdf file renamed as test.pdf) to the WebContent/WEB-INF folder of the web application.

4) Test the servlet by typing the following URL in the browser

http://localhost:8080/WebAppName/downloadFile

enum in Java (Enumerated data types)

Enumerated data types can be created in Java with the enum keyword. Variable declared of the enum type can then only hold values listed in the definition of the enum type.

enums can be declared within a class as a class member or outside a class. When declared inside a class as a member, access modifiers can be applied to the enum and the same rules of access modifiers as for other members apply to an enum as well. An enum declaration also needs the enclosing class-name when accessing it outside the class.

An enum however cannot be declared within a method.

Just like a class, enums can have constructors, instance variables and methods.
An enum constructor, unlike a class constructor, cannot be directly invoked. It can only be invoked from within the enum from the listed enumerated values.


package info.icontraining.core;

enum Gender { MALE, FEMALE };

public class EnumExample {
 
   enum Color { 
      
      SAFFRON("top"), WHITE("middle"), GREEN("bottom");

      private String position;

      Color(String position) {
         this.position = position;
      }
 
      public String getPosition() {
         return this.position;
      }
   };
  
   Color color;   
   Gender gender;

   public static void main(String[] args) {
      EnumExample e = new EnumExample();
  
      e.gender = Gender.MALE;
      e.color = EnumExample.Color.SAFFRON;
  
      System.out.println(e.color.getPosition());
   }
}

Variable Argument Parameters List in Java (Var-args)

Java 5.0 supports invoking methods with a variable number of arguments (Var-args). The variable arguments are received in the method parameter as an array object. There can be only one variable argument parameter in a method and it must be the last one in the order of parameters. The variable-argument parameter is declared in the method as follows:

[type of parameter][ellipsis (three dots)][white-space][name of array variable]

For example, the following declares a String-type var-arg, and the arguments are stuffed in a String array:

String... strArray


package info.icontraining.core;

public class VarargExample {

   public static void main(String[] args) {
      varargMethod(true, "A", "B", "C");
      varargMethod(false,"E", "F");
      varargMethod(true, "G", "H", "I", "J");
   }
 
   public static void varargMethod(boolean b, String... names) {
      System.out.println("Number of var-arg values: " + names.length);
      for (String s: names) {
         System.out.print(s + " ");
      }
      System.out.println();
   }
}

Java Collections Framework: Map Example with HashMap and equals() and hashCode() implementation

The HashMap implementation of the Map interface uses hashing to store and find objects. Putting a good implementation of the hashCode() method optimizes searching for objects.

The containsKey() and the containsValue() methods use the equals() method to check for meaningful equality of objects. Classes that have not implemented the equals() methods will not be checked for meaningful equality and will only be checked for referential equality by the containsKey() and the containsValue() methods.

HashMapExample.java

package info.icontraining.collections;

import java.util.*;

public class HashMapExample {

   public static void main(String[] args) {
  
      Map<Customer, Integer> map = new HashMap<Customer, Integer>();

      map.put(new Customer("Dinesh", "Atlanta"), 1);
      map.put(new Customer("Tanvi", "Norcross"), 2);
      map.put(new Customer("Laksh", "Duluth"), 3);
      map.put(new Customer("Dinesh", "Alpharetta"), 4);

      System.out.println("Size of Map = " + map.size());  
      System.out.println(map.containsKey(new Customer("Laksh", "Duluth")));       }
}

Customer.java

package info.icontraining.collections;
 
public class Customer {

   private String customerName;
   private String customerCity;
 
   public Customer(String customerName, String customerCity) {
      this.customerName = customerName;
      this.customerCity = customerCity;
   }
 
   public String getCustomerName() {
      return this.customerName;
   }
 
   public String getCustomerCity() {
      return this.customerCity;
   }
 
   public int hashCode() {
      return customerName.length() + customerCity.length();
   }
 
   public boolean equals(Object c) {
      if ((this.customerName.equals(((Customer)c).customerName)) 
          && (this.customerCity.equals(((Customer)c).customerCity))) {
         return true;
      }
      return false;
   }
}

Java Collections Framework: TreeSet Example with Comparable and Comparator implementation

The TreeSet implementation of the Set interface maintains a sorted collection of unique objects. The custom sort order is determined by implementing either the Comparable interface or the Comparator interface.

In case of the Comparable interface, the class (objects of which will be added to the TreeSet) has to implement the interface.

In case of the Comparator interface. an external class implements the interface. The Comparator allows creating a custom sort order for objects of a 3rd party class.

TreeSet code example with Comparable to compare objects for custom sort order

package info.icontraining.collections;

import java.util.*;

public class TreeSetExample {

   public static void main(String[] args) {
 
      Set customers = new TreeSet();

      customers.add(new Customer("Dinesh", "Atlanta"));      
      customers.add(new Customer("Tanvi", "Norcross"));
      customers.add(new Customer("Laksh", "Duluth"));
  
      for(Customer c: customers) {
         System.out.print(c.getCustomerName() + " | ");
         System.out.println(c.getCustomerCity());      
      }  
     
      customers.add(new Customer("Dinesh", "Alpharetta"));

      System.out.println();

      for(Customer c: customers) {
         System.out.print(c.getCustomerName() + " | ");
         System.out.println(c.getCustomerCity());      
      }    
   }
}

package info.icontraining.collections;

public class Customer implements Comparable {

   private String customerName;
   private String customerCity;
 
   public Customer(String customerName, String customerCity) {
      this.customerName = customerName;
      this.customerCity = customerCity;
   }
 
   public int compareTo(Customer customer) {
      int nameOrder = this.customerName.compareTo(customer.customerName);

      if (nameOrder == 0)
         return this.customerCity.compareTo(customer.customerCity);
  
      return nameOrder;
   }
 
   public String getCustomerName() {
      return this.customerName;
   }
 
   public String getCustomerCity() {
      return this.customerCity;
   }
}

TreeSet code example with Comparator to compare objects for custom sort order

Using the Comparator interface entails creating a new class to implement the interface. The Comparator should be used in the situation where the Customer class is a 3rd party class whose source code is unavailable to us.

package info.icontraining.collections;

import java.util.Comparator;

public class CustomerComparator implements Comparator {

   public int compare(Customer c1, Customer c2) {
      int nameOrder = c1.getCustomerName().compareTo(c2.getCustomerName());
  
      if (nameOrder == 0)
         return c1.getCustomerCity().compareTo(c2.getCustomerCity());
  
      return nameOrder;
   }
}

Also make the following changes to run the example with Comparator instead of Comparable,

1) From the Customer class, remove the implements Comparable

2) In the TreeSetExample class, replace the following line to instantiate the TreeSet

Set<Customer> customers = new TreeSet<Customer>();

with

Set<Customer> customers = new TreeSet<Customer>(new CustomerComparator());

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