Monday, December 7, 2009

JAX-WS Web Services with JBoss (JBossWS)

Today, Web Services are an essential part of every developer’s toolkit not only because they have diverse and varied applications but because they are easy to create and consume and work like a charm. Whether it is about inter-communication between legacy applications and new ones or there might be a scenario in which two applications (programmed in different languages) need to interact, Web Services come to your rescue. In short, Web Services are everywhere and you cannot imagine your life without them, especially if you are a Web Developer.

So, without wasting any more time on Web Services as there are many good resources for introducing them (see resources below), lets see how to create the environment needed to develop these Web Services. (Sometimes, I feel that creating an environment for developing and deploying Java apps is more tedious process than actually coding for the application :-) )

What is JAX-WS ?

JAX-WS stands of Java API for XML – Web Services; it is the latest standard/specification created for development and maintenance of web services. It is a successor to JAX-RPC and you can read here about the differences between the two. JAX-WS bring along many improvements, but for one, it is too easy to create, deploy and consume than its earlier counterpart.

What is JBossWS ?

We will use JBoss Application Server to deploy our application and hence we will use their Web Service Stack. JBossWS (JBoss Web Services) is in short, an implementation of JAX-WS specification.

Software that we require:

  1. JDK 1.5 and above (We use JDK 1.6)
  2. JBoss Application Server (We will use JBoss5.1.0 with JDK 1.6)
  3. JBossWS Web Service Stack (We use JBossWS Native Stack)
  4. Ant (Java Build/Automation Tool)

So, lets set up the environment around us so that we can easily create new and happening web services.

Step 1

Download and Install JDK on your machine (if not already installed). Also set your environment variable JAVA_HOME to the installed JDK location. Also add it to PATH environment variable. To check if this step is done properly, check by typing on command line:
>>> java –version

It will show you something like this (your current java version) and because you set the PATH variable, you can do this from anywhere:

javaVersion 

Step 2

Download and install ANT (a Java based Build Tool). If you are new to ANT, check my earlier blog entry about ANT to gain more insight. Again, set ANT_HOME to installation path and also include ANT_HOME in PATH variable. To check, type on console:
>>> ant -version

It will show the current version of ANT installed, something like this

antVersion 

Step 3

Download JBoss 5.1.0 with JDK 1.6 from here and install it on your system. Now, set JBOSS_HOME = {Installation path}
check by starting and stopping server. Pretty simple so far.

Step 4 

Download JBossWS Web Service Stack. Note that JBoss application server alone is not enough to deploy your web-services so you need additional jars that help you create, deploy, maintain and consume your JBossWS Web Services.

Download the binary distribution of JBossWS-Native 3.2.1 GA from here. Now, lets see how to install this pack.
Installing jbossWS pack requires:

1. Copy ant.properties.example to ant.properties (Creating a backup)

2. Change following in ant.properties (this file is used by build.xml)

   a) Location of your JBoss
      jboss510.home=E:/JBoss/jboss-5.1.0.GA

(since we are using JBoss5.1.0 so replacing that constant with real value)

3. Now run the ant script from command line specifying the target according to the version of JBoss you are using.

   >> ant deploy-jbossXXX  (replace XXX with your version of jboss)
   >> ant deploy-jboss510

It will run the build.xml file and execute all the tasks mentioned in it in the specified manner. If at the end, it prints BUILD SUCCESSFUL, then it means that you have successfully installed the web service pack. :-)

To confirm that it has installed correctly, check the following url (assuming that JBoss works on 8080 for you): http://localhost:8080/jbossws/

jbossWS If you see a picture similar to what is embedded here, it means that JBossWS Web Service Pack is installed successfully on your system and you are ready to create more. This URL acts as a console to manage your currently deployed web services.

Note:

It is not necessary that you need JBoss to deploy JAX-WS Web Services. With the advent of JDK1.6, you can also use Tomcat server to host these web services as JDK1.6 is already shipped with JAX-WS jars, although the procedure to create and deploy such services will differ from that of JBossWS. 

In the next blog entry, I would give an example of creating a simple web service using JBossWS Web Services. The actual purpose of this blog entry is to prepare you for the big picture !!

Resources:

  1. Introduction to Web Services (Must read for any Beginner)
  2. Web Services Architecture
  3. JAX-WS Reference Implementation (a really detailed one !!)
  4. Comparison between JAX-WS and JAX-RPC
  5. Download JDK1.6
  6. Download ANT
  7. Download JBoss Application Server
  8. Download JBossWS-Native (Web Service Stack)

Sunday, November 15, 2009

Deploying Web-Apps on Tomcat

Today, we are going to see various methods that can be used to deploy a web-application using Tomcat. These techniques are pretty simple and are a must for every web developer. However, most of us are only aware of a few of these.

Lets say that on your machine, Tomcat is installed at E:/Tomcat/apache-tomcat-6.0.10/. Hereafter, we will refer this location as {TOMCAT_HOME}

Also suppose that your web application is named as TestWebApp and is located at E:/MyWorkSpace/Java/TestWebApp. Hereafter, we will refer to this location as {WEBAPP_HOME}, and the output folder is named as web.

