Monday Jan 23, 2006

A Webservice and a Client in 5 simple steps using Glassfish

In my previous blog, I went into some details of how development of webservices has been made easy in JavaEE5 platform and made easier by Glassfish. In this blog, you will see those words in action as I develop a simple JAXWS based webservice on Glassfish. As mentioned in my previous blog, couple of earlier blogs have addressed this. But still I chose to write a new one because :


  • I want to show how a developer can get a JAXWS based service and a client up and running on Glassfish with just a handful of simple steps.

  • The blog written by Jerome is pretty old and the specification has changed a bit since then.

  • Also the blog written by Bobby is related to developing a JAXWS based service on JWSDP which will work as is on Glassfish but is not JSR109 compliant and hence is not portable across JavaEE platforms.

I will write a separate blog on how to move a JAXWS based service developed for JWSDP to be JSR109 compliant so that the service is portable across JavaEE platform implementations.

Before starting, lets us get the environment set properly. I have used Glassfish as my JavaEE platform. You should have this installed on your system to try out this sample. The $GLASSFISH_HOME referred to is the directory where you have installed Glassfish on your system. Also you will need JDK5. You need to point JAVA_HOME to a valid JDK5 installed directory.

With your environment set properly, here is a simple webservice endpoint that adds two numbers :

package endpoint;

import javax.jws.WebService;

@WebService
public class AddNumbers {
public int add(int n1, int n2) {
return n1+n2;
}
}

Save this as endpoint/AddNumbers.java and compile this into the autodeploy directory of Glassfish using the following command

PROMPT> $JAVA_HOME/bin/javac -cp $GLASSFISH_HOME/lib/javaee.jar -d $GLASSFISH_HOME/domains/domain1/autodeploy endpoint/AddNumbers.java

and this endpoint gets deployed as a web service. You can see that the service is deployed and available by accessing the following link in your browser :

http://localhost:8080/AddNumbers/AddNumbersService?WSDL

Now that we have a service up and running, here is a simple webservice client that uses the above service :

package client;

import javax.xml.ws.WebServiceRef;

import endpoint.AddNumbersService;
import endpoint.AddNumbers;

public class Client {

@WebServiceRef(wsdlLocation="http://localhost:8080/AddNumbers/AddNumbersService?WSDL")
static AddNumbersService service;

public static void main(String[] args) {
Client client = new Client();
client.doAdd();
}

public void doAdd() {
try {
AddNumbers port = service.getAddNumbersPort();
int ret = port.add(11,22);
System.out.println("Add result = " + ret);
} catch(Exception e) {
e.printStackTrace();
}
}
}

Save this as client/Client.java. Now, to get the client up and running, here is what you do : First, generate all required client side artifacts from the WSDL (this is required so that the client has the webservice interfaces and ports available), then compile the client with these artifacts and then run the client in the appclient container :


PROMPT>$GLASSFISH_HOME/bin/wsimport -d client http://localhost:8080/AddNumbers/AddNumbersService?WSDL

PROMPT>$JAVA_HOME/bin/javac -cp .:./client:$GLASSFISH_HOME/lib/javaee.jar client/Client.java

PROMPT>export APPCPATH=.:./client:$CLASSPATH; $GLASSFISH_HOME/bin/appclient client.Client

Add result = 33
PROMPT>

Thats it - you have got a service developed, deployed and running with a client accessing the service. It is that simple.

Here are some useful notes on what we have done :


  • In all the URLs used above, you may have to change the host and port info as per your environment

  • @WebService is required to be present in the endpoint implementation class and this indicates that AddNumbers.class is indeed a JAXWS based webservice endpoint. As mentioned, You can see how use of this simple annotation obviates the need for all those pesky deployment descriptors like webservices.xml :)

  • @WebServiceRef in the client indicates this client refers to a webservice and the rest is done for you. As mentioned, no need for those JNDI lookups :)

  • When you run wsimport to generate client side artifacts, the classes are generated under package 'endpoint'; if you use '-keep' option for wsimport, you can see the generated source files also

  • And the above steps also shows you how Glassfish has made life even easier by not requiring you to package things - all that you did above was to write java classes and perform certain simple steps and, voila !!!, you got a service deployed and a client also used that service successfully. And with our friends at NetBeans planning to support JAXWS based webservice development soon, life for webservice developers using NetBeans and Glassfish should be lots of fun :)

  • The steps described above results in the service being deployed as a webservice with servlet endpoint. For a service with an EJB endpoint, all that you do is to add @Stateless annotation to the implementation class - thats it - more on that in a later blog

Hope developers found this useful - Your comments and suggestions are most welcome. You can either post your comment on this blog or start a thread in the Glassfish discussion forums. You can also submit new feature requests via the Glassfish community mechanism.

Tuesday Jan 17, 2006

webservice made easy

