Google

Sep 28, 2012

JSF Tutorial: Using JSF 2.0, eclipse, and maven

This tutorial is an extension to the previous simple web tutorial . In this tutorial, JSF is used to create a simple greeting web application to run on the Tomcat server. It also demonstrates how Maven brings in the relevant dependent JAR files.

Step 1: Firstly, you need to bring in the relevant dependency JSF jar files like jsf-api-2.1.3.jar, jsf-impl-2.1.3.jar, el-ri-1.0.jar, jsf-facelets-1.1.14.jar (brought it in transitively), jsp-api-2.1.jar, and so on. This where maven comes in handy and all you have to do is modify the pom.xml that you created in the previous simple web tutorial to have the relevant dependencies added as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.mytutorial</groupId>
 <artifactId>simpleWeb</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>simpleWeb Maven Webapp</name>
 <url>http://maven.apache.org</url>

 <dependencies>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-api</artifactId>
   <version>2.1.7</version>
  </dependency>
  <dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-impl</artifactId>
   <version>2.1.7</version>
  </dependency>

  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>

  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
  </dependency>

  <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.1</version>
  </dependency>
  <!-- Tomcat 6 need this -->
  <dependency>
   <groupId>com.sun.el</groupId>
   <artifactId>el-ri</artifactId>
   <version>1.0</version>
  </dependency>

 </dependencies>
 <build>
  <finalName>simpleWeb</finalName>
 </build>
</project>


Step 2: Once you have updated the pom.xml file, you can right-mouse-click on the simpleWeb project to bring up the context menu, and then select Maven --> Update Dependencies, which should now update your dependencies with additional jar files by downloading it from the external maven repository. You can view the files 2 ways.

Option 1: Change your perspective to Java perspective from the JEE perspective, by selecting Window --> Open Perspective --> Java from the top (or main) menu. Once you are in that perspective, you can view the dependency jar files as shown below.



Option 2: You can right-mouse-click on the simpleWeb  project to bring up the contextual menu, and then select Properties  and then Java Build Path on the modal pop up menu, and on the RHS dialogue you can see the maven dependency jar files as shown below.


Step 3: You need to create new folders (java and resources)  and a package (com.mytutorial) under simpleWeb/src/main folder. Right-mouse-click on "main" folder under which you want to create a new folder, and the select New --> Folder and name the folder as java in the Folder name input box. Do the same for the resources folder under the main folder if it does not already exist.

Step 4: Now, add these newly added folder(s) to your build path by right-mouse-clicking on simpleWeb folder and then selecting Build Path --> Use as Source Folder. You can view if it has been properly added by right-mouse-clicking on simpleWeb, and then selecting Properties and then Build Path  on the modal pop up menu


The src/main/java is for the java source files and the src/main/resources is for .properties files like messages.properties.

Step 5: You can now add the com.mytutorial package under both src/main/java and src/main/resources folders. Right-mouse-click on the relevant folders (src/main/java and src/main/resources) and then select New --> Package and then type "com.mytutorial" under the "Name" input box.


Step 6: Create the messages.properties file under sr/main/resources folder and package com.mytutorial by right-mouse-clicking on  mytutorial and then selecting New --> File and then typing in messages.properties in the "File name" input box. Enter the following file contents

inputname_header=JSF Tutorial
prompt=Tell me your name:
greeting_text=Welcome to JSF
button_text=Hello
sign=!




Note: it is a best practice to externalize the  messages, button labels, etc as shown above with messages.properties.

Step 7: Create a JSF managed bean under src/main/java folder and package com.mytutorial.  You do this by right-mouse.clicking on com.mytutorial and then selecting New --> Class. Enter "PersonBean" in the "Name" input box. Fill in the contents as shown below

package com.mytutorial;

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

@ManagedBean
@SessionScoped
public class PersonBean {
 
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}


Tip: type the  private String name; and then right-mouse-click on the "name" and then select Source --> Generate Getters and Setters, to generate the appropriate getter and setter methods by ticking the appropriate check boxes in the pop up modal panel.




Note: In JSF 1.x, you had to declare this beans in the faces-config.xml, but this is no longer required in JSF 2.0. Power of annotations to simplify things.

Step 8: Next step is to create the relevant xhtml pages. The greeting.xhtml will display a input box to capture a name from a user and a button "greeting", when clicked will forward a another page welcome.xhtml to greet the person with name.

So, greeting.xhtml --> welcome.xhtml

Create the pages by right clicking on webapp under src/main and create two new files by right-mouse-clicking and then selection New ---> File. Enter the "File name" as greeting.xhtml and the other one as welcome.xhtml.


Step 9: Fill in the file contents as shown below and then save the files.

