Tag: Servlet3.0

Application level log4j.xml and logging in JBoss AS7

Hi,

Log4j or any logging framework is very useful entity of any enterprise application, So that we can have a separate Application level logging using our own version of log4j.jar or any other logger framework version.

In this demonstration we will see how to use the log4j logging inside our Web Application, with it’s own version of “log4j.xml” file. We will also talk about the following points:

In this example we will mainly focus on following points

Point-1). How to use the “log4j.xml” which is placed inside “${YOUR_WAR}/WEB-INF/classes” directory.

Point-2). How to avoid using the JBoss provided logging framework or How to exclude the “org.apache.log4j” module provided by JBoss with the help of “${YOUR_WAR}/META-INF/jboss-deployment-structure.xml” file.

Point-3). Where to place your own version of “log4j.jar” file inside your WAR file. “${YOUR_WAR}/WEB-INF/lib”

Point-4). The Source code of this Demo can be downloaded from the following link (Git Repository):
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/ApplicationLevelLog4jDemo

Another Demo (uploaded on 26 Nov 2012) at EAR level.
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/EAR_Level_Log4jDemo

Developing WAR with it’s own logging

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

Step-2). Create a directory with the name “src” somewhere in your file system like “/home/userone/ApplicationLevelLog4jDemo/”. Inside the “src” directory we are going to place our all source code and xml files for development.

Step-3). Write a simple “index.jsp” file inside “/home/userone/ApplicationLevelLog4jDemo/src” as following:

<html>
<head>
<title>Application Level Log4j Demo In JBoss AS7</title>
</head>
<body>

      <form action="TestServlet" method="Get">
           Choose Log Level : 
                           <select name="logLevel">
                              <option>TRACE</option>
                              <option>DEBUG</option>
                              <option>WARN</option>
                              <option selected="true">INFO</option>
                           </select>
                           <BR>
           Enter Mesage to be logged: <input type="textarea" name="logMessage"/> <BR>
           <input type="submit" name="submit" value="log the message"/> 
      </form>
      
</body>
</html>

Step-4). Now we will write a simple Servlet based on Servlet3.0 specification with name “TestServlet.java” inside “/home/userone/ApplicationLevelLog4jDemo/src” as following

package servlets;
import java.io.IOException;
import java.io.PrintWriter;

//servlet-api
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//log4j
import org.apache.log4j.Logger;

@WebServlet(value="/TestServlet")
public class TestServlet extends HttpServlet 
  {
	private static final long serialVersionUID = 1L;
        private static Logger logger = null;

        public void init() throws ServletException {
         logger= Logger.getLogger(TestServlet.class);   
        }

	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			PrintWriter out=response.getWriter();
                        String logLevel=request.getParameter("logLevel");
                        String logMessage=request.getParameter("logMessage");
                        out.println("<html><head><title>Log4j Logging Demo</title></head><body>");
                        if(logLevel.equals("TRACE"))
                           {
                             out.println("["+logLevel+"] "+logMessage+" (logged inside log file).");
                             logger.trace(logMessage);
                           }
                        if(logLevel.equals("DEBUG"))
                           {
                             out.println("["+logLevel+"] "+logMessage+" (logged inside log file).");
                             logger.debug(logMessage);
                           }
                        if(logLevel.equals("INFO"))
                           {
                             out.println("["+logLevel+"] "+logMessage+" (logged inside log file).");
                             logger.info(logMessage);
                           }
                        if(logLevel.equals("WARN"))
                           {
                             out.println("["+logLevel+"] "+logMessage+" (logged inside log file).");
                             logger.warn(logMessage);
                           }

                        out.println("<BR><BR><a href="index.jsp"> Want a different logging level? </a></body></html>");
		     } 
                 catch (Exception e) 
                     {
			e.printStackTrace();
		     }
	}
}

Step-5). The most important part, We will need to write the following kind of “log4j.xml” file inside “/home/userone/ApplicationLevelLog4jDemo/src” as following :

