Tag: EE6 Feature

EE6 feature JSR-303 Bean validation in JBoss AS7

Hi,

JavaBeans Validation is a new validation model available as part of Java EE 6 platform. The Bean Validation model is supported by constraints in the form of annotations placed on a field, method, or class of a JavaBeans component, such as a managed bean.

JSR-303 Bean Validation specification allows us to generate the Java Bean validation. Bean Validation aims at standardizing constraint validation for the the Java platform. Validating data that eventually feeds into the domain model is a common task that is copied in many different layers of an application, from the presentation tier to the persistentce layer. Many times the exact same constraints and validation logic has to be duplicated in each separate validation framework, which is time-consuming and error-prone. More information about this specification can be found in the following link: http://jcp.org/en/jsr/detail?id=303

Red Hat has been heavily involved in the making of Java EE 6. Here are some of the specs RedHat has put a lot of effort into either by contributing heavily or by leading the standardization effort: Java Persistence 2, Java Server Faces 2, JSR-299 formely known as Web Beans, JSR-303 Bean Validation. More information about this can be found in the following interesting FAQ section: http://www.jboss.com/about/leadership/jsr/bernard.html

Features To Discuss.

In this example we will mainly focus on following points

Point-1). Here we are using JBoss AS7 latest build “jboss-as-7.1.0.CR1b” which can be downloaded from the following link: http://www.jboss.org/jbossas/downloads

Point-2). How to utilize Existing JSR-303 annotations “javax.validation.constraints.*” inside our application.

Point-3). How to create our own Custom Validation Rules (Annotations), Example E-Mail Address Validation @ValidateEMail(domain=”middlewaremagic.com”)

Point-4). Also we will see how to implement Bean Validation inside JSF2.0 @ManagedBean’s

Developing Web Application using JSR-303

Step1). Create a directory somewhere in your file system like “/home/userone/JSF2_BeanValidation_Demo” where we will place our application build related stuff. Then create another directory “src” inside “/home/userone/JSF2_BeanValidation_Demo” where we will be placing our source codes and JSPs.

Step2). Create Bean class “HelloBean.java” as following inside the “/home/userone/JSF2_BeanValidation_Demo/src” directory.

package org;
import java.io.Serializable;

// faces APIs
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

//Validation APIs
import javax.validation.constraints.Size;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import custom.validators.ValidateEMail;

@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {
 
        @Size(min=4, max=240, message="The Name {javax.validation.constraints.Size.message}")
	private String name;
 	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}


        @NotNull (message="The Salary {javax.validation.constraints.NotNull.message}")
        @Max(value=50000, message="The Salary {javax.validation.constraints.Max.message}")
        @Min(value=25000, message="The Salary {javax.validation.constraints.Min.message}")
	private Integer salary;
 	public Integer getSalary() {
		return salary;
	}
	public void setSalary(Integer salary) {
		this.salary = salary;
	}

        // NOTE: - "custom.validators.ValidateEMail" is our Custom Validator Annotation.
        @ValidateEMail(domain="middlewaremagic.com")
        private String emailAddress;
        public String getEmailAddress() {
                return emailAddress;
        }
        public void setEmailAddress(String emailAddress) {
                this.emailAddress = emailAddress;
        }

}

Step3). Now we will create a Validator wich will validate whether an E-Mail address entered by the user has domain “middlewaremagic.com” or not? So we will create an Interface first with some name like “ValidateEMail.java” inside “/home/userone/JSF2_BeanValidation_Demo/src” directory as following:

package custom.validators;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = ValidateEMail_Impl.class)
@Documented
public @interface ValidateEMail {

    String message() default "E-Mail Address must belong to mail domain as {domain}";
    Class<?>[] groups() default {};
    String domain();
    Class<? extends Payload>[] payload() default {};
}

Step4). Now provide the implementation of the above interface “ValidateEMail_Impl.java” to provide the actual logic of the validation whether the E-Mail entered by user is containing “middlewaremagic.com” or not? So Place this file as well inside the “/home/userone/JSF2_BeanValidation_Demo/src” directory as following:

package custom.validators;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.StringTokenizer;


public class ValidateEMail_Impl implements ConstraintValidator<ValidateEMail, String> {