greeting.xhtml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:h="http://java.sun.com/jsf/html">
      
    <f:loadBundle basename="com.mytutorial.messages" var="msg" />  
 
    <h:head>
        <title>JSF 2.0 Greeting</title>
    </h:head>
    <h:body>
     <h3>JSF 2.0 Hello World Example - greeting.xhtml</h3>
     <h:form>
        <h:inputText value="#{personBean.name}"></h:inputText>
        <h:commandButton value="greeting" action="welcome"></h:commandButton>
     </h:form>
    </h:body>
</html>


Normally you would need faces-config.xml to define your navigation rule and define the method in the backing managed bean. Since, this is a simple tutorial, the action="welcome" will navigate to welcome.xhtml page and since the PersonBean is defined in the session scope, it will be in scope for the welcome.xhtml to pull out the "personBean.name".

welcome.xhtml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"  
      xmlns:f="http://java.sun.com/jsf/core"   
      xmlns:h="http://java.sun.com/jsf/html">
   
 <f:loadBundle basename="com.mytutorial.messages" var="msg" />  
 
    <h:head>
     <title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body bgcolor="white">
     <h3>JSF 2.0 greeting - welcome.xhtml</h3>
     <h4><h:outputText value="#{msg.greeting_text}" />
      #{personBean.name}
  <h:outputText value="#{msg.sign}" /></h4>
    </h:body>
</html>




Step 10: This step is to wire up JSF via the web.xml file which is found under src/main/webapp/WEB-INF.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 id="WebApp_ID" version="2.5">
 
 <display-name>JSF Application</display-name>

 <!-- Change to "Production" when you are ready to deploy -->
 <context-param>
  <param-name>javax.faces.PROJECT_STAGE</param-name>
  <param-value>Development</param-value>
 </context-param>

 <!-- JSF mapping -->
 <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

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




STEP 11: You can now publish the simpleWeb application within eclipse and start the Tomcat server as you did in the previous simpleWeb tutorial without JSF.



STEP 12: You can now type the following URL to start the application in browser of your choice.


  • http://localhost:8080/simpleWeb/greeting.jsf
  • http://localhost:8080/simpleWeb/greeting.xhtml
  • http://localhost:8080/simpleWeb/greeting.faces
  • http://localhost:8080/simpleWeb/faces/greeting.xhtml



STEP 13: You will get the following browser screen. Type in your name, and click on the "greeting" button.



You will get the welcome.xhtml page as shown below. the URL will still stay the same as this is a  page "forward". If you want the URL to change, then you need to do a "sendredirect" by defining the navigation rule in the faces-config.xml.



So, you not only have learnt to create a simple JSF page, but also how to use eclipse IDE and Maven. See, now if you can build the war outside eclipse using the  "mvn eclipse install" and deploy it to the Tomcat outside eclipse. The built file will be stored in the "target" folder.

Labels:

Sep 25, 2012

Java tutorial: Create a simple Web app using JEE

Install Apache Tomcat application server

To run JEE based web apps, you need an  application server that contains a web container. There are a number of application servers like Apache Tomcat, JBoss, GlassFish, etc. This tutorial will use Apache Tomcat.

Step 1: Download and install Apache Tomcat from http://tomcat.apache.org/download-70.cgi. The installing is all about unzipping it to the right folder. If you are running on Windows 7, download the 64-bit windows zip.




Continue with creating a Web project.

Step 2: Generate a Web project structure using Maven as we did for simple Java project in the previous tutorial. Run the command under C:\Temp\Java\projects.

mvn archetype:generate -DgroupId=com.mytutorial -DartifactId=simpleWeb  -DarchetypeArtifactId=maven-archetype-webapp

This would have created  the simpleWeb and a number of other sub folders adhering to the maven convention.


As you can see, it had generated a webapp folder and the web.xml.

Step 3: Import this project into eclipse. This step is very similar to the simple Java tutorial.


Also, note that in the top right hand corner  the tab says that eclipse is in Java EE perspective.

Integrate Tomcat server into eclipse so that you can it within eclipse.

Step 4: From eclipse top menu select "Window --> Preferences"





Step 5: Select the path to previously installed Tomcat server.




Step 6: Add this new server to the panel marked "Server". This where the "Console" tab is also located. This will also allow you to deploy the "simpleWeb" project to the Tomcat  server.





Step 7: Deploy the simpleWeb project by selecting it from the left pane marked "Available" and adding to the right pane marked "Configured".



Step 8: Start the Tomcat server that was deployed with the simpleWeb within eclipse by right-mouse-clicking on the server and selecting "Start".




Step 9: The console tab will output the server logs.