NOTE: We need to just make sure that once the application is build this file should be present inside the ${WAR_NAME}/WEB-INF/classes directory.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
  <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
     <appender name="AppLogAppender" class="org.apache.log4j.DailyRollingFileAppender">
         <param name="DatePattern" value="'.'yyyy-MM-dd"/>
	 <param name="File" value="${jboss.server.log.dir}/MyAppLogsFile.log" />
	 <param name="Append" value="false"/>
         <layout class="org.apache.log4j.PatternLayout">
	     <param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
	 </layout>
     </appender>

     <!-- The "category" represents the package names of your Application APIs which we want to log -->
     <category name="servlets">
         <priority value="TRACE"/>
     </category>

     <root>
         <priority value ="TRACE"/>
         <appender-ref ref="AppLogAppender"/>
     </root>
 </log4j:configuration>

Step-6). Download and place the desired version of log4j jar (like “log4j-1.2.16.jar”) inside the “/home/userone/ApplicationLevelLog4jDemo/src”. So that after building the application this jar will be available inside the “${WAR_NAME}/WEB-INF/lib” directory.

Step-7). Now the most important part, In order to avoid using JBoss provided logging APIs, we need to place the following kind of “jboss-deployment-structure.xml” file inside “/home/userone/ApplicationLevelLog4jDemo/src” so that we can exclude the jboss logging APIs for our application and our application can use it’s own version of logging APIs.

NOTE: after building the WAR file make sure that the “jboss-deployment-structure.xml” is present inside the “META-INF” directory of your WAR file. Example: ${WAR_NAME}/META-INF/jboss-deployment-structure.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <deployment>
    <exclusions>
        <module name="org.apache.log4j" />
    </exclusions>
  </deployment>
</jboss-deployment-structure>

NOTE: If you are using JBossAS 7.1.2 then In order to avoid this ClassCastException you will need to include the following System property in your JBoss -Dorg.jboss.as.logging.per-deployment=false
If you are using JBoss AS7.1.2 and not using the above mentioned “jboss-deployment-structure” file then you will see the following kind of exception at the time of deployment of your WAR:

18:05:41,507 ERROR [stderr] (MSC service thread 1-3) log4j:ERROR Could not create an Appender. Reported error follows.
18:05:41,509 ERROR [stderr] (MSC service thread 1-3) java.lang.ClassCastException: org.apache.log4j.DailyRollingFileAppender cannot be cast to org.apache.log4j.Appender
18:05:41,509 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:248)
18:05:41,510 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176)
18:05:41,510 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191)
18:05:41,510 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:523)
18:05:41,510 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:492)
18:05:41,511 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:1001)
18:05:41,511 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:867)
18:05:41,511 ERROR [stderr] (MSC service thread 1-3) 	at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:794)
18:05:41,512 ERROR [stderr] (MSC service thread 1-3) 	at org.jboss.as.logging.LoggingConfigurationProcessor.deploy(LoggingConfigurationProcessor.java:111)
18:05:41,512 ERROR [stderr] (MSC service thread 1-3) 	at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:116)
18:05:41,513 ERROR [stderr] (MSC service thread 1-3) 	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
18:05:41,513 ERROR [stderr] (MSC service thread 1-3) 	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
18:05:41,513 ERROR [stderr] (MSC service thread 1-3) 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
18:05:41,514 ERROR [stderr] (MSC service thread 1-3) 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
18:05:41,514 ERROR [stderr] (MSC service thread 1-3) 	at java.lang.Thread.run(Thread.java:722)

Step-8). Now in order to build and deploy the above application we will write a very simple ant build script “build.xml” inside “/home/userone/jboss-as-7.1.0.Final/standalone/TESTING/ApplicationLevelLog4jDemo” as following:

<project name="Log4j_Basic_Demo" default="deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Final" />
<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="Log4jDemo.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}" />
           <mkdir dir="${tmp.dir}/WEB-INF/lib"/>
           <mkdir dir="${tmp.dir}/WEB-INF/classes"/>
           <mkdir dir="${tmp.dir}/WEB-INF/META-INF"/>
           <mkdir dir="${tmp.dir}/META-INF"/>
        </target>
 
        <target name="build" depends="init">
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath" />
           <copy todir="${tmp.dir}/WEB-INF/classes">
                <fileset dir="${src.dir}" includes="**/*.java"/>
           </copy>
           <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/>   

           <!-- Make sure to place the "log4j.xml" file inside ${WAR_NAME}/WEB-INF/classes  directory--> 
           <copy file="${src.dir}/log4j.xml" todir="${tmp.dir}/WEB-INF/classes"/>

           <!-- Make sure to place the "log4j-1.2.16.jar" file inside ${WAR_NAME}/WEB-INF/lib  directory--> 
           <copy file="${src.dir}/log4j-1.2.16.jar" todir="${tmp.dir}/WEB-INF/lib"/>

           <!-- Using this file we are going to satisfy the log4j dependency without directly placing the log4j.jar inside "WEB-INF/lib"-->
           <copy file="${src.dir}/jboss-deployment-structure.xml" todir="${tmp.dir}/META-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   *********************" />
        </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.

Step-9). 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%

Step-10). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/jboss-as-7.1.0.Final/standalone/TESTING/ApplicationLevelLog4jDemo” and then run the ant to build & deploy the webapplication. by running the command “ant deploy”

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

init:
   [delete] Deleting directory /home/userone/ApplicationLevelLog4jDemo/build
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/build
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/lib
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/META-INF
    [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/META-INF

build:
    [javac] Compiling 1 source file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/lib
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/META-INF
      [jar] Building jar: /home/userone/ApplicationLevelLog4jDemo/tmp/Log4jDemo.war
     [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/build

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

BUILD SUCCESSFUL
Total time: 2 seconds

Step-11). Now you will able to access your application. “http://localhost:8080/Log4jDemo/index.jsp” try to access the servlet and then check the “${jboss.server.log.dir}/MyAppLogsFile.log” file to see if the application level logging is happening properly.

.
.
Thanks
Middleware Magic Team


Simplified FileUpload using Servlet3.0 in JBoss AS7

Hi,

Uploading files through web applications is one of the most important job of most of the applications. Earlier to servlet3.0 specification we used to do it manually, But now from Servlet 3.0 specification a very useful feature of file upload is associated. Servlet3.0 specification introduced annotation @javax.servlet.annotation.MultipartConfig and the API javax.servlet.http.Part to simplify the file upload.

Here “javax.servlet.http.Part” represents a part or form item that was received within a multipart/form-data POST request. And the @MultipartConfig indicating that instances of the Servlet expect requests that conform to the multipart/form-data MIME type. Servlets annotated with MultipartConfig may retrieve the Part components of a given multipart/form-data request by calling getPart or getParts.

In this example we will see how to uload files using the @MultipartConfig annotation and how to use the javax.servlet.http.Part API.

Step1). Our application is going to upload the files inside the server location “${jboss.server.base.dir}/upload” directory so make sure that we create a directory with name “upload” inside “${jboss.server.base.dir}”, Which means the following path should exist: “/home/userone/jboss-as-7.1.0.CR1b/standalone/upload”

Step2). Create a Directory somewhere inside your file system where we can create our web application. Suppose i am creating a directory as “/home/userone/EE6_FileUpload_Servlet” and the create a subdirectory with name “src” inside “/home/userone/EE6_FileUpload_Servlet”

Step3). We will place a simple “index.jsp” file inside “/home/userone/EE6_FileUpload_Servlet/src” directory which will present a html form to the user so that user can browse & upload the desired file.

<html>
    <head>
        <title>FileUpload Demo</title>
    </head>
    <body bgcolor="maroon" text="white">
      <center>
        <h1>FileUpload Demo Using Servlet3.0 in JBoss AS7</h1>
        <form id="formId" action="FileUploadServlet" enctype="multipart/form-data" method="post">
          <input type="file" id="FileUploadId" name="***Upload***"  /> 
          <input type="submit" id="uploadButtonId" value="Upload Now" />
        </form>   
      </center>
    </body>