As I had mentioned in my previous blog, my colleagues have already blogged about developing and deploying a very simple JAXWS based webservice on Glassfish. Those blogs give you some idea about what is involved in developing and deploying a simple JAXWS based webservice either using a 'vi' like text editor or IDEs. In this blog, I will give an overview of what has changed from a developer's perspective - what are the major differences between developing a JAXRPC based webservice and a JAXWS based webservice.

Note that :


  • Great IDEs like NetBeans did a very good job of hiding much of the requirements for JAXRPC based services from a developer but those of us (like me) who swear by 'emacs' and 'ant' had to face these things)

  • What I have listed below is what a developer trying to develop a JAXWS based service will see as the improvements for a simple web service. There are many more ways life has been made easy for a webservice developer in JavaEE5 and GlassFish and this list does not cover everything - this list is just a starting point and hopefully future blogs will cover other points.

The shortest way to describe the change is 'make life of a developer easy' which has been the focus of JavaEE5 platform. Given that, at first I will list the ways in which the JavaEE5 platform has made development and deployment of webservice easy.


  • No need for that esoteric webservice.xml deployment descriptor : With the JAXWS specification defining the annotations to be used for various webservice features, a developer can deploy a JAXWS webservice on a JavaEE5 platform without a single webservice related deployment descriptor. In comparison, a JAXRPC based webservice required the developer to deploy the webservice as a WAR / EJB-JAR / EAR in which the webservice.xml descriptor was a mandatory requirement.

  • No need for those generated mapping files : For a JAXWS based service, the requirement of the mapping file that contains the information on java-wsdl mapping has been completely done away with. JAXRPC based service required such a mapping file to be packaged in the deployable artifact.

  • No need to have a webservice interface class : JAXWS does away with the requirement that every webservice needs to have an interface class and an endpoint implementation class. Any class having the @WebService annotation is considered a webservice endpoint implementation class. The additional presence of @Stateless will make that endpoint an EJB-webservice endpoint, but more on that in a later blog. For now, it is enough to note that there is no need for the developer to have an interface and an implementation class for a JAXWS based service whereas this is not the case in the case of JAXRPC service. A JAXRPC service required an endpoint interface class that looked somethig like this :

    public interface WeatherService extends Remote {...}

    and then an impl class that looked somethis like this :

    public class WeatherServiceImpl implements WeatherService, ServiceLifecycle {...}


  • No need for a client to lookup a service using JNDI : A JAXWS based client looking up a webservice just uses the @WebServiceRef annotation to look up a deployed webservice and use it. There is no need for those <service-ref> elements in the client's deployment descriptor and there is no need for the client to look up the service using JNDI lookup mechanism which is the case in a JAXRPC client.

  • Relaxed packaging requirements

  • Easier way to specify handlers through annotations

And now, I will go into the details on how Glassfish improves upon the above to make life of a developer even easier.


  • As Jerome points out in his blog, Glassfish makes life even easier by taking out the need for packaging anything. In Glassfish, the simplest "Hello World" kind of webservice can be just a single class : the webservice endpoint implementation class.

  • Deploying such a simple service does not require any packaging. Simply compiling the endpoint implementation class into the autodeploy directory of Glassfish, as detailed by Jerome, will result in deployment of such a service as a webservice with servlet endpoint.

  • Similarly, as Jerome points out in his blog, the client accessing the simple 'Hello World' kind of service will be a single class with just a simple annotation without any JNDI lookups

  • For the client to deploy and run, there is no need for the developer to do anything but write the simple client class and then use the 'asapt' script which does the rest of the job for the developer :) :)

Thus the simplest of a webservice developed and deployed on Glassfish will be a service endpoint implementation class and client class - each with couple of lines of code - compiled into particular directories without the need for any descriptors whatsoever. With leading IDEs, Netbeans, planning to release support for Glassfish pretty soon, the life of a developer should be made much easier :) :)

Since Jerome's blog last June, the specifications have changed a bit (surely for the better). So I will address developing a simple servlet webservice endpoint (will reuse lots of Jerome's blog - thanks Jerome :)) and a simple EJB webservice endpoint in my next blog.

Hope developers find this info useful - Your comments and suggestions are most welcome. You can either post your comment on this blog or start a thread in the Glassfish discussion forums. You can also submit new feature requests via the Glassfish community mechanism.

Thursday Jan 12, 2006

Hello Web Service developers

Hello World :) :)

Now that the WebService implemention in Glassfish is almost complete, I thought I will start blogging about how developers can use the webservice features in Glassfish. Obviously, my blogs will use Glassfish as the reference JavaEE5 platform and will highlight the nice features available in Glassfish that makes the life of a web service developer so darn easy.

Already my colleagues Jerome. Manisha, Bobby and Vince have written about developing JAXWS based Webservices in Glassfish. I will start with these as a reference to begin with and go into the various details gradually - hope developers find it useful - Your comments and suggestions are most welcome. You can also submit new feature requests via the Glassfish community mechanism.