Step 10: Once the server has started, you type the following URL in a browser of your choice. Now you have a very simple Web application running in Tomcat server.

http://localhost:8080/simpleWeb/index.jsp



Now, let's see how we can build the war  package and deploy it to Tomcat from outside eclipse.

Step 11: Firstly, use Maven to build the war package. These steps are very similar to simple Java tutorial, except for deploying the Web ARchive (i.e. the war file) to Tomcat, and starting Tomcat outside eclipse. If your Tomcat is already running within eclipse stop it by selecting the server and then right-mouse-clicking to bring up the context menu, and then selecting the "Stop" button. You can check the "console" tab to see if the server has stopped.


Step 12: Now, use the "mvn" command to build the war file after changing the directory to "simpleWeb"  in a command line.  You need to be in the "simpleWeb" folder because that is where the pom.xml file is.


c:\Temp\Java\projects\simpleWeb>mvn clean install

Step 13: You can see the generate war file deployed to your local maven repository.



Step 14: To deploy the simpleWeb-1.0-SNAPSHOT.war file to Tomcat, copy it to the Tomcat's "webapps" folder, and then you can start the server by double clicking on "startup.bat", which will deploy the application when the server starts up. It simply unzips the simpleWeb-1.0-SNAPSHOT.war file by creating a new folder "simpleWeb-1.0-SNAPSHOT", which will have all the required files.





Step 15: Once the server is started, you can access the application in browser of your choice with the following URL.

http://localhost:8080/simpleWeb-1.0-SNAPSHOT/index.jsp


As you can notice, "simpleWeb-1.0-SNAPSHOT" is the exploded folder under the "webapps" folder within Tomcat file structure.

You may also like

Labels: , ,

Sep 21, 2012

Java Tutorial: Setting up Java, Maven, and eclipse

This is mainly for the beginners of Java to get familiarized with Java, Maven, and eclipse. This will also be handy for starting on your self-taught Java projects.

Install and configure Java

Step 1:  Download and install Java 6 or later version if available by googling "Java downloads". Make sure that you download and install the right version for the operating system on which you will be running -- for example Windows (32 bit or 64 bit), Linux, Solaris, MAC, etc. You will need both the JDK and the JRE.




The javac is the compiler that converts a source file (e.g. HelloWorld.java) to a byte code file  (e.g. HelloWorld.class). The java is the run-time command to execute a program (i.e. java HelloWorld). The src.zip is where all the library files are located and rt.jar is where the run-time class files are located.

Step 2: Set the environment variables. In a command prompt, if you type "set" (in WIN 32)  and "env" (in Unix), it will show all the environment variables. You need to set the JAVA_HOME environment variable. In DOS it is %JAVA_HOME% and in a Unix system, it is $JAVA_HOME. You also need to add %JAVA_HOME%/bin to the "path" environment variable. you can verify if Java is set up correctly by typing the following command in a command prompt.



If the version is not displayed, then Java is not set up correctly.

Install and configure Maven

Maven is a build and deployment tool.

Step 1: Download and install Maven from http://maven.apache.org/download.html.

Step 2: Configure the environment variables "M2_HOME" and "path". Use M2_HOME instead of M3_HOME as eclipse might not work well with M3_HOME. For example

SET USERPROFILE=%TOOLS_HOME%home
SET JAVA_HOME=%TOOLS_HOME%java\jdk-1.6.0_25

SET M2_HOME=%TOOLS_HOME%maven\apache-maven-3.0.3

SET MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=256m -Duser.home=%USERPROFILE%

Once maven has been set up correctly, you should be able to verify it by


You can set up the repository location by opening the settings.xml file under conf folder inside your maven installation directory. Repository is where the dependency Java libraries will be stored.

<localRepository>c:\tools\home\.m2\repository</localRepository>

If your internet access requires proxy settings, you need have that added to your settings.xml file.

<proxy>

  <id>optional</id>

  <active>true</active>

  <protocol>http</protocol>

  <username>proxyuser</username>

  <password>proxypass</password>

  <host>webproxy</host>

  <port>8080</port>

  <nonProxyHosts>local.net,some.host.com</nonProxyHosts>

</proxy>


Install and configure eclipse. 

Step 1: Download and install eclipse latest version from http://www.eclipse.org/downloads/. It is an IDE (i.e. Integrated Development Environment). Get the EE (Enterprise Edition).



Step 2: It is a good practice to keep your eclipse work space separate from where your tutorials or projects are stored. This will not tie up your projects or tutorials with an IDE. What if you want to use your projects or tutorials with NetBeans? For example


Here is a simple step by step guide in setting up Maven and eclipse