</html>

Step4). Now we will write the “FileUploadServlet.java” program inside the “/home/userone/EE6_FileUpload_Servlet/src” directory which will be responsible for uploading the file provided by end user on the JBoss Server box.

package servlets;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

//IOStream
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

//Servlet3.0 specific annotations 
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.Part;

@WebServlet(description = "FileUploadServlet Description", urlPatterns = { "/FileUploadServlet" })
@MultipartConfig(location="/home/userone/EE6_FileUpload_Servlet")

public class FileUploadServlet extends HttpServlet {
 
    private static final long serialVersionUID = 1L;
    public FileUploadServlet()
        {
          super();
          System.out.println("FileUploadServlet Initialized & Instantiated.");
        }
 
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
          PrintWriter out=response.getWriter();
          out.println("<html><head><body>");
          for (Part part : request.getParts()) 
              {
                  String fileName = "";
                  String partHeader = part.getHeader("content-disposition");
                  long partSize = part.getSize();
                  out.println("<BR>Part Name = "+part.getName());
                  out.println("<BR>Part Header = " + partHeader);
                  out.println("<BR>Part Size = " + partSize);
                  System.out.println("part.getHeader("content-disposition") = " + part.getHeader("content-disposition"));
               }
           out.println("<center><h1>File Upload Completed Successfully</h1></center></body></html>");