The Three Methods to deploy any web application on Tomcat are discussed below:

First Method – Copy & Paste

The simplest and the most straight-forward method to deploy any web application on Tomcat is by copying the output folder or the WAR (Web Application Archive) file of your application to webapps folder of your Tomcat installation as shown below:

a) Copy the output folder

Simply copy the output folder of your web application to {TOMCAT_HOME}/webapps/ folder. Note that you must take care that your output folder must have a folder named WEB-INF, which further contains web.xml file. This file is also known as deployment descriptor as it governs how a web application should be deployed. Now restart tomcat to see the effect.

FYI, the Tomcat Home, or the Tomcat Home page you see when you type http://localhost:8080/ is also deployed this way and the output folder is named as ROOT.

b) Copy the WAR file

First, create a WAR file by going to {WEBAPP_HOME}/web and then type:

> jar –cvf * TestWebApp.war

This will create a WAR file for you, which you have to copy to {TOMCAT_HOME}/webapps/ folder. Now, restart tomcat to see the deployed application.

Second Method – Server.xml

Another way to deploy your Web application is to add a context entry in Tomcat’s server.xml file, which can be found at {TOMCAT_HOME}/conf/server.xml

Edit this file by adding the following entry:

<Context path=”/myApp” docBase=”E:/MyWorkSpace/Java/TestWebApp/web” debug=”true” reloadable=”false” />

where myApp is now the Context for you deployed application. To see the deployed application, simply restart tomcat and access the deployed application at http://localhost:8080/myApp/

To deploy more applications, simply add one Context entry per application. Note that the path attribute should be unique for all deployed applications at one time.

Third Method – Context in an external XML file

Create a XML file containing the Context Entry for your application

<Context path=”/myApp” docBase=”E:/MyWorkSpace/Java/TestWebApp/web” debug=”true” reloadable=”false” />

You can give any name to this XML file, but a common practice is to name it in such a way that helps you identify it with the application it deploys. We name is testWebApp.xml.

All that is left now, is to copy this testWebApp.xml file to {TOMCAT_HOME}/conf/Catalina/localhost/ folder.

Restart tomcat and voila, you are done. This way, we have one XML file per application, containing the context and location for that application.

Comparing Various Methods

The first method is pretty simple and straight-forward but it restricts you to copy the output folder to Tomcat Installation, something that you would not want to do every-time or you may not have enough access rights in some cases.

On the other hand, the second method is flexible in the sense that location of the output folder of your web application is independent of your Tomcat installation. The downside is that deploying and un-deploying applications again and again can be a head-ache as you have to edit the same server.xml file again and again.

The third method rules !! It not only is flexible as its second counter-part but also it deploys applications independent of each other in the sense that each application has its own context file (xml file). In case you want to deploy some applications, while restrict some other, you simply have to move/delete the context files (xml) for the applications you do not want to deploy.

Any Comments, Suggestions or Corrections are welcome

Thursday, September 24, 2009

Sorting Collections in Java

Now this is a pretty basic requirement that Java developers often face. You may want to sort an array of Strings or an List of Complex user defined object based on any field of that object. Java provides you with several options for this purpose that we are going to explore.

Sorting An Array of Pre-defined Data Types

To sort simple objects like String, Integer or primitive Data types, you can simply use build-in functions like:

  • Collections.sort( );
  • Arrays.sort( );

Sorting List of Objects – Comparable Vs Comparator

A more practical example would be to sort a User-defined Object on any field of that Object. Suppose we have a Person class that looks like the following:

Personjava

Now, we want to sort an ArrayList of Persons based on their name, we have 2 options:

Have Person Class Implement Comparable Interface

Have your person class implement the Comparable Interface, which makes you implement compareTo(..) method, which is actually used by build-in sorting methods to sort Persons. This method looks like following and compares two person objects, which determines which Person should come first in the sorted order.

PersonComparable

This method compareTo(..) is used to Compare two Person Objects based on their name. It returns an integer value: 0 if both of them are equal, positive value if the first object comes before the second one, and negative value if first object comes after the second one.

Now call sort() on it as follows,

sortingPersons

where persons is an ArrayList of Persons. As already said, the sort() method internally uses compareTo(..) method to sort these Person Objects

Create a Separate Class (Comparator Class) implementing Comparator Interface

A better way to sort these Persons is to create a separate comparator class as shown below.

comparatorPerson

Here we have created a static inner class which is used in sort() method as follows:

personComparator

Comparable Vs Comparator

I call it a better way as you can now sort your Person class on different fields: Suppose now you want to sort Persons based on their Age, then all you need to do is create a new Comparator class based on age and call sort method with this comparator.

Note:

The code shown above is compatible with Java 1.5 and above. The non-generic functions for Comparable and Comparators looks a bit different but inherently serve the same purpose.

Saturday, September 5, 2009

Hibernate Basic Tutorial

This blog post is meant for beginners who want to start with Hibernate and could not find an easy way to set up the basic project. Pre-requisites for understanding this are basic knowledge of Core Java and JDBC knowledge.