Step 1: The settings.xml file under %M2_HOME%/conf is where you can set up your local repository location, central repository server from where you can download the relevant artifacts, proxy server settings to access internet, etc as shown below.

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

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  
  <localRepository>c:\temp\java\.m2\repository</localRepository>
  
  <proxies>    
    <proxy>
   <id>genproxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>username</username>
      <password>passwd</password>
      <host>proxy-server</host>
      <port>8080</port>
      <nonProxyHosts>localhost</nonProxyHosts>
    </proxy>
  
  </proxies>
  
 
</settings>


You can browse the repository by going to http://search.maven.org where you can search for artifacts and relevant version numbers. You can even manually download artifacts.

Need to add the following snippets to the root element of your settings.xml file to tell where to download the jar files from.
<profiles>
    <profile>
      <id>JDK</id>
      <activation>
        <property>
          <name>JDK</name>
        </property>
      </activation>
      <properties>
        <JDK_1_5>c:\tools\java\jdk-1.5.0_06</JDK_1_5>
        <JDK_1_6>c:\tools\java\jdk-1.6.0_11</JDK_1_6>
      </properties>

    </profile>
    
 <profile>
  <id>nexus</id>
  <activation>
   <activeByDefault>true</activeByDefault>
  </activation>
  <!--Enable snapshots for the built in central repo to direct -->
  <!--all requests to nexus via the mirror -->
  <repositories>
   <repository>
    <id>central</id>
    <url>http://search.maven.org/</url>
    <releases><enabled>true</enabled></releases>
    <snapshots><enabled>true</enabled></snapshots>
   </repository>
  </repositories>
  <pluginRepositories>
   <pluginRepository>
    <id>central</id>
    <url>http://search.maven.org/</url>
    <releases><enabled>true</enabled></releases>
    <snapshots><enabled>false</enabled></snapshots>
   </pluginRepository>
  </pluginRepositories>
 </profile>
</profiles>


Note: Drill down by groupid that specify in your pom.xml file under dependencies.
Step 2: Generate the pom structure with the following maven command.

C:\Temp\Java\projects>mvn archetype:generate -DgroupId=com.mytutorial -DartifactId=simple

Note: Make sure that you already don't have a folder "simple" under projects. Accept the default settings when prompted by pressing enter. Now, if you inspect the file structure, it will look like.


Carefully, inspect the folders and files that maven has created. The local repository will also have a number of jar files for project dependencies like junit.jar and maven plugin jars.



This maven project can be imported into eclipse.

Step 3: create an eclipse short cut as shown below to open eclipse with your workspace "my-tutorials"

C:\Tools\eclipse\eclipse-3.7-SR2-win32-x86_64\eclipse.exe -data  C:\Temp\Java\workspace\my-tutorials


Step 4: Close the welcome splash screen, and tell eclipse with the help of the m2e (i.e maven to eclipse) plugin where your maven settings.xml file is residing. This is done by selecting from the eclipse main menu Window --> Preferences --> Maven (note: you can also search at the top in the Preferences dialogue).  As you can see below, it will also display your repository location as highlighted in blue.



Now, you can refresh your projects or select the project "simple" and then right-mouse-click to bring up the contextual menu, and then select "Maven --> Update Dependencies" to see the packages your project depends on. In this example, it is junit-xxx.jar.




You can also check you build path by  right-mouse-clicking on the simple project and then selecting Build Path --> Configure Build Path

Step 5: Import the maven project you had just created. Select  File --> Import and then



Click Next,



Step 6: Now, you can see the "App.java" Java source file as shown below. This was created by Maven.



Also inspect the pom.xml file which is used for packaging up your artifacts. The junit.jar is required for writing unit tests. You can also notice AppTest.java under src/test/java 




Step 7: You can run the class by "right-clicking" on App.java to bring up the contextual menu and then selecting "Run As" and then "Java Application", which prints the output "Hello World" in the console tab window.


Step 8: You can now package it as a jar file by running the mvn command on a command prompt. The pom file says the packaging type is "jar". Currently the target folder is empty, and once you package it, it will have the packaged artifacts.

Firstly, locate the folder where the pom.xml file is and then execute the mvn command.


The command is "mvn clean package". if you refresh the "target" folder by selecting it and pressing F5 or by selecting it and then right-mouse-clicking and then selecting "Refresh" you will see the artifacts that are generated. If you don't want the junit tests to be run, you can add -Dmaven.test.skip to the above command.

If you want the package to be deployed to your maven repository which is located at "c:\temp\java\.m2\repository" you should run the command "mvn clean install".



Step 9: Finally, you can run the jar file from a command prompt.The classpath tells where to find the App.class file.




