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