Introduction to Hibernate

Hibernate is basically an Object-Relational Mapping tool that is used to query against the database in an effective manner and can convert the results into (Java) objects pretty easily.

In simple terms, one can say that you can Map one database table to a Java class and objects of that class will correspond to rows in that database table. (Obviously, complex mappings also exists and we can specify all kind of relationships but to begin with, we will talk about the easy ones).

You can think of Hibernate as a Wrapper over JDBC. The reason I choose the word ‘Wrapper’ is to emphasize on the fact that Hibernate itself uses JDBC under the hood. So, its not really a radically different technology that we are going to learn.

Some Advantages of Hibernate

  1. Database Independence – The code that you write is not dependent on the underlying database. It is also known as transparent persistence as you can always change the underlying database without changing any of your Java code, the only change required is in a Hibernate configuration file. This also means independence from the queries that you will otherwise write specific to a database.
  2. Open Source – Hibernate is Free and Open Source and licensed under LGPL (Less GNU Public License)
  3. Performance – It claims to have improved performance when compared to JDBC API.
  4. Enhanced API - It also provides an enhanced Criteria API to query against the database in an effective fashion. Apart from Criteria API, one can also use Native SQL or HQL (Hibernate Query Language)

Lets Get Started

So lets start with setting up a basic Hibernate Project in Eclipse. Software and Other stuff that you require are

Open Eclipse IDE. Create a new Java Project. Name it as you like and press finish. Before we start coding, first let us add the required libraries:

Hibernate JARs (from Hibernate Core Framework). Consists of classes like Session, Transaction, Criteria etc. which are used to write Hibernate code.

  • hibernate3.jar
  • common-collections-3.1.jar
  • javassist-3.4.GA.jar
  • jta-1.1.jar
  • dom4j-1.6.1.jar
  • antlr-2.7.6.jar

Logging JARs (used to log the queries fired and for other purposes)

  • log4j-1.2.13.jar
  • slf4j-api-1.5.8.jar
  • slf4j-log4j12-1.5.8.jar

Data-Base specific Driver JAR (which contains the implementation of JDBC specification and is used to connect to underlying DB )

  • mysql-connector-java-5.1.7-bin.jar

After adding the required libraries, let us create a table in our database, which we will use in our example. Following syntax is used for MySQL to create a student table in ‘hibernate’ schema :

studentsql

As already discussed, Hibernate Provides us with the Capability of Mapping a Table in a Relational Database to a Java Class. So Any Operations that you perform the objects of that class are actually performed on the rows of that database table when you save these objects using Hibernate API.

So, lets create a Student Class in Eclipse (Student.java). This class will have (in this simple case) the instance variables with one-to-one correspondence with the columns of the Student Table that we created above. These classes generally follow JavaBeans Pattern by having Getters and Setters for every property and an empty constructor. So, this is how our Student.java looks like:

Studentpic

Mapping Java Class to Database Table

Now, we must provide the mapping so that Hibernate can actually map this java file against our table. This mapping is provided in a XML file, which we name as Student.hbm.xml. Although you can provide any name, but keeping the same name as that of the class helps in identification if required later on. The *.hbm.xml extension is mandatory for all mapping files. The Mapping File looks like:

Studenthbm

Let us spend a few minutes pondering over this mapping file. Although, most of it is pretty straight-forward. It says that we are mapping our class Student (Student.java) to table Student with primary key as id which maps to id column of table. The generator tag is used to generate primary keys. Different types of generator classes can be used for this purpose. Most commonly used are native (which means use database dependent scheme for generating primary keys), increment (which can be used to increment normal data types like Long, Integer etc.

Other tags in the file simply maps properties of Java Class to Database columns. You can also specify data types of these properties. Hibernate supports almost all data types that Java offers. This is perhaps the simplest Mapping file that you will see and use. More complex mappings are normally used but we stick to basics since there is much more to learn.

Hibernate Configuration

Are we missing something ? So far we have created a Database table, a Java file and a XML file that specifies the mapping used by Hibernate, but so far we have not told Hibernate anything about the location of database, the username-password to access it, the name of schema in which all these database objects lie. So to specify these, we use Hibernate Configuration File hibernate.cfg.xml which looks like the following:

hibernatecfgxml

There are many ways to provide this configuration to Hibernate. One of them is to use this file.

  • The property connection.url tells the location of the schema (named as hibernate) to which we connect using Hibernate. It contains all the database objects that we use in our Hibernate application.
  • The connection.username and connection.password properties specifies the username and password to connect to our schema.
  • This file also specifies all the hbm.xml mapping files that we created (only one in this case) as mapping resources. Yes, this is not a best practice and better techniques do exist.
  • The property hibernate.show_sql property is used to generate all SQL statements that Hibernate internally uses.
  • There are many other properties as well which we have skipped

Logging APIs

Hibernate uses log4j and slf4j for logging purposes. We use log4j.properties to specify logging properties.

log4properties

Finally, lets write some Code

I have always experienced that setting up environment for any web application is far more difficult than actually writing the code. ;) So, perhaps the difficult part of setting up the environment for our Hibernate Application ( a one-time activity ) is over, and we can write Hibernate code to insert and retrieve data.