java -classpath C:\Temp\Java\.m2\repository\com\mytutorial\simple\1.0-SNAPSHOT\simple-1.0-SNAPSHOT.jar com.mytutorial.App 


That's it. You now have Java, Maven (build tool), and eclipse (IDE) working with each other. If you liked this give me your feedback and stay tuned for more tutorials.

Note: If you want to generate the eclipse related artifacts outside eclipse from a command-line, you can issue the following command mvn eclipse:clean eclipse:eclipse. Similar commands are available for other IDEs as well.

You may also like


Labels: , ,

Sep 19, 2012

Interview questions and answers on SDLC (Software Development Life Cycle)

I just had been to a job interview and I was grilled on this very topic. The interviewer was passionate about this topic. I will have more posts on SDLC by providing additional links here. If you are an experienced developer, these questions and answers should be pretty easy. If you are a novice, this will give you a high level overview. It is good to be familiarized than have no idea at all.

Q. What does SDLC stand for and what are the different phases?
A. SDLC stands for Software Development Life Cycle, which is a process of building an application through different phases.





Q. How will you go about choosing the right SDLC for your project?
A. 
  • Firstly choose a base methodology: from a number of SDLC methodoligies like Waterfall, RUP (Rational Unified Process), SCRUM, XP (eXtreme Programming), etc. If you already have a SDLC methodology in place, analyse the existing deficiencies. This can be done by interviewing users of the system.
  • Secondly, analyze what other best practices can be adopted from the other SDLC methodologies. For example, you can adopt best practices like daily stand-up meetings, iterative development, peer code reviews, and test driven development with waterfall as the base methodology. 

Here are a few factors that will help you decide what SDLC methodology is right for your project

1. Understanding how the business is structured. For example, are the business units siloed by products? the culture of the organization, etc.
2. Complexity of the project. What is the size of the project team? How many streams are there?, etc.
3. Nature of the project. New greenfield project versus enhancements and maintenance to existing systems.
4. Capabilities of your engineers, tools, and current processes in place.


Q. What are the benefits of peer code reviews?
A.

1. Pick up issues and bad practices in others' code.
2. Get more familiarized with others' code.
3. Learn from others' code.

Q. Why would you use continuous integration?
A. 

  • One of the key practices in agile processes is collective code ownership. The continuous integration supports continuous design and collective code ownership. The developers will be required to integrate others' changes more frequently.
  • The continuous integration build process is a mechanism to find and eliminate problems from code changes as early as possible. The continuous integration motivates developers to check in code as often as they can, and avoids any stale code. This will also result in reduced down time.
The best practice for continuous integration is to perform the integration of others' changes on a your local workstation before your code escapes into the build server. It’s okay to break the build once in a while, but it hast to be quickly fixed. The build should never spend the night in a broken state.

During integrating others' changes, you are also peer reviewing and familiarizing yourself with others' changes.

Q. What are the pros and cons of pair programming?
A. 

Pros:

1. Continual design and code review that leads to more effective solution and effecient defect removal rates.
2. Programmers can learn from each other.
3. Improves communication and can build better teams.
4. The programmers will be more disciplined and encourages the agile principle of collective code ownership.
5. Fewer interruptions as people who are working in pair are less likely to be interrupted than someone working alone.

Cons:

1. Pair programming can double code development expenses.
2. Hard to get all programmers to embrace it. It takes the programmers out of their comfort zone.

Q. What are functional requirements? What are Non-funcrional requirements?
A. Functional requirements  are captured in a document with use cases or via story boards which contain what a certain system has to do to achieve a number of user objectives.This task is carried out during the priliminary stage of SDLC. For example, allow investors to place buy and sell trades. Prior to placing trades, the user inputs need to be validated, etc. Use case diagrams are used to capture the user experience.

Non-functional requirements addresses aspects that a software will never function properly without them. Response times, security, reliability, accuracy, high availability, and cross browser compatibilty are examples of non functional requirements. The Non functional requirements decide how a software will be percieved by its users. Users wouldn't be happy using a system that is not highly availabled and riddled with security holes. 