    private String domain;
    public void initialize(ValidateEMail constraintAnnotation) {
        System.out.println("nt initialize() called");
        String emailDomain = constraintAnnotation.domain();
        String msg = constraintAnnotation.message();

        setDomain(emailDomain);
        if (emailDomain == null || emailDomain.equals("")) {
            throw new IllegalArgumentException("The email address specified in @"+ ValidateEMail.class.getSimpleName() + " must not be null.");
        }
    }

    public boolean isValid(String email,ConstraintValidatorContext constraintValidatorContext) {
        boolean valid=false;
        System.out.println("nt isValid() called");
        if (email == null)
           {
               return false;
           }
        else
           {
              StringTokenizer st=new StringTokenizer(email,"@");
              if(st.countTokens() == 2  )
               {
                   st.nextToken();  // Ignoring first tooken
                   String emailDomain=getDomain();   // like   middlewaremagic.com
                   if(st.nextToken().trim().equals(emailDomain))
                     {
                       valid=true;
                       return valid;
                     }
               }
              else
               {
                   return valid;
               }
           }
        return valid;
    }

    public void setDomain(String domain)
    {
      System.out.println("nt setDomain  called domain= "+domain);
      this.domain=domain;
    }
    public String getDomain()
    {
      System.out.println("nt getDomain  called ");
      return domain;
    }
}

Step5). Now as we are going to use the Bean Validation inside JSF2.0 application so we will a simple “faces-config.xml”, Place this file as well inside the “/home/userone/JSF2_BeanValidation_Demo/src” directory as following:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    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"
	version="2.0">

    <!-- After adding the message-bundle make sure that we place "ApplicationMessages.properties" file inside "WEB-INF/classes" directory. -->
    <application>
        <message-bundle>ApplicationMessages</message-bundle>
    </application>

</faces-config>

Step6). Now we will create “ApplicationMessages.properties” file, Place this file as well inside the “/home/userone/JSF2_BeanValidation_Demo/src” directory as following (We need to make sure that this file goes inside the “WEB-INF/classes” directory once the application is built.):

javax.validation.constraints.Min.message=must be greater than or equal to {value}
javax.validation.constraints.Max.message=must be less than or equal to {value}

javax.validation.constraints.Null.message=must be null
javax.validation.constraints.NotNull.message=must not be null

javax.validation.constraints.Past.message=must be a past date
javax.validation.constraints.Future.message=must be a future date

javax.validation.constraints.Size.message=size must be between {min} and {max}
javax.validation.constraints.Digits.message=numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected)

javax.validation.constraints.AssertTrue.message=must be true
javax.validation.constraints.AssertFalse.message=must be false

javax.validation.constraints.Pattern.message=must match the following regular expression: {regexp}


custom.validators.ValidateEMail.message= E-Mail Address must belong to mail domain as {domain}

Step7). Now we will write simple “hello.xhtml” file inside “/home/userone/JSF2_BeanValidation_Demo/src” directory as following to provide a form to the user to enter some inputs:

<?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:f="http://java.sun.com/jsf/core"      
      xmlns:h="http://java.sun.com/jsf/html">
 
    <h:head>
        <title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body>
    	<h3>JSF 2.0 Hello World Example - hello.xhtml</h3>
    	<h:form>
    	   <h:outputLabel id="usernameLabel" value="Enter UserName: "/> 
           <h:inputText id="usernameText" value="#{helloBean.name}">  </h:inputText>
           <h:message for="usernameText" errorStyle="color:red"/>

           <BR/>

    	   <h:outputLabel id="salaryLabel" value="Enter Salary: "/> 
           <h:inputText id="salaryText" value="#{helloBean.salary}">  </h:inputText>
           <h:message for="salaryText" errorStyle="color:red"/>

           <BR/>

    	   <h:outputLabel id="emailLabel" value="Enter emailAddress: "/> 
           <h:inputText id="emailText" value="#{helloBean.emailAddress}">  </h:inputText>
           <h:message for="emailText" errorStyle="color:red"/>

           <BR/>

    	   <h:commandButton value="Welcome Me" action="welcome"></h:commandButton>
    	</h:form>
    </h:body>
</html>