Again, there are many best practices to code like using Connection Pooling for connections, Transaction Management in an effective manner. But for demo purposes, we have ignored all of it as the purpose here to get started with Hibernate.

Hibernate Session Factory

We create a Session Factory which is then used to get new Hibernate sessions, close sessions and retrieve existing sessions.

hibernatesessionfactory

Now we create a Test Java file (TestHibernate.java) that creates a new Student, retrieves all existing Students, delete a particular student.

Creating a New Student

createStudent

Retrieving all Students

getAllStudents

Delete A Student

deleteStudent

Project Structure

Now that we have created all the files that we need, we really missed the big part. How to organize them ?? So lets see how we should organize all these files we have created so far.

projectStructure

The TestHibernate.java class contains all the hibernate methods shown above plus a main method (for demo) to test these methods. When you run this Java file, check out the messages printed on the console.

I hope I have told all the implementation details in the best possible ways I can. I hope you will have a good time building applications with Hibernate. :-)

Notes

I faced a few problems in setting up project. Mostly were related to missing JARs or usage of old JARs, but few minutes of googling really helped. That’s why I have clearly stated the JARs that I used.

Connection Pooling with Hibernate is done using C3P0 connection pooling mechanism.

Last but not the least, this is just a small yet decent beginning in the huge world of Hibernate. In case you find any mistake, please leave it as a comment. Any suggestions and comments are welcome. :-)

Sunday, July 12, 2009

Singleton Class in Java

What is Singleton ?

Many times we face situations in which we need to model an entity which can have only one Live instance at a time. Speaking in technical terms, we need to create a class which can be instantiated only once i.e. only one object can be created of that class during the scope of the entire application. Examples can be an instance of a Printer which can be used by many clients to print any document. But since we have only printer, so we must not allow the user/client to create more than one instance of the Printer class. Rather all of them must use the same instance in an synchronized manner.

A more common example could be a handle to the Database Connection Pool. We must have only 1 instance of the Pool Manager, which in turn can allocate database connections from the common pool of connections and can put them back after they are used. Having more than 1 instance of the Pool Manager can result in problems, which can be really difficult to debug.

Lets see how to make a Java Class that can be used as a Singleton

Method 1

Inside your class, keep a count of how many instances have been created so far in a static variable. Now, you can throw an Exception in your constructor, the moment a client tries to create more than one instance. Example code given below:

pic2

Method 2

Make your class’ constructor Private and keep another private instance variable which can call the constructor. Create a public getter function for the retrieving the singleton object as shown below:

pic1

One problem with this approach is that one can use Reflection API to invoke the private constructor and thus the whole concept of Singleton class is violated as shown below:

pic3

This can be overcome by throwing an exception in the MySingleton constructor when it is called more than once (as we have done in first Method)

Another Caveat

Can you think of any more way the above code can be broken? By breaking, I mean can you create two instances of the above class.

Hint: Serialization !!

Answer: If your class implements Serializable interface or inherits some class which implements this interface, then this code can be broken by first serializing the object (saving the state of the object to some file) and then de-serializing it (retrieving back the original state). If we do not override readResolve() method as shown below:

pic4

To the best of my knowledge, now I think there is no way you can create another object with all these checks implemented. Please feel free to comment & discuss this and point out any problems with above mentioned techniques.

Saturday, June 6, 2009

uCertify PrepKit for SCJP 5.0

Recently, I got an exciting opportunity to review the uCertify Prepkit for SCJP 5.0 certification.

SCJP stands for Sun Certified Java Professional and is one of the many certifications offered by Sun Microsystems that makes you stand out in the crowd. In the times like these, who would not want that. :-)
If you want to know more about SCJP, you can look at the Sun's site here or you check this to see some related FAQ's.

Coming back to uCertify Preparation Kit, I actually found it pretty useful overall, for it gives you a broad spectrum of features for a relatively smaller price. The preparation engine provides you with
  • Study Notes & Helpful Articles
  • 7 Mock Tests, each with 75 questions
  • Study & Learn Module
  • Ability to Bookmark and Tag Questions
The Study & Learn Module provides a presentation (thus not really boring) based on each Examination Objective of SCJP 5.0. Going through them before the exam could be the fastest way to revise the entire syllabus. This is so because SCJP has well-defined objectives (rules & syntax of the language) that it tests. There is no need to go beyond these objectives if you want to clear the exam.

You can also attach your own notes with Study Notes and Articles, thus making a note of some exceptional condition or some related fact. These makes life really easy when you go through them again.