           //**** Custom Option ****//
           System.out.println("Custom Way To Upload File with Actual FileName.");
           fileUploadWithDesiredFilePathAndName(request);
           System.out.println("File Uploaded using custom Way.");
        }

    

     /* Following method allows us to place the uploaded file in a desired Location on the server along with the desired fileName */
     public void fileUploadWithDesiredFilePathAndName(HttpServletRequest request) throws IOException,ServletException
        {
          /******** Following part of code is not needed ********/
          InputStream inputStream = null;
          FileOutputStream outputStream =null;
          try
           {
             for (Part part : request.getParts()) 
               {
                  System.out.println(part.getName());
                  inputStream = request.getPart(part.getName()).getInputStream();
                  int i = inputStream.available();
                  byte[] b  = new byte[i];
                  inputStream.read(b);
                  System.out.println("Length : " + b.length);

                // Finding the fileName //
                  String fileName = "";
                  String partHeader = part.getHeader("content-disposition");
                  System.out.println("Part Header = " + partHeader);
                  System.out.println("part.getHeader("content-disposition") = " + part.getHeader("content-disposition"));

                  for (String temp : part.getHeader("content-disposition").split(";")) 
                     {
                       if (temp.trim().startsWith("filename")) 
                        {
                           fileName=temp.substring(temp.indexOf('=') + 1).trim().replace(""", "");
                        }
                     }

                  // Writing contents to desired FilePath & FileName //
                  String uploadDir=System.getProperty("jboss.server.base.dir")+"/upload";
                  System.out.println("File will be Uploaded at: " +uploadDir+"/"+fileName);                  
                  outputStream = new FileOutputStream(uploadDir +"/"+fileName);
                  outputStream.write(b);
                  inputStream.close();
               }
            }
          catch(Exception e)
            {
               System.out.println("Unable to Upload File: "+e);
               e.printStackTrace();
            }
          finally
            {
                if(inputStream!=null)
                   {   
                      try{ inputStream.close(); } catch(Exception e){ e.printStackTrace(); } 
                   }
                if(outputStream!=null)
                   {   
                      try{ outputStream.close(); } catch(Exception e){ e.printStackTrace(); } 
                   }
            }
        }
   }

NOTE:
The above servlet represents two ways to upload the file. One is purely using @MultipartConfig(location=”/home/userone/EE6_FileUpload_Servlet”) in this case the upload file location is specified but the uploaded file will have some random name, which is quite confusing some time.

So the above Servlet also has a separate method “fileUploadWithDesiredFilePathAndName(HttpServletRequest)” which extract the actual file name and places it in a desired location on the server box.

Step5). Now we will write a simple ant “build.xml” file in order to build and deploy our web application on JBoss AS7. So write the following “build.xml” file inside “/home/userone/EE6_FileUpload_Servlet” as following:

<project name="Servlet3FileUploadProject" 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.name" value="Servlet3FileUploadDemo.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"/>
           <copy file="${src.dir}/index.jsp" todir="${tmp.dir}"/>
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath"/> 

           <copy todir="${tmp.dir}/WEB-INF">
                <fileset dir="${src.dir}/">
                      <include name="web.xml"/> 
                </fileset>
           </copy>          
           <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
      
           <!-- Clean up -->
           <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 is to point to your own JBoss AS7 directory home 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/apache-ant-1.8.2/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/apache-ant-1.8.2/bin;%PATH%

Step7). Now run the ant file from the directory where you have placed the “build.xml” file as following:

[userone@localhost httpOnlyDemo]$ ant

Buildfile: build.xml

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

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

deploy:
     [echo] *******************  Deploying the WAR file Servlet3FileUploadDemo.war *********************
     [echo] ********** build/Servlet3FileUploadDemo.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   *********************

BUILD SUCCESSFUL
Total time: 3 seconds

Step8). Now access the application like following: “http://localhost:8080/Servlet3FileUploadDemo/index.jsp

NOTE: We will need to make sure that whatever upload directory we have choosen for this demo, Must already exist.
.
.
Thanks
MiddlewareMagic Team


Basic JPA2.0 Demo with Hibernate as persistence provider on JBoss AS7

Hi,

The Java Persistence Architecture API (JPA) is a Java specification for accessing, persisting, and managing data between Java objects / classes and a relational database. JPA was defined as part of the EJB 3.0 specification as a replacement for the EJB 2 CMP Entity Beans specification. JPA is now considered the standard industry approach for Object to Relational Mapping (ORM) in the Java Industry.

The JBoss Application Server JPA subsystem implements the JPA 2.0 container-managed requirements. JPA Applications use the Hibernate (core) 4.0 persistence provider, that is included with JBoss AS. Hibernate 4 is packaged with the AS and is the default persistence provider. The JPA 2.0 Specifications can be found in the following link: http://jcp.org/aboutJava/communityprocess/pfd/jsr317/index.html

A Best reference for JPA features inside JBoss AS7 can be foun in the following link: https://docs.jboss.org/author/display/AS7/JPA+Reference+Guide

However in this current emo we will just create a Simple JPA persistence unit and then we will try to insert some employee detils insie the DataBase. So basically this is just as a startup.

In this example we will mainly focus on following points

Point-1). For Web Applications we should put the “persistence.xml” file inside “${WEB_APPLICATION}/WEB-INF/classes/META-INF/persistence.xml”
For EJB Applications we should put the “persistence.xml” file inside “${EJB_JAR}/META-INF”

Point-2). To inject the EntityManager inside our Web Components we can use the annotation @javax.persistence.PersistenceContext(unitName=”name”)

Point-3). We can use the @javax.ejb.EJB annotation to inject an Enterprise Java Bean inside our app components. Like @EJB(lookup=”jndiName”)

Server Side Configuration

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

Point-2). In order to get more details on how to create MySQL DataSource in JBoss AS7 you can refer to the following article: http://middlewaremagic.com/jboss/?p=872
Create a DataSource inside “${JBOSS_HOME}/standalone/configuration/standalone-full.xml” file as following:

        <subsystem xmlns="urn:jboss:domain:datasources:1.0">
            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="H2DS" enabled="true">
                    <connection-url>
                        jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
                    </connection-url>
                    <driver>
                        h2
                    </driver>
                    <security>
                        <security-domain>
                            encrypted-ds
                        </security-domain>
                    </security>
                </datasource>


                <!-- Below is the DataSource Configuration which we added for our JPA TestCase-->
                <datasource jndi-name="java:/MySqlDS" pool-name="MySqlDS_Pool" enabled="true" jta="false" use-ccm="false">
                    <connection-url>
                        jdbc:mysql://localhost:3306/testDB
                    </connection-url>
                    <driver-class>
                        com.mysql.jdbc.Driver
                    </driver-class>
                    <driver>
                        mysql-connector-java-5.1.13-bin.jar
                    </driver>
                    <security>
                        <user-name>someDBUserName</user-name>
                        <password>someDBPassword</password>
                    </security>
                </datasource>
                <!-- Above is the DataSource we created on MySQL Database -->


                <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>
                            org.h2.jdbcx.JdbcDataSource
                        </xa-datasource-class>
                    </driver>
                </drivers>
            </datasources>
        </subsystem>

Point-3). Restart your JBoss AS7 from inside “/home/userone/jboss-as-7.1.0.Beta1/bin” directory as following:

.
 ./standalone.sh -c standalone-full.xml
.

Developing JPA Test Case

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

Step2). Now first of all we will create an Entity “Employee.java” as following inside the “/home/userone/JPA_1_On_AS7/src” directory.

package jpa;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;

@Entity
@Table(name="Employee")
public class Employee implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	private BigDecimal empno;

	private String ename;

    public Employee() {
    	System.out.println("Employee Object Created.");
    }

	public BigDecimal getEmpno() {
		return this.empno;
	}

	public void setEmpno(BigDecimal empno) {
		this.empno = empno;
	}

	public String getEname() {
		return this.ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}
}

Step3). Now we will create a Simple Stateless SessionBean remote Interface “EmployeeServiceRemote.java” inside “/home/userone/JPA_1_On_AS7/src” directory as following:

package jpa;
import java.math.BigDecimal;
import java.util.Collection;
import javax.ejb.Remote;
@Remote

public interface EmployeeServiceRemote{
  public void doAction();
  public Employee createEmployee(BigDecimal id, String name);
  public void removeEmployee(BigDecimal id);
  public Employee findEmployee(BigDecimal id);
  public Collection<Employee> findAllEmployees() ;

}

Step4). Now we will Stateless Session Bean class “EmployeeService.java” by implementing the interface “EmployeeServiceRemote.java”. Place this file as well inside the “/home/userone/JPA_1_On_AS7/src” directory as following:

package jpa;
import java.math.BigDecimal;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class EmployeeService implements EmployeeServiceRemote {
  @PersistenceContext(unitName="EmployeeService")
  EntityManager em;

  public EmployeeService() {
     System.out.println("nt Employee Object Created.");
  }

  public Employee createEmployee(BigDecimal id, String name) {
    Employee emp = new Employee();
    emp.setEmpno(id);
    emp.setEname(name);
    em.persist(emp);
    emp = findEmployee(id);
    System.out.println("nt Inside createEmployee() findEmployee result: "+emp);
    em.flush();
    return emp;
  }

  public void removeEmployee(BigDecimal id) {
       System.out.println("nt Inside removeEmployee("+id+")");
       Employee emp = findEmployee(id);
       if (emp != null) {
          em.remove(emp);
       }
  }

  public Employee findEmployee(BigDecimal id) {
        System.out.println("nt Inside findEmployee("+id+")");
        return em.find(Employee.class, id);
  }

  @SuppressWarnings("unchecked")
  public Collection<Employee> findAllEmployees() {
        System.out.println("nt Inside findAllEmployees()");
        Query query = em.createQuery("SELECT e FROM Employee e");
        return (Collection<Employee>) query.getResultList();
  }

  public void doAction(){
  }
}

Step5). Now we will write the “persistence.xml” file inside the “/home/userone/JPA_1_On_AS7/src” directory as following:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
	<persistence-unit name="EmployeeService"> <!-- transaction-type="JTA" -->
		<jta-data-source>java:/MySqlDS</jta-data-source>
		<class>jpa.Employee</class>
		<properties>
			<property name="hibernate.hbm2ddl.auto" value="create-drop" />
                        <property name="hibernate.show_sql" value="true" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
		</properties>
	</persistence-unit>
</persistence>

NOTE: We need to make sure that this “persistence.xml” file goes inside the “${war.name}/WEB-INF/classes/META-INF” directory of our WAR file.
Due to the property “hibernate.hbm2ddl.auto” the Employee table will be automatically created in the database as soon as we deploy the application on JBoss and will be automatically droped as soon as we undeploy our application. Valid values for this property are “validate | update | create | create-drop”

Step6). Now we will write a simple “index.jsp” page to just provide a some input forms so that a user can enter the employee name and id details , Place this file as well inside the “/home/userone/JPA_1_On_AS7/src” directory as following:

<html>
  <head>
     <title>JPA Demo In JBoss AS7</title>
  </head>
  <body>
     <form action="TestServlet">
       Enter Employee ID : <input name="empId" type="text" value="" /> <BR/>
       Enter Employee Name : <input name="empName" type="text" value="" /> <BR/>
       <input type="submit" value="Store" />
     </form>
  </body>
</html>

Step7). We will write the “TestServlet.java” inside the “/home/userone/JPA_1_On_AS7/src” as following in order to insert the details entered by the user in previous index.jsp page.

package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jpa.Employee;

@WebServlet(value="/TestServlet")
public class TestServlet extends HttpServlet 
  {
	private static final long serialVersionUID = 1L;

        @PersistenceContext(unitName="EmployeeService")
	EntityManager em;
	  
        @EJB(lookup="java:global/JPA_BASIC_Demo/EmployeeService!jpa.EmployeeServiceRemote")
        jpa.EmployeeServiceRemote remote;

	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			System.out.println("inside TestServlet service()");
			System.out.println("Got Remote: "+remote);
			
			remote.createEmployee(new BigDecimal(request.getParameter("empId")),request.getParameter("empName"));
			PrintWriter out=response.getWriter();
                        out.println("<html><head><title>JPA Insert</title></head><body>");
			out.println("<BR>Employee Record Inserted in the Database.<BR>");
                        out.println("<TABLE border="10%">");
                        out.println("<TR><TD>EmpID</TD><TD>EmpName</TD></TR>");
			for(Employee tmp:remote.findAllEmployees())
			{
			   out.println("<TR><TD>"+tmp.getEmpno()+"</TD><TD>"+tmp.getEname()+"</TD></TR>");
			}
                        out.println("</TABLE>");
                        out.println("<BR><BR><a href="index.jsp"> Want to insert Some More Employee Records ?</a></body></html>");
		     } 
                 catch (Exception e) 
                     {
			e.printStackTrace();
		     }
	}
}

Step8). Now the most important part, here we are going to develop “build.xml” ANT file, which will build, deploy our web application on the JBoss AS7.1 Beta Server, so write the following “build.xml” file inside “/home/userone/JPA_1_On_AS7” directory.

<project name="JPA_BASIC_Demo" default="deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Beta1" />
<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="JPA_BASIC_Demo.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}" />
           <mkdir dir="${tmp.dir}/WEB-INF/classes/META-INF"/>
        </target>
 
        <target name="build" depends="init">
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath" />
           <copy todir="${tmp.dir}/WEB-INF/classes">
                <fileset dir="${src.dir}" includes="**/*.java"/>
           </copy>
           <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/>

           <!-- Make Sure that the persistence.xml file is placed inside "${war.name}/WEB-INF/classes/META-INF" directory -->
           <copy file="${src.dir}/persistence.xml" tofile="${tmp.dir}/WEB-INF/classes/META-INF/persistence.xml"/>

           <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.

Step9). 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%

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

Buildfile: /home/userone/JPA_1_On_AS7/build.xml

init:
   [delete] Deleting directory /home/userone/JPA_1_On_AS7/build
    [mkdir] Created dir: /home/userone/JPA_1_On_AS7/build
   [delete] Deleting directory /home/userone/JPA_1_On_AS7/tmp
    [mkdir] Created dir: /home/userone/JPA_1_On_AS7/tmp
    [mkdir] Created dir: /home/userone/JPA_1_On_AS7/tmp/WEB-INF/classes/META-INF

build:
    [javac] /home/userone/JPA_1_On_AS7/build.xml:25: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 4 source files to /home/userone/JPA_1_On_AS7/tmp/WEB-INF/classes
     [copy] Copying 4 files to /home/userone/JPA_1_On_AS7/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/JPA_1_On_AS7/tmp
     [copy] Copying 1 file to /home/userone/JPA_1_On_AS7/tmp/WEB-INF/classes/META-INF
      [jar] Building jar: /home/userone/JPA_1_On_AS7/tmp/JPA_BASIC_Demo.war
     [copy] Copying 1 file to /home/userone/JPA_1_On_AS7/build

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

BUILD SUCCESSFUL
Total time: 2 seconds

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

10:36:38,128 INFO  [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-1) HHH000227: Running hbm2ddl schema export
10:36:38,131 INFO  [stdout] (MSC service thread 1-1) Hibernate: drop table if exists Employee
10:36:38,207 INFO  [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-1) HHH000230: Schema export complete
10:36:38,213 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-6) Stopped deployment JPA_BASIC_Demo.war in 90ms
10:36:38,214 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) Starting deployment of "JPA_BASIC_Demo.war"
10:36:38,229 INFO  [org.jboss.jpa] (MSC service thread 1-8) JBAS011401: Read persistence.xml for EmployeeService
10:36:38,242 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named EmployeeService in deployment unit deployment "JPA_BASIC_Demo.war" are as follows:

	java:global/JPA_BASIC_Demo/EmployeeService!jpa.EmployeeServiceRemote
	java:app/JPA_BASIC_Demo/EmployeeService!jpa.EmployeeServiceRemote
	java:module/EmployeeService!jpa.EmployeeServiceRemote
	java:global/JPA_BASIC_Demo/EmployeeService
	java:app/JPA_BASIC_Demo/EmployeeService
	java:module/EmployeeService

10:36:38,264 INFO  [org.jboss.jpa] (MSC service thread 1-8) JBAS011402: Starting Persistence Unit Service 'JPA_BASIC_Demo.war#EmployeeService'
10:36:38,266 INFO  [org.hibernate.ejb.Ejb3Configuration] (MSC service thread 1-8) HHH000204: Processing PersistenceUnitInfo [
	name: EmployeeService
	...]
10:36:38,270 INFO  [org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator] (MSC service thread 1-8) HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
10:36:38,275 INFO  [org.hibernate.dialect.Dialect] (MSC service thread 1-8) HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
10:36:38,276 INFO  [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (MSC service thread 1-8) HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
10:36:38,276 INFO  [org.hibernate.engine.transaction.internal.TransactionFactoryInitiator] (MSC service thread 1-8) HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory
10:36:38,277 INFO  [org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory] (MSC service thread 1-8) HHH000397: Using ASTQueryTranslatorFactory
10:36:38,284 INFO  [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-8) HHH000227: Running hbm2ddl schema export
10:36:38,285 INFO  [stdout] (MSC service thread 1-8) Hibernate: drop table if exists Employee
10:36:38,287 INFO  [stdout] (MSC service thread 1-8) Hibernate: create table Employee (empno decimal(19,2) not null, ename varchar(255), primary key (empno))
10:36:38,438 INFO  [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-8) HHH000230: Schema export complete
10:36:38,455 INFO  [org.jboss.web] (MSC service thread 1-1) registering web context: /JPA_BASIC_Demo
10:36:38,470 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 1) Replaced deployment "JPA_BASIC_Demo.war" with deployment "JPA_BASIC_Demo.war"

Step12). Now access the WebApplication like following :
http://localhost:8080/JPA_BASIC_Demo/index.jsp

.
.
Thanks
Middleware Magic Team


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