Step8). Now we will write simple “welcome.xhtml” file inside “/home/userone/JSF2_BeanValidation_Demo/src” directory as following to get the details entered by the user in previous xhtml form:

<?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:h="http://java.sun.com/jsf/html">
 
    <h:head>
    	<title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body bgcolor="white">
    	<h3>JSF 2.0 Hello World Example - welcome.xhtml</h3>
    	<h4>Welcome Mr.     <font color="green">#{helloBean.name}</font></h4>
    	<h4>Your Salary is  <font color="green">#{helloBean.salary} Rs/-</font></h4>
    	<h4>Your E-Mail is  <font color="green">#{helloBean.emailAddress}</font></h4>
    </h:body>
</html>

Step9). Now we will write the “web.xml” file inside “/home/userone/JSF2_BeanValidation_Demo/src” directory as following:

<?xml version="1.0"?>
<web-app version="3.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-app_3_0.xsd">

 <display-name>TestJSF Bean Validation EE6</display-name>
 <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

  <!-- Welcome page -->
  <welcome-file-list>
    <welcome-file>hello.xhtml</welcome-file>
  </welcome-file-list> 

  <!-- Map these files with JSF -->
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
</web-app>

Building and Deploying Application

Step10). Now the most important part, here we are going to develop “build.xml” ANT file, which will build, deployour webapplication on the JBoss jboss-as-7.1.0.CR1b Server, so write the following “build.xml” file inside “/home/userone/JSF2_BeanValidation_Demo” directory.

<project name="JSR-303_Demo" default="deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.CR1b" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="output.dir" value="build" />
<property name="src.dir" value="src" />
<property name="war.context" value="EE6_BeanValidationDemo" />
<property name="war.name" value="${war.context}.war" />

        <path id="jboss.classpath">
           <fileset dir="${jboss.module.dir}">
              <include name="**/*.jar"/>
           </fileset>  
        </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>
	 
        <target name="build" depends="init">
           <mkdir dir="${tmp.dir}/WEB-INF/classes"/>
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath" />
           <copy file="${src.dir}/hello.xhtml" todir="${tmp.dir}"/>
           <copy file="${src.dir}/welcome.xhtml" todir="${tmp.dir}"/>
           <copy file="${src.dir}/ApplicationMessages.properties" todir="${tmp.dir}/WEB-INF/classes"/>
           <copy file="${src.dir}/HelloBean.java" todir="${tmp.dir}/WEB-INF/classes"/>
           <copy file="${src.dir}/web.xml" todir="${tmp.dir}/WEB-INF"/>
           <copy file="${src.dir}/faces-config.xml" todir="${tmp.dir}/WEB-INF"/>
   
           <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
           <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/>

           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}"/>
           </delete> 
        </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />  
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  
            <echo message="http://localhost:8080/${war.context}" />
        </target>
</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script to point to your own JBoss AS7 directory.

Step11). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step12). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/JSF2_BeanValidation_Demo” and then run the ant to build the webservice. by running the command “ant deploy”

[userone@localhost JSF2_BeanValidation_Demo]$ ant deploy
Buildfile: /home/userone/JSF2_BeanValidation_Demo/build.xml

init:
   [delete] Deleting directory /home/userone/JSF2_BeanValidation_Demo/build
    [mkdir] Created dir: /home/userone/JSF2_BeanValidation_Demo/build
    [mkdir] Created dir: /home/userone/JSF2_BeanValidation_Demo/tmp

build:
    [mkdir] Created dir: /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF/classes
    [javac] Compiling 3 source files to /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/tmp/WEB-INF
      [jar] Building jar: /home/userone/JSF2_BeanValidation_Demo/tmp/EE6_BeanValidationDemo.war
     [copy] Copying 1 file to /home/userone/JSF2_BeanValidation_Demo/build

deploy:
     [echo] *******************  Deploying the WAR file EE6_BeanValidationDemo.war *********************
     [echo] ********** build/EE6_BeanValidationDemo.war to /home/userone/jboss-as-7.1.0.CR1b/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.CR1b/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************
     [echo] http://localhost:8080/EE6_BeanValidationDemo

BUILD SUCCESSFUL
Total time: 3 seconds