Q. What are the different types of testing?
A. 
  • Unit testing where the developers test their code by writing unit tests. Code coverage tools are used to determine the extend to which the code is covered.
  • System integration tests are generally conducted by the developers to test integration of their code with external  CMS (Content Management) Systems like Vignette, CRM (i.e Customer Relationship Management) systems like Siebel or Salesforce, and any other third party system. During development, the external systems can be mocked, and during system integration testing, both happy path and unhappy paths like service failures, service timeouts, sticky versus non-sticky sessions, and service retry need to be tested.  
  • Cross browser compatibility testing.  The modern applications are very rich in client experience and use lots of client side scripting like JavaScript. So, it is imperative to perform browser compatibility testing to ensure that the code works with major browsers like internet explorer, Firefox, Google chrome, and safari. There are tools like BrowserShotsIE Tester (for various IE versions), Adobe Browser Lab, etc.
  • Performance Testing – uses automated tools that are designed to test and tweak system performance. For example, use JMeter to write performance testing scripts.
  • Load Testing – helps determine how well the product handles heavy demand for system resources. For example, how well a trading system handles panic sells during a financial meltdown. 
  • Security Testing –  to guard against accidental miss-use, hackers, or known computer malware attack. For example, using a tool like Skipfish from Google.
  • Alpha Testing – is conducted after the majority of the software functionality is complete but before end-users are going to be involved. 
  • Beta Testing – is conducted after project code is complete. 
  • Acceptance Testing – is carried out by the testers, business analysts, and users to ensure that the system meets the functional and non functional requirements. The software is packaged and released with release candidate version numbers like RC1, RC2, etc to the user acceptance testing environment.
  • Regression Testing – is conducted to check if bug fixes have been implemented successfully. Also checks for the presence of new bugs or flaws that could have been created from correcting the original errors and ensures no baseline functionality has been lost.

Other Relevant Links







Labels:

Sep 18, 2012

Understanding Hibernate proxy objects and avoiding potential pitfalls


Q. How does hibernate support lazy loading?
A. Hibernate uses a proxy object to support lazy loading. Basically as soon as you reference a child or lookup object via the accessor/getter methods, if the linked entity is not in the session cache (i.e. the first-level cache), then the proxy code will go off to the database and load the linked object. It uses javassist (or CGLIB ) to effectively and dynamically generate sub-classed implementations of your objects.

Let's look at an example. An employee hierarchy table can be represented in a database table as shown below

public class Employee {

   private Long id;
   private String name;
   private String title;
   private Employee superior;
   private Set<Employee> subordinates;

   //getters and setters are omitted

}


In the above example, if you use lazy loading then the "superior" and "subordinates" will be proxied (i.e. not the actual object, but the stub object that knows how to load the actual object) when the main "Employee" object is loaded. So, if you need to get the "subordinates" or "superior" object, you invoke the getter method on the employee like employee.getSuperior( ) and the actual object will be loaded.

Q. What are some of the pitfalls of using a proxy object?
A. The typical pitfall is in how you implement your equals( ) method that gets invoked when comparing objects.

Pitfall 1: As explained before, the proxy objects are dynamically created by sub-classing your object at runtime. The subclass will have all the methods of the parent, but the fields (e.g. name, etc) in the proxy object will remain null, and when any of the methods are accessed via getter/setter method, the proxy loads up the real object from the database.

A typical equals( ) method implementation will look like

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof Employee)) {         //Line X: compare object type
      return false;
    }
    return name.equals((Employee)obj).name);  //Line Y: compare names
  }
 
As discussed before, the supplied object is a proxy object and the supplied name will be null. This can be fixed by using the getter method in Line Y instead of using the field directly. Using the getter method will tell the proxy object to load the actual object as shown below.

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof Employee)) {
      return false;
    }
    return name.equals((Employee)obj).getName());  //Line Y: compare names
  }
 
Pitfall 2: We saw earlier that the the proxy objects are dynamically created by sub-classing your object. In a simple scenario where you only have the "Employee" object the typecasting in Line Y and "instanceof" operator in Line X will work. But, what will happen if you have a type hierarchy for The class Employee as shown below

   public class PermanentEmployee extends Employee {
       .......
   }
   
   public class CasualEmployee extends Employee {
       .......
   }
   

When you have a type hierarchy as shown above, the type casts and instanceof operators will not work with the proxy objects.

A proxy class is a subclass of a field type that is required. Hibernate creartes a dynamic subclass by looking at the type of field. This means that if the field type is not the actual implementation (e.g. CasualEmployee) type, but an interface or superclass (e.g. Employee), the type of the proxy will be different than the type of the actual object. So, as shown in the diagram below, If the field type is the superclass (e.g. Employee) of the actual implementation (i.e. CasualEmployee), the proxy type (i.e. proxy) and the implementation-type (e.g. CasualEmployee) will be siblings in the type hierarchy, both extending the superclass. This means the proxy object will not be an instance of the implementing type (i.e. CasualEmployee), and the application code depending on this check will fail.



To prevent this issue, you have two approaches.

Approach 1: Switch off proxying on the top level class by setting lazy=”false”, which will turn proxying off for the hierachy.

Approach 2: Use the "Gang of Four" (i.e. GoF) visitor design pattern that allows you to adapt a single object or manipulate a collection of polymorphic objects without all the messy typecasts and instanceof operations.