The practice exams give you a real feel of the actual certification exam as it contains both multiple choice questions (MCQ's) and few drag-and-drop questions. Also the level of the questions are neither too high nor too low. On a personal level, when I took the first practice exam without really preparing for it, I faltered on questions related to in-built classes like Locale, Date, NumberFormat and use of native modifier and Enumerations.

According to me, the best feature is certainly the way the answers are explained once your test is over and you see the results. You can review all the answers whether correct or not, and find out the reason for the same.
The answers are explained in length, touching the concept involved and focussing on why other options are wrong. This gives you a proper insight of what's going on.

On the downside, I would have preferred a highlighting feature that enables me to highlight important facts in the study notes and articles, so that next time I read only that part, which is important to me. Also, I would have loved had they allowed me to copy the code and paste it to test it but I understand that they probably can't do it for piracy issues and misuse.

Conclusion
Although it is an excellent kit to give you a proper feel of the actual exam; it is equipped with some easy ones and some tough(read tricky) questions as well just as the actual paper would. But, do not think that you need just this PrepKit to clear the paper!!
What you also need is a javac(Java compiler) to practice and code. I strongly recommend understanding the involved concepts and coding by hand (not by IDE), then take these useful tests to gain confidence as the actual exam looks almost the same.

For more information about the other preparation kits that uCertify provides you, please visit there site here.

Monday, June 1, 2009

ByteCode Back to Java Source Code !!

I have always thought about the title of this blog entry, ever since I started learning Java. But, until recently, I had no idea about the same. I didn't knew that something magical existed that would perform this conversion. But now since I know a bit, I thought I better share it.

Java Decompiler
As you would have guessed by now, a Java Decompiler is a computer program capable of reversing the work done by a Compiler. In essence, it can convert back the Bytecode (the .class file) into the source code (the .java file).
There are many decompilers that exist today, but we will talk about the most widely used JD - Java Decompiler, which is available both as a stand-alone GUI program and as an Eclipse-plugin.

To install and use these tools are a breeze and would not take you more than a few minutes to get accustomed to it. Hence, I would not repeat the process that's already mentioned on their site.

One thing that we must note here is that the process of conversion might NOT result into 100% exact code, i.e. the generated Java file might not match the actual Java code character by character. However, most of the code would be replicated but things like variable & function names or some other minor details may differ.

Lets have a look at the JD-GUI, stand-alone tool, written in C++;making it pretty fast to execute(decompile) and display the result. Also, it is independent of the the Java Runtime Environment and thus no setup is required to install it.

Lets test the tool now.

Example Java Code:
public class test{
public static void main(String[] args){
System.out.println("Hello world");
}
}


Compile it: javac test.java
so that we have ByteCode (test.class file) with us now.

Decompile it using any one of the following ways:
  1. Execute the following on the command line: jdi-gui.exe test.class
  2. Select 'Open File' from the menu, browse to get to the test.class file and open it
  3. Drag and Drop the test.class file into the JD-GUI tool
All of the above situations result in generating the following Java Code, have a look:

import java.io.PrintStream;

public class test
{
public static void main(String[] paramArrayOfString)
{
System.out.println("Hello world");
}
}

Well just by seeing JD perform really well on this simple example, we cannot decide how efficient is this tool. But, still it is a tool that every Java Developer must be aware of. Because, in case you have accidently deleted your Java files and are left with only the .class files, this is the tool that can save your neck. :-)

Sunday, May 31, 2009

Strings & Java

Perhaps one of the most frequently used Class in Java is the String class. The major reason for Strings to be really poweful is the flexibility of Strings to interact with other objects with so much ease.

Strings in Java posses many unique characteristics that differentiates it from the rest. For example, it is a well-known fact that Strings are Immutable. For those who do not know what that means is, 'String objects one created, can never be changed.' An example would make it more clear.

String s1 = "Hello World";
Here, s1 holds the reference to the String object on the heap containing the value "Hello World". Now, if we type

String s2 = s1.concat(", here I come");
Now, s2 holds another object on the heap with the value "Hello World, here I come". But this doesn't change the object s1. What it rather does, it creates a new object concatenating the new value to it and storing its reference in s2.

If we would have typed,

s1.concat(", here I come");
then also a new object with value "Hello World, here I come" is created but is lost and cannot be referenced since we have not stored it somewhere. Here also, s1 remains the same and is not changed. It cannot be changed.

It would also be good to remember that to make Java Memory Model more efficient,  Java Runtime allocates memory for Strings from "String constant pool" rather than allocating the memory from the heap. 
Now, when the compiler encounters any string literal, it first searches the String constant pool for an identical string. 
  • If a match is found, the reference to the already existing identical string is returned for the new request. 
  • If a match is not found, then a new string literal is created in the pool of strings. This approach works without failure since Strings are immutable in nature.
An example can again smooth things out here:

String s1 = "Agraj";
String s2 = "Agraj";
System.out.println(s1 == s2);              // prints true !!
System.out.println(s1.equals(s2));     // prints true as expected

String s1 = "Agraj";
String s2 = new String("Agraj");
System.out.println(s1 == s2);              // prints false because of 'new'
System.out.println(s1.equals(s2));     // prints true as expected

The first example prints according to String constant pool approach. While, the second example allocates memory again to s2 because the new operator is used, which forces the compiler to allocate memory again.
It would not hurt to remember that the '==' operator is used to compare references while the 'equals' function actually compares the string value(character by character) stored inside the objects.