Step13). Now access the WebApplication like following :
http://localhost:8080/EE6_BeanValidationDemo

You will notice that the Bean Validation is working as following:

BeanValidation JSR-303 EE6 feature in JBoss

.
.
Thanks 🙂
Middleware Magic Team


Invoking a Local Stateless Bean from a Servlet in JBoss AS7

Hi,

Here in this demo we will see how to lookup Local EJB3 stateless Bean from a separate Web Application’s Servlet. Where as the EAR containing the Stateless EJB3 and the WAR are separately deployed on the same JBoss AS7 instance. Here we will also discuss the use of different JNDI Names.

The JNDI names for EJB session beans are assigned by the container via the following scheme:

1). Global JNDI
java:global[/<app-name>l]/<module-name>/<bean-name>l[!<fully-qualified-interface-name>l]

java:global JNDI can be used to lookup a resource which is deployed on the same server but as part of a separate application.

2). Application JNDI
java:app/<module-name>l/<bean-name>l[!<fully-qualified-interface-name>l]

java:app JNDI can be used to lookup a resource which is deployed on the same server but as part of the same application.

3). Module JNDI
java:module/<bean-name>l[!<fully-qualified-interface-name>l]

java:module allows a component executing within a Java EE application to access a namespace rooted below the portion of the namespace corresponding to its module.

More details about portable JNDI can be found in the EJB3.1 JSR-318 specification: http://jcp.org/en/jsr/detail?id=318

In this example we will mainly focus on following points

Point-1). Here we are using JBoss AS7 latest build “jboss-as-7.1.0.Alpha2-SNAPSHOT” Download Location :  https://ci.jboss.org/jenkins/job/JBoss-AS-7.x-latest/

Point-2). How to use and develop Servlets without defining servlet-mapping inside the “web.xml” file, while using the @javax.servlet.annotation.WebServlet annotation.

Point-3). How to perform a Local EJB lookup which is deployed as part of a Separate EAR file, with the help of Global JNDI lookup using @javax.ejb.EJB (lookup=””) annotation.

=========

Step1). Create a directory somewhere in your filesystem like “/home/userone/EJB3_LocalLookup_Demo” where we will place our application build related stuff. Then create another directory “src” inside “/home/userone/EJB3_LocalLookup_Demo” where we will be placing our source codes for EJB and WAR files.

Step2). Now we will create a Local Bean Interface “CallerLocal.java” file and Place this file as wll inside the “/home/userone/EJB3_LocalLookup_Demo/src” directory as following:

package caller;
import javax.ejb.*;
@Remote
public interface CallerLocal
{
     public String testMethod(String name);
}

Step3). Now we will create a Simple Stateless EJB with a simple business method to test whether we can invoke this EJB Locally or not. so provide a class inside “/home/userone/EJB3_LocalLookup_Demo/src” directory with name “TestAsyncStatelessSessionBean.java” as following:

package caller;
import javax.ejb.*;
import javax.naming.*;
import java.util.*;
@Stateless(name = "CallerName", mappedName = "CallerMappedName")
public class CallerBean implements CallerLocal
 {
     public String testMethod(String name)
	    {
		   System.out.println("nnt Bean's testMethod(String name) called....");
		   return "[CallerBean] returned Hello "+name;
	    }
 }

Step4). Now we will write the “application.xml” file inside the “/home/userone/EJB3_LocalLookup_Demo” directory to define the EAR application and to define the EJB module inside it as following:

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

<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">
  <display-name>EJB3_localCallDemo</display-name>
  <module>
    <ejb>localEJB.jar</ejb>
  </module>
</application>

Step5). Create Servlet class “TestServlet.java” as following inside the “/home/userone/EJB3_LocalLookup_Demo/src” directory.

package servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.ejb.*;
import javax.servlet.annotation.WebServlet;

@WebServlet(value="/TestServlet")
public class TestServlet extends HttpServlet
  {
     @EJB(lookup="java:global/TestLocalEJBEAR/localEJB/CallerName!caller.CallerLocal")
     private caller.CallerLocal local;
     public void service(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
       {
            PrintWriter out=res.getWriter();
            out.println("caller.CallerLocal local = "+local);
            out.println("nn");
            out.println("local.testMethod() = "+local.testMethod("MiddlewareMagic"));
       }
  }

Step6). Now the most important part, here we are going to develop “build.xml” ANT file, which will build and deploy our EAR and the WAR applications separately on the JBoss AS7.1 Server, so write the following “build.xml” file inside “/home/userone/EJB3_LocalLookup_Demo” directory.