Pitfall 3: As per the above example, if you have an “Employee” class, that contains a “name” property, when you invoke do “employee.getName()”, the proxies will get the "name" from Hibernate caches (either 1st or 2nd levels) or the database when requested. But if this call happens in the presentation layer like in the Struts action class, you will get the org.hibernate.LazyInitializationException because the Hibernate Session is closed and this lazy attribute does not have the session attached, hence  can’t load their lazy references.

The solution is to de-proxy the employee class as shown below:

Step 1: Write a generic utility class to de-proxy a given object

public class HibernateUtil {

    public static <T> T unproxy(T entity) {
        if (entity == null) {
            return null;
        }
 
        if (entity instanceof HibernateProxy) {
            Hibernate.initialize(entity);
            entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
        }

        return entity;
    }
}


Step 2: Use the above utility class


public Employee getSuperior() {
    superior = HibernateUtils.unproxy(employee);
    return superior;
}


These types of issues are hard to debug, and being aware of these pitfalls can save you lots of time in debugging and fixing the issues.

Labels:

Sep 6, 2012

Java coding to compare and sort objects

--> It is very common in real life coding to compare objects and sort objects in a collection. For example, retrieve the data from a database, and display the data differently by sorting by different fields. The PDF or xls reports can be generated by sorting the data as per user input. Java provides a number of classes like Collections and interfaces like Comparable and Comparator to sort objects within a collection. Here are a few questions and answers in sorting objects in Java.

Q. Can you write a simple program that compares two objects to return if they are equal or not? This method will be handy in defining your own equals( ) method.
A. This is usefull in domain or value object class to compare different object fields in an equals method


public class DomainObject {
 
  //protected because only inheriting domain classes can use it
  protected boolean isPropertyEqual(Object compare1, Object compare2) {
     // go here if compare1 is null, i.e. test cases 1 & 3
        if (compare1 == null) {
             if (compare2 != null) {
                 return false;
              }
        //go here if compare1 is not null, i.e. test cases 2 & 5     
        } else if (!compare1.equals(compare2)) {
             return false;
        }
        
        return true;      //test cases 1 & 4
   }
  
  public static void main(String[] args) {
     DomainObject d =  new DomainObject();
     Print(d.isPropertyEqual(null, null));  //test case 1
     Print(d.isPropertyEqual("abc", null)); //test case 2
     Print(d.isPropertyEqual(null, "abc")); //test case 3
     Print(d.isPropertyEqual("abc", "abc"));//test case 4
     Print(d.isPropertyEqual("abc", "cba"));//test case 5
 }
  
  
 public static void Print(boolean bol){
     System.out.println(bol);
 }
}

Note: The above class must be abstract. It was not tagged abstract to demo via the main() method by creating a new DomainObject(). The above method can be used in an extending class like

public class Security extends DomainObject implements Serializable {
    
    private String id; 

    //skipping other methods like getter/setter, toString, etc
   
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Security)) {
            return false;
        }
  
  //calling super class handy method we just created
        return isPropertyEqual(this.id, ((Security) obj).getId());
    }
 
  public int hashCode() {
        return id.hashCode();
    }

}


Q. Can you write code to sort the following string values naturally (i.e. in alphabetical order)?

   JEE, Java, Servlets, JMS, JNDI, JDBC, JSP, and EJB.
 
A. Here is the sample code that makes use of the default compareTo( ) provided in the String class as it implements the Comparable interface and the Collections utility class that provides a sorting method, which internally uses the efficient "merge sort" algorithm.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Sort1 {

 public static void main(String[] args) {
  List<string> values = Arrays.asList("JEE", "Java", "Servlets", "JMS", "JNDI", "JDBC", "JSP", "EJB");
  Collections.sort(values); // uses the default compareTo(String anotherString)  in the String class 
  System.out.println(values);
 }
}



Output:

[EJB, JDBC, JEE, JMS, JNDI, JSP, Java, Servlets]

Q. Is there anything wrong with the above code?
A. Yes, 2 things -- firstly, the above sort is case sensitive, that is the uppercase takes priority over lowercase pushing 'Java' after 'JSP'. Secondly, if the collection had any null values, it will throw a NullpointerException.