On some pondering, one might think that if identical strings are not allocated same memory, then if one might change one reference to the string, then all other references would also reflect the change. For example,

String s1 = "Agraj";
String s2 = "Agraj";
s1 = s1.toUpperCase();       // s1 = "AGRAJ" but s2="Agraj"

One might expect s2 also to be equal to "AGRAJ", which is not desired. But, since Strings are immutable in nature, so the toUpperCase() function creates a new string, rather than modifying the original string (it cannot modify the original string, nothing can) and assigns it to s1 while s2 still reference to the original string "Agraj".

StringBuffer and StringBuilder 

A person can argue that in a module that does heavy String manipulation, there would be excess of new Strings that would be created now and then and would not be used at the end, leading to wastage of memory. And you see, this person is not entirely wrong. Strings if used in a careless manner can cause huge performance bottleneck. 
So mostly, when we have to do String manipulation a lot in our application, it is advisable to use classes such as StringBuffer & StringBuilder. Both of these provide the same API and behave in the same manner as Strings do, the difference being the fact that they are mutable. Thus, you can change a StringBuffer / StringBuilder object once created. 
Example:

StringBuilder str1 = new StringBuilder("Hello");
str1.append(" World");

would change the existing object "Hello" and will not create a new object as normal String Object would have done. 

Difference b/w StringBuilder & StringBuffer
Both of them provide us with the same API and thus are similar except the fact that StringBuffer is thread-safe while StringBuilder is not. 
Thus it is always advisable to use StringBuilder class, where-ever thread-safety is not a issue (which is commonly the case always). It is advisable to use StringBuilder than StringBuffer because StringBuilder is much more faster than its thread-safe twin. This is so because it ignores the complications that comes along while deailing with stuff like synchronization and threads. 

There is much more to Strings usage in Java than what can be covered in a blog entry, but I guess I have covered some of the important points which are normally ignored by novices like me. 

Saturday, April 25, 2009

Ergonomics - Garbage Collection in Java

What is Ergonomics ?

With J2SE 5.0 onwards, Ergonomics is defined as the capability of the JVM to
  • Automatically select Heap Size, Garbage collector & type of Virtual Machine (server or client) based on the platform on which your application is running.
  • Allowing us to Tune the behaviour of the Garbage Collector using various command line options to achieve the desired effect. 
But, the aim of Ergonomics is to improve performance & minimize command line tuning as it believes in selecting the optimum configuration for the application which is running. The values are chosen based on the type of machine and the operating system (the platform) on which the application is running.

Machines are divided into 2 categories:
  • Server class machines
  • Non-server class machines
According to J2SE 5.0, a server class machine is the one which has
  1. At least 2 CPU's (processors)
  2. At least 2 GB of physical memory
All other machines with less no of processors and memory are treated as non-server class machines. As visible from the configuration, the server class machines are mostly used to run large applications (typically web applications using some server framework) 

Automatic Selections

For a server class machine, the default values chosen are

Type of JVM : Server JVM
Type of Garbage Collector  : Parallel Garbage Collector
Heap Size :
1/64th of Physical Mem Avail  <=  Min Heap Size  <= 1 GB
1/4th of Physical Mem Avail    <=  Max Heap Size <= 1 GB

For a non-server class machine, the default values chosen are

Type of JVM    : Client JVM
Type of Garbage Collector     : Serial Collector
Heap Size :
Min Heap Size :    4 MB
Max Heap Size : 64 MB

To explicitly make JVM treat your machine as server machine, one can do it using any of the 2 ways:
1. Use the -server command line option with java command
2. Change the first two lines of jvm.cfg file in your JRE_installation_directory/lib/
Change 
-client KNOWN
-server KNOWN
to
-server KNOWN
-client KNOWN

A server JVM differs from client JVM in the sense that it might take more time (approx. 10% more time) in start-up, but eventually it increases the performance & the throughput of the application in the long run. 
While client JVM is sufficient for normal standalone applications, server JVM is best suited for large-scale applications like web applications using a server framework running on some application server.

Behavioral Tuning

If you really know that these automatic settings are not suitable for your application, then JVM gives you the flexibility of changing them as well.

Changing the type of VM
Use -client for using Client VM
Use -server for using Server VM

Changing the type of Garbage Collector
Use
-XX:UseSerialGC Serial Collector
-XX:UseParallelGC Parallel Collector
-XX:UseParallelOldGC Parallel Compacting Collector
-XX:UseConcMarkSweepGC CMS Collector

Changing the Heap Size
Use -Xms to set Minimum heap size. Ex: -Xms512 will set 512MB to be minimum heap size
Use -Xmx to set Maximum heap size. Ex: -Xmx724 will set 724MB to be maximum heap size.

Setting maximum & minimum heap size to be same takes away the flexibility away from JVM of changing the heap size according to the requirements as they arise.

Certain Goals
With these command line options, you can set certain goals for the Garbage Collector to achieve and their relative priorities. The Garbage Collector works to achieve these goals and can change the heap size and other related parameters