<project name="SingletonStartupService" default="all">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="src.dir" value="src" />
<property name="output.dir" value="build" />
<property name="ear.name" value="TestLocalEJBEAR.ear" />
<property name="war.name" value="TestWebApp.war" />
<property name="ejb.jar" value="localEJB.jar" />

   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>  
   </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>
	 
        <target name="all" depends="deploy" />

        <target name="build_ear">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}"  includes="*.java" classpathref="jboss.classpath"/>

           <jar jarfile="${tmp.dir}/${ejb.jar}" basedir="${tmp.dir}" compress="true" />

           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/caller"/>
           </delete> 
           <mkdir dir="${tmp.dir}/META-INF"/>
           <copy todir="${tmp.dir}/META-INF">
                <fileset dir="${src.dir}/">
                  <include name="application.xml"/> 
                </fileset>
           </copy>           
           <jar jarfile="${tmp.dir}/${ear.name}" basedir="${tmp.dir}" compress="true" />
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/META-INF"/>
           </delete> 
           <delete file="${tmp.dir}/${ejb.jar}"/>

           <copy file="${tmp.dir}/${ear.name}" tofile="${output.dir}/${ear.name}"/>
           <delete file="${tmp.dir}/${ear.name}"/>
        </target>


        <target name="build_war">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}/WEB-INF/classes" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="CallerLocal.java,TestServlet.java" classpathref="jboss.classpath"/>
           <jar jarfile="${output.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
        </target>        

        <target name="deploy" depends="build_ear,build_war">
            <echo message="*******************  Deploying the EAR file ${ear.name} *********************" />  
            <echo message="********** ${output.dir}/${ear.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${ear.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />  
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  

        </target>
</project>


NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script is to point to your own JBoss AS7 directory home directory.

Step7). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step8). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/EJB3_LocalLookup_Demo” and then run the ant to build the webservice. by running the command “ant build”

[userone@localhost EJB3_LocalLookup_Demo]$ ant deploy
Buildfile: build.xml

build_ear:
   [delete] Deleting directory /home/userone/EJB3_LocalLookup_Demo/tmp
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp
    [javac] Compiling 3 source files to /home/userone/EJB3_LocalLookup_Demo/tmp
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/tmp/localEJB.jar
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp/META-INF
     [copy] Copying 1 file to /home/userone/EJB3_LocalLookup_Demo/tmp/META-INF
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/tmp/TestLocalEJBEAR.ear
   [delete] Deleting: /home/userone/EJB3_LocalLookup_Demo/tmp/localEJB.jar
     [copy] Copying 1 file to /home/userone/EJB3_LocalLookup_Demo/build
   [delete] Deleting: /home/userone/EJB3_LocalLookup_Demo/tmp/TestLocalEJBEAR.ear

build_war:
   [delete] Deleting directory /home/userone/EJB3_LocalLookup_Demo/tmp
    [mkdir] Created dir: /home/userone/EJB3_LocalLookup_Demo/tmp/WEB-INF/classes
    [javac] Compiling 2 source files to /home/userone/EJB3_LocalLookup_Demo/tmp/WEB-INF/classes
      [jar] Building jar: /home/userone/EJB3_LocalLookup_Demo/build/TestWebApp.war

deploy:
     [echo] *******************  Deploying the EAR file TestLocalEJBEAR.ear *********************
     [echo] ********** build/TestLocalEJBEAR.ear to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************
     [echo] *******************  Deploying the WAR file TestWebApp.war *********************
     [echo] ********** build/TestWebApp.war to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

all:

BUILD SUCCESSFUL
Total time: 2 seconds

Step9). Now you will see the following kind of output on your JBoss AS7.1 console which means the applications EAR and the WAR are deployed successfully :