These two issues can be rectified by providing a custom sorting implementation that ignores case and handles null values by pushing them to the end. The Collections class's sort method takes a Comparator implementation as a second argument. In the code below, the Comparator has been implemented as an anonymous inner class. The compare(...) method will be called a number of times by the Collections.sort(list, comparator).

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Sort2 {

 public static void main(String[] args) {
  List<String> values = Arrays.asList("JEE", "Java", null,  "Servlets", null, "JMS", "JNDI", "JDBC", "JSP", null,"EJB");
  
  //The comparator is defined as an anonymous inner class, but it can be
  //defined in its own class. Handles nulls and ignores case
  Collections.sort(values, new Comparator<String>() {

   @Override
   public int compare(String o1, String o2) {
    //push the null values to the end
    if(o1 == null){
     if(o2 == null) {
      return 0;
     }
     return 1;
    }
    else if(o2 == null){
     return -1;
    }
    return o1.compareToIgnoreCase(o2);
   }
  }); // anonymous inner class end
  
  System.out.println(values);
 }
}



Q. Now, what if you have your own custom class like a Dog, Cat, etc instead of a library class like String, Integer, etc?
A. Here is an example of a JavaTechnology custom object that implements a default sorting logic based on the rank (i.e popularity).

public class JavaTechnology implements Comparable<JavaTechnology>{
 
 private String name;
    private int rank;   // popularity lower value means more popular
 
    public JavaTechnology(String name, int rank){
        this.name = name;
        this.rank = rank;
    }

    //default implementation by rank alone
 @Override
 public int compareTo(JavaTechnology technology) {
  
  int rank1 = this.rank;
        int rank2 = technology.rank;
 
        if (rank1 > rank2){
            return +1;
        }else if (rank1 < rank2){
            return -1;
        }else{
            return 0;
        }
 }
 

    //required for printing, displaying, etc.
 @Override
 public String toString() {
  return "(" + name + " , " + rank + ")";
 }
}



Now, a simple test class
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Sort3Test {
 
 public static void main(String[] args) {
  
  JavaTechnology jt1 = new JavaTechnology("JEE", 1);
  JavaTechnology jt2 = new JavaTechnology("Java", 1);
  JavaTechnology jt3 = new JavaTechnology("Servlets", 2);
  JavaTechnology jt4 = new JavaTechnology("JSP", 2);
  JavaTechnology jt5 = new JavaTechnology("JNDI", 3);
  JavaTechnology jt6 = new JavaTechnology("EJB", 4);
  JavaTechnology jt7 = new JavaTechnology("JMS", 5);

  List<javatechnology> values = Arrays.asList(jt1, jt2, jt3, jt4, jt5, jt6, jt7);
  
  Collections.sort(values); // invokes the compareTo(...) method in JavaTechnology a number of times
  
  System.out.println(values);
  
 }
 
}



Output:

[(JEE , 1), (Java , 1), (Servlets , 2), (JSP , 2), (JNDI , 3), (EJB , 4), (JMS , 5)]


Q. What if you have a specific scenario where you want to first sort by rank and then alphabetically if the ranks are same?
A. Any number of Comparator classes can be created to sort them differently as shown below.

import java.util.Comparator;

public class JavaTechnologyComparator implements Comparator<JavaTechnology> {

 @Override
 public int compare(JavaTechnology t1, JavaTechnology t2) {

  //handle null values here
  Integer rank1 = t1.getRank();
  Integer rank2 = t2.getRank();
  
  int rankVal = rank1.compareTo(rank2);
  int nameVal = t1.getName().toLowerCase().compareTo(t2.getName().toLowerCase());
  
  //if same rank, then sort by name
  if(rankVal == 0){
   return nameVal;
  }
  
  //else sort by rank
  return rankVal ;
 }

}


Now, the Sort3Test class has been slightly modified to use a Comparator .

import java.util.Collections;
import java.util.List;

public class Sort3Test {
 
 public static void main(String[] args) {
  
  JavaTechnology jt1 = new JavaTechnology("JEE", 1);
  JavaTechnology jt2 = new JavaTechnology("Java", 1);
  JavaTechnology jt3 = new JavaTechnology("Servlets", 2);
  JavaTechnology jt4 = new JavaTechnology("JSP", 2);
  JavaTechnology jt5 = new JavaTechnology("JNDI", 3);
  JavaTechnology jt6 = new JavaTechnology("EJB", 4);
  JavaTechnology jt7 = new JavaTechnology("JMS", 5);

  List<JavaTechnology> values = Arrays.asList(jt1, jt2, jt3, jt4, jt5, jt6, jt7);
  
  Collections.sort(values, new JavaTechnologyComparator()); // invokes the compare(...) in JavaTechnologyComparator
                                                            // a number of times
  
  System.out.println(values);
  
 }
 
}


The output will be:

[(Java , 1), (JEE , 1), (JSP , 2), (Servlets , 2), (JNDI , 3), (EJB , 4), (JMS , 5)]
This should now enable you to sort any Java objects.

-->

Labels: ,