The specification Web Services for Java EE, JSR 109 defines two ways of implementing a web service. One way is based on the Java class programming model -- the web service is implemented by a Java class that runs in a web container. The other way is based on the
A sample package accompanies this tip. It demonstrates a standalone Java client accessing the EJB 3.0-based Calculator service. The example uses an open source reference implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Community Downloads page.
Writing the EJB 3.0 Stateless Session Bean Class
Let's start by creating the stateless session bean for the service. One of the significant improvements in the Java EE 5 platform is a much simpler EJB programming model as defined in the Enterprise JavaBeans 3.0 Specification, JSR-220. One of the simplifications is that a bean implementation class is no longer required to implement the javax.ejb.SessionBean or javax.ejb.EntityBean interface. You can declare a class a session bean or
EJB 3.0 does specify additional rules for the bean implementation class:
- It must be declared public and must have a default constructor that doesn't take any arguments.
- It must not be final or abstract and must be a top-level class.
- It must not define a finalize() method.
Another simplification in EJB 3.0 is that a component interface or home interface is no longer required for a session bean. The one interface a session bean needs is a business interface that defines the business methods for the bean. Unlike business methods in a component interface, the business methods in a business interface are not required to throw java.remote.RemoteException. However the business methods can define throws clauses for arbitrary application exceptions. The EJB 3.0 business methods should not be static and final.
Given these simplifications and rules, here is a stateless session bean for the Calculator class that conforms to the EJB 3.0 programming model (you can find the source code for the Calculator class in the endpoint directory of the installed sample package):
package endpoint; |
Because the EJB 3.0 bean doesn't need to implement the javax.ejb.SessionBean interface, it no longer needs to include unimplemented lifecycle methods such as ejbActivate and ejbPassivate. This results in a much simpler and cleaner class. Various annotations defined in EJB 3.0 reduce the burden on developers and deployers by reducing or eliminating the need to write a deployment descriptor for the component.
Marking the EJB 3.0 Bean as a Web Service
To mark a bean as a web service simply annotate the class with the @WebService annotation. This is an annotation type defined in the javax.jws.WebService package, and is specified in Web Services Metadata for the Java Platform, JSR 181. Here is the code for Calculator class marked as a web service:
package endpoint; |
Marking a Java class with a @WebService annotation makes it a service implementation class. Note that you don't have to implement a service endpoint interface. According to the JSR 109, you only need to provide a javax.jws.WebService-annotated service implementation bean. Deployment tools can then be used to generate a service endpoint interface, as well as a WSDL document, using JAX-WS rules for Java WSDL mapping.
Packaging the Web Service
A web service based on the EJB programming model needs to be packaged as a JAR file. Using the @WebService annotation, you only need to package the service implementation bean class (with its dependent classes, if any) and the service endpoint interface class (if explicitly provided). Additionally, the @Stateless annotation frees you from packaging ejb-jar.xml. By comparison, in the JAX-RPC style of packaging web services based on EJB 2.0 or earlier, you were responsible for providing the service endpoint interface class, the service implementation bean class (and dependent classes), generated portable artifacts, the JAX-RPC mapping file, and a web services deployment descriptor (webservices.xml and ejb-jar.xml).
With JSR 224, JSR 109, JSR 181 and JSR 220, an application server deployment tool can generate all the necessary artifacts such as a deployment descriptor (if not explicitly provided by the user) for deploying the web service. These artifacts, bundled in the EJB JAR file, are deployed in an EJB container. A deployer can choose to overwrite values specified by the @WebService and @Stateless annotations by explicitly providing any of the previously-mentioned artifacts and packaging them in the EJB module at the time of deployment. For this tip, the following files are packaged in the EJB module to be deployed:
endpoint/Calculator.class
endpoint/jaxws/Add.class
endpoint/jaxws/AddResponse.class
The rest of the deployment artifacts are generated by the application server (in this case, GlassFish).
Writing the Client
After you deploy the web service, you can access it from a
@WebServiceRef(wsdlLocation=
"http://localhost:8080/CalculatorService/Calculator?WSDL")
static endpoint.CalculatorService service;
The value of the wsdlLocation parameter in @WebServiceRef is a URL that points to the location of the WSDL file for the referenced service. (The @WebServiceRef annotation supports additional properties that are optional. These optional properties are specified in section 7.9 of the JAX-WS 2.0 specification.) The static variable named service will be injected by the application client container.
Looking further at the source code for JAXWSClient, you'll notice the following line:
endpoint.Calculator port = service.getCalculatorPort(); |
The service object provides the method, getCalculatorPort, to access the Calculator port of the web service. Note that both endpoint.CalculatorService and endpoint.Calculator are portable artifacts that are generated by using the wsimport utility. The wsimport utility is used to generate JAX-WS artifacts (it is invoked as part of the build-client step when you run the example program.)
After you get the port, you can invoke a business method on it just as though you invoke a Java method on an object. For example, the following line in JAXWSClient invokes the add method in Calculator:
int ret = port.add(i, 10); |
Running the Sample Code
A sample package accompanies this tip. It demonstrates the techniques covered in the tip. To install and run the sample:
- If you haven't already done so, download GlassFish from the GlassFish Community Downloads page.
- Set the following environment variables:
- Download the sample package for the tip and extract its contents. You should now see the newly extracted directory as
/ttmar2006ejb-ws, where is the directory in which you installed the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\ttmar2006ejb-ws. The ejb-techtip directory below ttmar2006ejb-ws contains the source files and other support file for the sample. - Change to the ejb-techtip directory and edit the build.properties files as appropriate. For example, if the admin host is remote, change the value of admin.host from the default (localhost) to the appropriate remote host.
- Start GlassFish by entering the following command:
- In the ejb-techtip directory, execute the following commands:
- To undeploy the EJB Module from GlassFish, execute the following command:
GLASSFISH_HOME: This should point to where you installed GlassFish (for example C:\Sun\AppServer)
ANT_HOME: This should point to where ant is installed. Ant is included in the GlassFish bundle that you downloaded. (In Windows, it's in the lib\ant subdirectory.)
JAVA_HOME: This should point to the location of
Also, add the ant location to your PATH environment variable.
/bin/asadmin start-domain domain1
where
ant build
This creates a build directory, compiles the classes, and puts the compiled classes in the build directory. It also creates an archive directory, creates a JAR file, and puts the JAR file in the archive directory.
ant deploy
This deploys the JAR file on GlassFish.
ant build-client
This generates portable artifacts and compiles the client source code.
ant run
This runs the application client and invokes the add operation in the Calculator service 10 times, adding 10 to the numbers 0-to-9. You should see the following in response:
run:
[echo] Executing appclient with client class as
client.JAXWSClient
[exec] Retrieving port from the service
endpoint.CalculatorService@159780d
[exec] Invoking add operation on the calculator port
[exec] Adding : 0 + 10 = 10
[exec] Adding : 1 + 10 = 11
[exec] Adding : 2 + 10 = 12
[exec] Adding : 3 + 10 = 13
[exec] Adding : 4 + 10 = 14
[exec] Adding : 5 + 10 = 15
[exec] Adding : 6 + 10 = 16
[exec] Adding : 7 + 10 = 17
[exec] Adding : 8 + 10 = 18
[exec] Adding : 9 + 10 = 19
ant undeploy
About the Author
Manisha Umbarje is a member of the product engineering group for the Sun Java System Application Server.
Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.
1 comment:
Interesting Article
EJB 3 Online Training | Java Online Training
Java Online Training from India | Core Java Online Training
Post a Comment