15:39:18,399 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) Starting deployment of "TestLocalEJBEAR.ear"
15:39:18,407 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) Starting deployment of "localEJB.jar"
15:39:18,438 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named CallerName in deployment unit subdeployment "localEJB.jar" of deployment "TestLocalEJBEAR.ear" are as follows:

	java:global/TestLocalEJBEAR/localEJB/CallerName!caller.CallerLocal
	java:app/localEJB/CallerName!caller.CallerLocal
	java:module/CallerName!caller.CallerLocal
	java:global/TestLocalEJBEAR/localEJB/CallerName
	java:app/localEJB/CallerName
	java:module/CallerName

15:39:18,468 INFO  [org.jboss.web] (MSC service thread 1-3) registering web context: /TestWebApp
15:39:18,483 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 2) Replaced deployment "TestLocalEJBEAR.ear" with deployment "TestLocalEJBEAR.ear"
15:39:18,483 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 2) Replaced deployment "TestWebApp.war" with deployment "TestWebApp.war"

Step10). Now access the WebApplication like following : http://localhost:8080//TestWebApp/TestServlet Now you will be able to access the TestServlet which is internally invoking a Business Method of a Local Stateless Bean deployed as part of a Separate EAR file.

NOTE: JBoss AS7 is a Community release and we always recommend you to use the RedHat Supported JBoss Enterprise Application Platform, There are various reasons behind this. Please refer to the Video: http://www.youtube.com/watch?v=iNFV0r9v14g&feature=player_detailpage

.
.
Thanks
Middleware Magic Team


JBoss AS7 with Async Servlet And Async EJB3

Hi,

As JBoss AS7 is very new And most powerful application server with many changes in it. Here we are going to see a very simple demo of how we can develop, build, deploy and test a simple Asynchronous Servlet and Asynchronous EJB3 inside a WAR file. (Which is the New Feature of Servlet Specification 3.0). One of the major changes in the Servlet Specification 3.0 is the support for Asynchronous Servlets: http://jcp.org/en/jsr/detail?id=315 …

This feature is very much desired when we invoke a long running process (like an EJB) from our Servlet, we want that the servlet should start the EJB execution in a separate process and should get back to the client as soon as possible.

In this example we will mainly focus on following points

Point-1). Here we are using JBoss AS7 latest build “jboss-as-7.1.0.Alpha2-SNAPSHOT”

Point-2). How to use and develop Asynchronous Servlets.

Point-3). How to use and develop Asynchronous EJBs with the help of javax.ejb.Asynchronous annotation.

Point-4). Also we will see how to place an Stateless Session Bean inside a WAR file.

Point-5). How to invoke an EJB3 from a Servlet which are present inside the same application. Using javax.ejb.EJB anotations lookup attribute.

Point-6). How to develop a Web Application without writing “web.xml”, rather using the Annotations to provide the servlet mapping and declaration.

Step1). Create a directory somewhere in your filesystem like “/home/userone/EE6_Async_Servlet_Demo” where we will place our application build related stuff. Then create another directory “src” inside “/home/userone/EE6_Async_Servlet_Demo” where we will be placing our source codes and JSPs.

Step2). Create Servlet class “TestAsyncServlet.java” as following inside the “/home/userone/EE6_Async_Servlet_Demo/src” directory.

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

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.servlet.AsyncContext;
import javax.servlet.annotation.WebServlet;
import javax.ejb.EJB;

@WebServlet(value="/TestAsyncServletURL", asyncSupported=true)
public class TestAsyncServlet extends HttpServlet
  {
       @EJB (lookup="java:module/TestAsyncStatelessSessionBean!ejb3.TestAsyncStatelessSessionBean")
       private ejb3.TestAsyncStatelessSessionBean testAsyncStatelessSessionBean;

       public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
        {
            Logger logger = Logger.getLogger(TestAsyncServlet.class.getName());
            PrintWriter out=response.getWriter();

            logger.log(Level.INFO, "TestAsyncServlet inside service(req,res)");
            logger.log(Level.INFO, "TestAsyncServlet inside ThreadName : "+Thread.currentThread().getName());

            // Calling startAsync() method on servlet indicates that we are associating request in Async Mode
            AsyncContext asyncContext = request.startAsync();

            // Here the main execution of the following EJB method will run in a separate thread
            testAsyncStatelessSessionBean.executeLongTask(asyncContext);
            String data="";
            for(int i=0;i<10;i++)
             {
                String threadName=Thread.currentThread().getName();
                System.out.println("tTestAsyncServlet service() at "+new java.util.Date()+"t"+threadName);
                try{   Thread.sleep(500); } catch(Exception e){ e.printStackTrace(); }
             }
            out.println("ServletRequest is Processed ... !!!<font color=red>But EJB still might be processing</font>");
            out.close();
        }
  }