Maximum Pause Time Goal
This goal can be used to set Maximum pause time that a Garbage Collector is allowed i.e. we can specify -XX:MaxGCPauseMillis=n meaning that Garbage Collector is allowed a maximum pause time of n milliseconds for each generation. And if it is not able to limit itself to n milliseconds then it must take some measures to achieve this goal. For example, it can reduce the size of the heap in order to reduce the maximum pause time.

Throughput Goal
It can be used to specify the time spend in doing Garbage Collection using -XX:GCTimeRatio=n 
The ratio of garbage collection time to application time is 1/(1+n)
So, that means if we set -XX:GCTimeRatio=19, it means that a maximum of 5% of total time can be spend in Garbage Collection.
Default value is n=99 which means that 1% of  total time is allowed for garbage collection
If this goal is not met, then the size of heap is increased so that it takes more time to fill the heap and thus garbage collection occurs less frequently.

Footprint Goal
This is an interesting one. It specifies that if Maximum Pause time goal and Throughput goal have been met, then keep on decreasing the size of the heap until one of the above mentioned Goals cannot be met. Then try to meet that goal. :-)

Goal Priorities
This goal specifies that priority of above mentioned goals. The order of importance is 
1. Max Pause Time goal
2. Throughout goal
3. Footprint goal

Tools to evaluate GC performace
In an ideal condition, you need not worry about Garbage Collection. This is precisely the goal of Ergonomics; selecting the best possible configuration according to the machine on which the application is running. But if your application runs into memory troubles like memory leaks and OutOfMemoryError, then there exists a plethora of tools to choose from.
Writing about each of them is out of scope of this document. So, I'm just giving out the names and the required links that would help you analyze the application and take proper steps

Some Tools To Look Out for
jConsole (Monitor you App)
HPROF (A Heap/CPU Profiling Tool)
jHat (Java Heap Analysis Tool)
VisualVM (Latest Tool and a Very Good One)
jStack (Stack Trace)
jinfo (Configuration Info)

Disclaimer: The contents of this blog and of all others are totally my personal opinion about the stuff, I have written and has nothing to do with my employer :-)

Wednesday, March 18, 2009

Getting started with Ant

Each one of us has used Ant knowingly or unknowingly, while building our projects. But, most of us are not aware of its existence. Thanks to IDEs like Eclipse & NetBeans !!

But, I feel that one must know how things happen. How a series of commands are executed when you build your project and how you can control and alter this flow.

This entry is not meant to give you insight into the build process but it is meant to introduce the tool (Ant) to beginners like me. We will go through installation and normal usage of Ant Tool.

So, lets get started :-)

What is ANT ?

Ant is a Java-based build tool used for automating the build process.
Ant is written in Java and that's what makes it platform-independent. This also means that you lose out on doing certain things (issuing certain OS-specific commands in build.xml) that could be done fastly in a OS-dependent manner.
ANT is an acronym for "Another Neat Tool". :-)
It accepts input in form of XML files (like build.xml) and can be used to perform repeatitive task in an efficient manner.

Installing ANT

Download the binary distribution from here.
Now, all you have to do to install ant and run from command line is to set following environment variables:
  • ANT_HOME : Set this variable to the path where you have unzipped the downloaded binary distribution
  • PATH : Append the ANT_HOME/bin to the already existing PATH value. This is needed so that we can run ant from command line.
  • JAVA_HOME : Set this variable(if not already set) to the path where JDK is installed
And Bingo !! you are done with installation. It's time to test whether we have installed Ant correctly or not

Test Your Installation

To test whether you have successfully installed Ant or not, type
>ant
on command line and press enter

It will give an error like
Buildfile: build.xml doesn't exist!
Build failed
because right now there is no build.xml file existing in the current directory. Ant tool makes use of build.xml to automate the build process.

Congratulations !!
You have successfully installed ANT if you can see this error message. :-)

What is build.xml ?

It is nothing but a normal XML file that is used to automate the build process. It contains certain commands that are executed in a defined/prescribed manner. You can think of it as writing a Shell Script which will be executed by Ant tool. Actually it's more like a make-file that we have in Linux/Unix environment.

A normal build.xml file would consist of following sections, in that order:
  1. Clean - It removes all the previously deployed files of the same application, if any.
  2. Init - Creating the directories and subdirectories according to your choice
  3. Compile - Used to compile the *.java files & servlets or jsp's with the help of libraries
  4. Copy - It copies the compiled class files and servlets in their appropriate locations
  5. Create-war - Finally, we create a .war file of our application and copy it to your server's deplyoment directory so that you can run the application.
All these steps are not neccessary and it depends entirely on you that what you wanna keep in your build.xml.
A look at a simple build.xml would simply what seems so tough right now. :-)


BUILD.XML


Lets see what it really means:

1. Root Element



First line tells us that it is a XML file.
Then comes the root element, project. Rest of the code for this project will come in between project tags. It has 3 attributes:
  1. name (optional) - Name of the project
  2. default (required) - The default target to use when no target is specified
  3. basedir (optional) - This tells the basedir for all the paths mentioned in the in this script. If it is missing, then parent directory of this build script will be used as basedir

2. User-defined variables