Step3). Now we will create a Simple Stateless EJB with a Long running Method so provide a class inside “/home/userone/EE6_Async_Servlet_Demo/src” directory with name “TestAsyncStatelessSessionBean.java” as following:

package ejb3;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import javax.servlet.AsyncContext;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

@Stateless
public class TestAsyncStatelessSessionBean
  {
     private Logger logger = Logger.getLogger(TestAsyncStatelessSessionBean.class.getName());

     @Asynchronous
     public void executeLongTask(AsyncContext asyncContext)
      {
           String data="";
           try {
                 for(int i=0;i<10;i++)
                  {
                     String threadName=Thread.currentThread().getName();
                     logger.log(Level.INFO,i+"t EJB3 executeLongTask(asyncContext) at "+new java.util.Date()+"t"+threadName);
                     Thread.sleep(2000);
                     data=data+"n"+i+"t EJB3 executeLongTask(asyncContext) at "+new java.util.Date()+"t"+threadName;
                  }
           System.out.println("[EJB Processing is done] : "+data);
           asyncContext.complete();

       } catch (Exception e) {
           logger.log(Level.SEVERE, e.getMessage(), e);
       }
      }
  }

Step4). Now we will write a simple “index.jsp” page just to point to the Servlet, Place this file as wll inside the “/home/userone/EE6_Async_Servlet_Demo/src” directory as following:

<html>
   <body>
     <center>
        <h1> Welcome Page </h1>
        <h3><font color=maroon><a href="TestAsyncServletURL">Click Here to Access TestAsyncServlet</a></font></h3>
     </center>
  </body>
</html>

Step5). Now the most important part, here we are going to develop “build.xml” ANT file, which will build, deployour webapplication on the JBoss AS7.1 Server, so write the following “build.xml” file inside “/home/userone/EE6_Async_Servlet_Demo” directory.

<project name="SingletonStartupService" default="deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="output.dir" value="build" />
<property name="src.dir" value="src" />
<property name="war.name" value="EE6Feature_AsyncServletAndEJB.war" />

   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>
   </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>

        <target name="build" depends="init">
           <mkdir dir="${tmp.dir}/WEB-INF/classes"/>
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath" />

          <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/>
          <copy file="${src.dir}/TestAsyncServlet.java" tofile="${tmp.dir}/WEB-INF/classes"/>
          <copy file="${src.dir}/TestAsyncStatelessSessionBean.java" tofile="${tmp.dir}/WEB-INF/classes"/>

           <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
           <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/>
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}"/>
           </delete>
        </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/>
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />
        </target>
</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script, to point to your own JBoss AS7 directory.

Step6). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step7). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/EE6_Async_Servlet_Demo” and then run the ant to build the webservice. by running the command “ant build”

[userone@localhost EE6_Async_Servlet_Demo]$ ant deploy
Buildfile: build.xml

init:
   [delete] Deleting directory /home/userone/EE6_Async_Servlet_Demo/build
    [mkdir] Created dir: /home/userone/EE6_Async_Servlet_Demo/build
    [mkdir] Created dir: /home/userone/EE6_Async_Servlet_Demo/tmp

build:
    [mkdir] Created dir: /home/userone/EE6_Async_Servlet_Demo/tmp/WEB-INF/classes
    [javac] Compiling 2 source files to /home/userone/EE6_Async_Servlet_Demo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/EE6_Async_Servlet_Demo/tmp
      [jar] Building jar: /home/userone/EE6_Async_Servlet_Demo/tmp/EE6Feature_AsyncServletAndEJB.war
     [copy] Copying 1 file to /home/userone/EE6_Async_Servlet_Demo/build

deploy:
     [echo] *******************  Deploying the WAR file EE6Feature_AsyncServletAndEJB.war *********************
     [echo] ********** build/EE6Feature_AsyncServletAndEJB.war to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Alpha2-SNAPSHOT/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

BUILD SUCCESSFUL

Step8). Now you will see the following kind of output on your JBoss AS7.1 console which means the application is deployed successfully:

12:46:26,905 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) Starting deployment of "EE6Feature_AsyncServletAndEJB.war"
12:46:26,928 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named TestAsyncStatelessSessionBean in deployment unit deployment "EE6Feature_AsyncServletAndEJB.war" are as follows:

	java:global/EE6Feature_AsyncServletAndEJB/TestAsyncStatelessSessionBean!ejb3.TestAsyncStatelessSessionBean
	java:app/EE6Feature_AsyncServletAndEJB/TestAsyncStatelessSessionBean!ejb3.TestAsyncStatelessSessionBean
	java:module/TestAsyncStatelessSessionBean!ejb3.TestAsyncStatelessSessionBean
	java:global/EE6Feature_AsyncServletAndEJB/TestAsyncStatelessSessionBean
	java:app/EE6Feature_AsyncServletAndEJB/TestAsyncStatelessSessionBean
	java:module/TestAsyncStatelessSessionBean

12:46:26,966 INFO  [org.jboss.web] (MSC service thread 1-2) registering web context: /EE6Feature_AsyncServletAndEJB
12:46:26,974 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 1) Replaced deployment "EE6Feature_AsyncServletAndEJB.war" with deployment "EE6Feature_AsyncServletAndEJB.war"

Step9). Now access the WebApplication like following : http://localhost:8080/EE6Feature_AsyncServletAndEJB

As soon as you will access the Servlet “http://localhost:8080/EE6Feature_AsyncServletAndEJB/TestAsyncServletURL” you will see the following kind of output …which indicates that the Servlet is being executed by Thread “http-localhost-127.0.0.1-8080-3” whereas the EJB invocation which is done through the Servlet is being executed by a Separate Thread “pool-8-thread-10”

12:48:13,063 INFO  [servlets.TestAsyncServlet] (http-localhost-127.0.0.1-8080-3) TestAsyncServlet inside service(req,res)
12:48:13,064 INFO  [servlets.TestAsyncServlet] (http-localhost-127.0.0.1-8080-3) TestAsyncServlet inside ThreadName : http-localhost-127.0.0.1-8080-3
12:48:13,065 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:13 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:13,065 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 0	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:13 IST 2011	pool-8-thread-10
12:48:13,566 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:13 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:14,067 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:14 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:14,567 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:14 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:15,066 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 1	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:15 IST 2011	pool-8-thread-10
12:48:15,068 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:15 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:15,608 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:15 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:16,108 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:16 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:16,609 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:16 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:17,067 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 2	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:17 IST 2011	pool-8-thread-10
12:48:17,110 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:17 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:17,610 INFO  [stdout] (http-localhost-127.0.0.1-8080-3) 	TestAsyncServlet service() at Sun Nov 20 12:48:17 IST 2011	http-localhost-127.0.0.1-8080-3
12:48:19,068 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 3	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:19 IST 2011	pool-8-thread-10
12:48:21,068 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 4	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:21 IST 2011	pool-8-thread-10
12:48:23,069 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 5	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:23 IST 2011	pool-8-thread-10
12:48:25,070 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 6	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:25 IST 2011	pool-8-thread-10
12:48:27,071 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 7	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:27 IST 2011	pool-8-thread-10
12:48:29,072 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 8	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:29 IST 2011	pool-8-thread-10
12:48:31,073 INFO  [ejb3.TestAsyncStatelessSessionBean] (pool-8-thread-10) 9	 EJB3 executeLongTask(asyncContext) at Sun Nov 20 12:48:31 IST 2011	pool-8-thread-10

NOTE:  JBoss AS7 is a Community release  and we always recommend you to use the RedHat Supported JBoss Enterprise Application Platform, There are various reasons behind this. Please refer to the Video:  http://www.youtube.com/watch?v=iNFV0r9v14g&feature=player_detailpage

.
Thanks
Middleware Magic Team


Copyright © 2010-2012 Middleware Magic. All rights reserved. |