These 2 lines declare user-defined variables which are used later in the file.
src holds the location of the current directory as given by '.'
build holds the location "basedir/build" where basedir was defined in project name above.
Remember all the paths mentioned are relative to basedir

So, property tag is used to give name-value pairs, but same effect could have been achieved by mentioning these name-value pairs in an external file (named build.properties) and using them in build.xml as they are used now.


3. Clean your earlier deployment



Target tag is like a function which you can call again to perform a reusable task.
These lines are pretty simple to understand.
The echo tag will echo/display whats written to the output console, and the delete command will delete the build directory

${build} is way to evaluate the build variable that we have defined above using property tag

4. Initialization - Creating Directory Structure for deployment



Here, we just create a directory using mkdir command.
The thing to note here is the depends attribute of target tag. This attribute is used throughout build.xml to create a chain of targets, to give a sequential flow i.e. it helps in specifying the dependencies of one module over another and tells us how the targets will be called.


5. Compiling source files and copying them to destination folder



This function compiles the source files present in src directory and stores the resulting .class files in build directory.
I have deliberately not added more steps like creating a war file and deploying it on server, because that would make this entry long and complicated un-neccessarily. Time to run what we have done so far.

Running this script

To run this script, create a folder and name it Test and copy this build.xml file in it. And to test whether your script works or not, create any correct java file in this Test folder, which we will compile.

Your directory structure should look like this.

Test
|
|------ build.xml
|
|-------HelloWorld.java


To run your build script, go to Test Folder, and type ant

C:\Users\Agraj\Desktop\Test>ant

If everything goes correct, it will give output

Buildfile: build.xml

clean:
[echo] Deleting build
[delete] Deleting directory C:\Users\Agraj\Desktop\Test\build

init:
[echo] Creating new directory: build
[mkdir] Created dir: C:\Users\Agraj\Desktop\Test\build

compile:
[echo] Compiling source files present in . to build
[javac] Compiling 1 source file to C:\Users\Agraj\Desktop\Test\build

BUILD SUCCESSFUL
Total time: 2 seconds

For starters, it doesn't and shouldn't work right away :-)
I said shouldn't because if it does, then perhaps you won't enjoy and learn more about Ant.

Having said that, the problem that occurs most commonly is that Ant tool is unable to parse the build.xml file correctly. This is so because even a space or tab inserted in xml file can cause Ant to fail. You can get to know about the extra spaces/tabs using vi editor on linux/unix machines, but it can be pretty frustating on windows to look out for such an error

Although, most of us will never change the build.xml while development but still it helps a lot when you know what happens when you build your project and you don't feel alien to the environment :-)

Random Notes :
  • Make sure that your CLASSPATH variable doesn't have any single quotes or double quotes ( ' or " ) in it even if there is a space in the path because, the presence of them will make ANT to fail.
  • Also make sure that there is no ending forward or backward slash ( / or \ ) in your CLASSPATH
  • For more on Ant, please refer to FAQ section here
  • For detailed installation from source or for setting optional parameters/preferences, one can go to the docs/manual/index.html page of the installation directory
Any comments, suggestions and corrections are welcome and required !!

Thursday, January 22, 2009

Checked Vs Unchecked Exceptions

In Java, there are 2 kinds of Exception:

Unchecked Exceptions which indicate some sort of programming error on the part of developer. Unchecked Exceptions are usually subclasses of RuntimeException class. Examples include: 
 --- NullPointerException (which is usually thrown when method is              invoked on a null object)
 --- DivideByZeroException (thrown when divide by zero happens in        your code)
 --- IllegalArgumentException (usually thrown when invalid argument        is passed to a method)
 --- ArrayIndexOutOfBoundsException (thrown when you try to access         array index beyond the memory allocated to it)
 --- ArithmeticException
 --- RuntimeException
If your methods throw an unchecked exception, then your method need not specify it as a part of its API i.e no need to write all the exceptions it throws using "throws" clause.

Checked Exceptions on the other hand, specifies conditions that are not due to human errors but due to conditions that are not in programmer's control. These include conditions such as database errors, network failures, file not found when searching or performing some operation on it. Examples include:
 --- FileNotFoundException
 --- SQLException
 --- PersistenceException
On the other hand, if your code throws any checked conditions, then either you must handle it or specify it using "throws" clause else your program will give compile-time error. 

Checked Vs Unchecked
Use Checked Exception in your code when you Client code (code that calls your code) is capable of dealing with the Exception and have ample knowledge why that Exception occurred in the first place and how to do away with it. 
Otherwise, it is always preferable to use Unchecked Exceptions since then the Client code is not forced to handle it and can choose to ignore it. Though that would not solve the problem and the exception would travel high up in hierarchy of function calls and perhaps finally encountered by the JVM, but at least the Client code is saved from the hassle of dealing with Exceptions that they don't know about it.
Let's take an example. Suppose we have a method throwing an SQLException:
The client code would never come to know that why this SQLException occurred, as it has no knowledge of underlying business logic and internal database design. Thus client is unable to handle the exception, so its always better to not force a client to handle an exception he do not know about.

Articles Worth Reading: