<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TechJava&#187; TechJava &#8211; Articles on jboss</title>
	<atom:link href="http://www.techjava.de/topics/category/es/jboss/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techjava.de</link>
	<description>Journal on Java Technology</description>
	<lastBuildDate>Thu, 17 Jun 2010 10:41:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Exposing Functionality using Web Services and JEE</title>
		<link>http://www.techjava.de/topics/2010/01/functionality-web-services-jee/</link>
		<comments>http://www.techjava.de/topics/2010/01/functionality-web-services-jee/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 11:11:22 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[bean]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[ejb3]]></category>
		<category><![CDATA[java 5]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[web service]]></category>
		<category><![CDATA[wsdl]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=554</guid>
		<description><![CDATA[
Abstract
About two years ago, I published an 
article about Exposing the Functionality implemented in Stateless Session Beans (EJB 2.1) using Web Services. J2EE 1.4 times are over and the new version of the Java Enterprise framework, called Java Enterprise Edition 5 (JavaEE 5, or simply JEE) has emerged. In this article the same business scenario [...]]]></description>
			<content:encoded><![CDATA[<h2>
<a  href="http://www.techjava.de/wp-content/uploads/valve.jpg" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/valve.jpg');" ><img style="float: right; margin: 5px;" title="valve" src="http://www.techjava.de/wp-content/uploads/valve-150x150.jpg" alt="" width="150" height="150" /></a>Abstract</h2>
<p>About two years ago, I published an 
<a  href="http://www.techjava.de/topics/2008/02/ws4j2ee14/">article</a> about Exposing the Functionality implemented in Stateless Session Beans (EJB 2.1) using Web Services. J2EE 1.4 times are over and the new version of the Java Enterprise framework, called Java Enterprise Edition 5 (JavaEE 5, or simply JEE) has emerged. In this article the same business scenario is repeated in the new framework. </p>
<h2>Requirements</h2>
<p>Before we dive into code examples, some software is required. The good news about the software is, that it also evolved over time. Here is what we use:</p>
<ul>
<li>Sun&#8217;s Java 6 SDK</li>
<li>JBoss AS 5.1.0 GA for JDK6</li>
<li>Eclipse Galileo 3.5.1 for JEE development</li>
</ul>
<p><span id="more-554"></span><br />
Some words about the used software. It is important to get the JDK6-compiled version of the JBoss Application Server. There are some issues with running the version compiled with Java 5 on JDK6, since JDK6 has its own JAX-WS implementation which causes problems with JBoss (affected should be all versions of JBoss &lt; 5.2. Currently it seems like version 5.2 will be compiled with JDK6 by default.) If you launch JBoss from Eclipse, make sure to add the <code>-Djava.endorsed.dirs=PATH_TO_JBOSS/jboss-5.1.0.GA/lib/endorsed</code> as a VM argument, if launched from the command line, please add it as an option inside of the <code>run.conf.bat</code> file:</p>
<pre class="brush: bash;">
set &quot;JAVA_OPTS=%JAVA_OPTS% -Djava.endorsed.dirs=$JBOSS_HOME/lib/endorsed&quot;
</pre>
<p>Otherwise you will get the following exception:</p>
<pre class="brush: java;">java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage</pre>
<p>After installation (unpacking) of Eclipse, make sure to configure the JDK (under <strong>Preferences &gt; Java &gt; Installed JREs</strong>) and the JBoss instance (<strong>Preferences &gt; Server &gt; Runtime Environment</strong>).</p>
<h2>Use Case</h2>
<p>In order to demonstrate the technology by example, imagine the following use case. The system under construction is capable of providing measurements of some sensors. The sensors are identified by numbers and can be queried by the user by providing the timespan of measurements. As a result, the systems delivers the set of measurements for the given timespan with one measurement per minute but at most sixty measurements. Every measurement contains the id of sensor from which it has been recorded, the timestamp, the value as a byte array, the measurement unit and finally a flag whether the measurement exceeds the limits or specified alarm values.</p>
<h2>Implementation</h2>
<p>We start the implementation with the creation of a JEE Session Bean and then expose the functionality using a second Facade bean. In doing so we follow the EJB 3 specification.</p>
<h3>Eclipse for Java EE development</h3>
<p>The plugins in Eclipse for Java EE provide massive support and foster the development by deep integration withe JEE servers. Instead of a simple Java Project, start with an <strong>Enterprise Application Project</strong>. Then, create a new <strong>EJB Project</strong> and add it to the created Enterprise Application Project. In order to deploy the resulting application to the server, right-click on the enterprise project and select <strong>Run As &gt; Run on Server </strong>.</p>
<p>To check the deployment on the application server, use the JBoss Consoles. These can be accessed via 
<a  href="http://localhost:8080/" onclick="javascript:pageTracker._trackPageview('/external/localhost/');" >http://localhost:8080/</a> for the locally installed JBoss. An additional Web Service Console is accessible via 
<a  href="http://localhost:8080/jbossws/" onclick="javascript:pageTracker._trackPageview('/external/localhost/jbossws/');" >http://localhost:8080/jbossws/</a>.</p>
<h3>Implementing the Functionality</h3>
<p>In order to implement the functionality in a stateless session bean, we start with the creation of the business interface.</p>
<pre class="brush: java;">
/**
 * Defines the sensor manager functionality
 */
public interface SensorManager
{
	/**
	 * Retrieve sensor data
	 * @param sensorId id of the sensor
	 * @param timespan the measurement period
	 * @return a list of measurements in the given period
	 * @throws SensorManagerException on any kinds of errors
	 */
	public List&lt;Measurement&gt; getSensorData(SensorID sensorId, Timespan timespan) throws SensorManagerException;
}
</pre>
<p>The POJOs <code>Measurement</code>, <code>SensorID</code> and <code>Timespan</code> are used to show the usage of custom user types:</p>
<pre class="brush: java;">
public class Measurement
{
	private SensorID sensorID;
	private Date timestamp;
	private boolean critical;
	private byte[] value;
	private String unit;
...
// getters and setters
}
....
public class SensorID
{
	private long sensorId;
...
// getters and setters
}

public class Timespan
{
	private Date start;
	private Date end;
...
// getters and setters
}
</pre>
<p>After the creation of the business interface, let us create the actual Session Bean. The class is annotated with the <code>@javax.ejb.Stateless</code> annotation in order to indicate that the bean is a Stateless Session Bean. Since it implements the business interface (and only it), the container will be able to deduce that the given interface is the Local Business interface: this is just one of many examples of the Configurations by Exception in EJB 3. In order to be able to reference the bean from other beans, we annotate the binding of the local interface to a specific JNDI name using the vendor-specific annotation <code>org.jboss.ejb3.LocalBinding</code>.</p>
<pre class="brush: java;">
@Stateless
@LocalBinding(jndiBinding=&quot;de.techjava.sensor/SensorManager&quot;)
public class SensorManagerBean implements SensorManager
{
	/** Logging facility */
	protected static Logger LOG = Logger.getLogger(SensorManagerBean.class);
	/** Max number of returned values */
	private static final long MAX_DURATION = 60;

	/**
	 * Implementation of the business method
	 */
	public List&lt;Measurement&gt; getSensorData(SensorID sensorId, Timespan timespan) throws SensorManagerException
	{
		LOG.debug(&quot;Entering getSensorData()&quot;);
		if (sensorId == null || timespan == null || timespan.getStart() == null || timespan.getStart() == null)
		{
			throw new SensorManagerException(&quot;Missing a mandatory parameter, that was null (not set)&quot;);
		} else if (!timespan.getStart().before(timespan.getEnd()))
		{
			throw new SensorManagerException(&quot;The timespan is defined by the start that should be before end&quot;);
		}

		List&lt;Measurement&gt; measurements = new LinkedList&lt;Measurement&gt;();
		for (long i = 0; i &lt; getNumberOfElements(timespan); i++)
		{
			Date date = new Date();
			date.setTime(timespan.getStart().getTime() + i * 1000 * 60);
			if (date.after(timespan.getEnd()))
				break;
			Measurement measurement = createMeasurement(sensorId, date, i);
			measurements.add(measurement);
		}

		LOG.debug(&quot;Leaving getSensorData(). Returning &quot; + measurements.size() + &quot; values.&quot;);
		return measurements;
	}

	/**
	 * Retrieves the number of measurements in timespan
	 */
	private long getNumberOfElements(Timespan timespan) { ... }

	/**
	 * Creates a measurement instance, a dummy implementation
	 */
	private Measurement createMeasurement(SensorID sensorId, Date timestamp, long number) { ... }
}
</pre>
<h2>Web Service Definition</h2>
<p>The quality of the web service interface is an important design consideration. As described in 
<a  href="http://www.techjava.de/topics/2008/02/ws4j2ee14/">the previous post</a>, in many cases it is a good idea to create it by hand instead of generation by a tool. In this particular case, we create another annotated Stateless Session Bean, which is used as a Facade and contains all Web Service-specific settings. From this Bean we generate the WSDL and then tune it in order to show the capability of the customization. In doing so we try to match the WSDL from the previous example as close as possible.</p>
<p>Firstly, we create the business interface and the bean class, then annotate it and finally add the code delegating the Web Service request to the SensorManager.</p>
<pre class="brush: java;">
public interface MeasurementProviderFacade
{
	public List&lt;Measurement&gt; getSensorData(SensorID id, Timespan timespan) throws SensorDataOperationFault;
}

...

@Stateless
public class MeasurementProviderFacadeBean implements MeasurementProviderFacade
{
	public List&lt;Measurement&gt; getSensorData(SensorID id, Timespan timespan) throws SensorDataOperationFault
	{
	...
	// implementation code
	}
}
</pre>
<p>In order to have a Session Bean exposed as a Web Service, the JAX-WS specification defines a set of annotations. The most important two are <code>@javax.jws.WebMethod</code> and <code>@javax.jws.WebService</code>. The <code>@WebService</code> annotation is used to mark the class to be exposed e.G.</p>
<pre class="brush: java;">
@Stateless
@WebService(
	serviceName = &quot;MeasurementProviderService&quot;,
	name = &quot;MeasurementProviderPortType&quot;,
	portName = &quot;MeasurementProviderPort&quot;,
	targetNamespace = &quot;http://www.techjava.de/2010/ws4jee/measurement/&quot;
)
public class MeasurementProviderFacadeBean implements MeasurementProviderFacade
{
	@WebMethod(
		operationName=&quot;GetSensorDataOperation&quot;,
		action=&quot;http://www.techjava.de/2010/ws4jee/measurement/GetSensorDataOperation&quot;
	)
	public List&lt;Measurement&gt; getSensorData(SensorID id, Timespan timespan) throws SensorDataOperationFault { ... }
}
</pre>
<p>All the attributes of the annotation are optional and their values will be derived from the classname and the name of the business interface. The default target namespace for the service definition is derived from the package name, the annotated class is located in. By default, all public methods of the annotated class will be exposed as WSDL operations, with operation&#8217;s name derived from the method name. Using the <code>@WebMethod</code> annotation, the name of the WSDL operation and the SOAP action can be changed.</p>
<p>The careful reader might have observed that the <code>getSensorData</code>-method is throwing an exception. In order to map the exception to a SOAP-Fault, the <code>javax.xml.ws.WebFault</code> class-level annotation can be used. The <code>faultBean</code> attribute is used to provide the full-qulified class name of the exception.</p>
<pre class="brush: java;">
...
@WebFault(
	name=&quot;GetSensorDataFault&quot;,
	targetNamespace=&quot;http://www.techjava.de/2010/ws4jee/measurement/&quot;,
	faultBean=&quot;de.techjava.sensor.bean.SensorDataOperationFault&quot;)
public class MeasurementProviderFacadeBean implements MeasurementProviderFacade { ... }
</pre>
<p>In order to increase the quality of the WSDL further, the method parameters and return type can be annotated with <code>javax.jws.WebParam</code> and <code>javax.jws.WebResult</code> respectively, so the method signature becomes a little unreadable. In order not to copy the long string containing the taget namespace a String constant can be used.</p>
<pre class="brush: java;">
...
	public final static String TYPES = &quot;http://www.techjava.de/2010/ws4jee/measurement/types/&quot;;
...
	@WebResult(name=&quot;measurement&quot;, targetNamespace=TYPES)
	public List&lt;Measurement&gt; getSensorData(
		@WebParam(name=&quot;sensor-id&quot;, targetNamespace=TYPES) SensorID id,
		@WebParam(name=&quot;timespan&quot;, targetNamespace=TYPES) Timespan timespan) throws SensorDataOperationFault	{ ... }
</pre>
<p>Finally, in order to force the marshaller / unmarshaller to map the custom data types (<code>Measurement</code>, <code>SensorID</code> and <code>Timespan</code>) to belong to the same namespace, the JAX-B class-level annotation <code>javax.xml.bind.annotation.XmlType</code> has to be used. By default, the datatypes will be mapped to XML Schema types according to their package name and class name.</p>
<pre class="brush: java;">
@XmlType(namespace = &quot;http://www.techjava.de/2010/ws4jee/measurement/types/&quot;, name = &quot;TimeSpan&quot;, propOrder = { &quot;start&quot;, &quot;end&quot; })
public class Timespan
{
	private Date start;
	private Date end;
</pre>
<p>If deployed to the JBoss, the resulting WSDL looks as following:</p>
<pre class="brush: xml; collapse: true; light: false; toolbar: true;">
&lt;definitions name='MeasurementProviderService' targetNamespace='http://www.techjava.de/2010/ws4jee/measurement/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:ns1='http://www.techjava.de/2010/ws4jee/measurement/types/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://www.techjava.de/2010/ws4jee/measurement/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'&gt;
 &lt;types&gt;
  &lt;xs:schema targetNamespace='http://www.techjava.de/2010/ws4jee/measurement/types/' version='1.0' xmlns:tns='http://www.techjava.de/2010/ws4jee/measurement/types/' xmlns:xs='http://www.w3.org/2001/XMLSchema'&gt;
   &lt;xs:element name='measurement' type='tns:Measurement'/&gt;
   &lt;xs:element name='sensor-id' type='tns:sensor-id'/&gt;
   &lt;xs:element name='timespan' type='tns:TimeSpan'/&gt;
   &lt;xs:complexType name='sensor-id'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element name='sensorId' type='xs:long'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
   &lt;xs:complexType name='TimeSpan'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element minOccurs='0' name='start' type='xs:dateTime'/&gt;
     &lt;xs:element minOccurs='0' name='end' type='xs:dateTime'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
   &lt;xs:complexType name='Measurement'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element name='critical' type='xs:boolean'/&gt;
     &lt;xs:element minOccurs='0' name='sensorID' type='tns:sensor-id'/&gt;
     &lt;xs:element minOccurs='0' name='timestamp' type='xs:dateTime'/&gt;
     &lt;xs:element minOccurs='0' name='unit' type='xs:string'/&gt;
     &lt;xs:element minOccurs='0' name='value' type='xs:base64Binary'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
  &lt;/xs:schema&gt;
  &lt;xs:schema targetNamespace='http://www.techjava.de/2010/ws4jee/measurement/' version='1.0' xmlns:ns1='http://www.techjava.de/2010/ws4jee/measurement/types/' xmlns:tns='http://www.techjava.de/2010/ws4jee/measurement/' xmlns:xs='http://www.w3.org/2001/XMLSchema'&gt;
   &lt;xs:import namespace='http://www.techjava.de/2010/ws4jee/measurement/types/'/&gt;
   &lt;xs:element name='GetSensorDataOperation' type='tns:GetSensorDataOperation'/&gt;
   &lt;xs:element name='GetSensorDataOperationResponse' type='tns:GetSensorDataOperationResponse'/&gt;
   &lt;xs:element name='SensorDataOperationFault' type='tns:SensorDataOperationFault'/&gt;
   &lt;xs:complexType name='GetSensorDataOperation'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element minOccurs='0' ref='ns1:sensor-id'/&gt;
     &lt;xs:element minOccurs='0' ref='ns1:timespan'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
   &lt;xs:complexType name='GetSensorDataOperationResponse'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element maxOccurs='unbounded' minOccurs='0' ref='ns1:measurement'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
   &lt;xs:complexType name='SensorDataOperationFault'&gt;
    &lt;xs:sequence&gt;
     &lt;xs:element minOccurs='0' name='message' type='xs:string'/&gt;
    &lt;/xs:sequence&gt;
   &lt;/xs:complexType&gt;
  &lt;/xs:schema&gt;
 &lt;/types&gt;
 &lt;message name='MeasurementProviderPortType_GetSensorDataOperation'&gt;
  &lt;part element='tns:GetSensorDataOperation' name='GetSensorDataOperation'&gt;&lt;/part&gt;
 &lt;/message&gt;
 &lt;message name='SensorDataOperationFault'&gt;
  &lt;part element='tns:SensorDataOperationFault' name='SensorDataOperationFault'&gt;&lt;/part&gt;
 &lt;/message&gt;
 &lt;message name='MeasurementProviderPortType_GetSensorDataOperationResponse'&gt;
  &lt;part element='tns:GetSensorDataOperationResponse' name='GetSensorDataOperationResponse'&gt;&lt;/part&gt;
 &lt;/message&gt;
 &lt;portType name='MeasurementProviderPortType'&gt;
  &lt;operation name='GetSensorDataOperation' parameterOrder='GetSensorDataOperation'&gt;
   &lt;input message='tns:MeasurementProviderPortType_GetSensorDataOperation' /&gt;
   &lt;output message='tns:MeasurementProviderPortType_GetSensorDataOperationResponse' /&gt;
   &lt;fault message='tns:SensorDataOperationFault' name='SensorDataOperationFault' /&gt;
  &lt;/operation&gt;
 &lt;/portType&gt;
 &lt;binding name='MeasurementProviderPortTypeBinding' type='tns:MeasurementProviderPortType'&gt;
  &lt;soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/&gt;
  &lt;operation name='GetSensorDataOperation'&gt;
   &lt;soap:operation soapAction='http://www.techjava.de/2010/ws4jee/measurement//GetSensorDataOperation'/&gt;
   &lt;input&gt;&lt;soap:body use='literal'/&gt;&lt;/input&gt;
   &lt;output&gt;&lt;soap:body use='literal'/&gt;&lt;/output&gt;
   &lt;fault name='SensorDataOperationFault'&gt;&lt;soap:fault name='SensorDataOperationFault' use='literal'/&gt;&lt;/fault&gt;
  &lt;/operation&gt;
 &lt;/binding&gt;
 &lt;service name='MeasurementProviderService'&gt;
  &lt;port binding='tns:MeasurementProviderPortTypeBinding' name='MeasurementProviderPort'&gt;
   &lt;soap:address location='http://127.0.0.1:8080/de.techjava.ws4ee-de.techjava.ws4ee.sensor/MeasurementProviderFacadeBean'/&gt;
  &lt;/port&gt;
 &lt;/service&gt;
&lt;/definitions&gt;
</pre>
<p>Please note, that the domain datatypes are mapped to the different namespace as the target namespace of the Web Service.</p>
<p>After some tuning the WSDL, like changing the cardinality of elements (minOccurs = 1, maxOccurs = 1) or adding comments we can let the container use the changed WSDL file instead of generating a new one. In order to do this, let us package the WSDL together with the source code. A good place for it is for example <code>/META-INF/wsdl/</code>, so we can provide a reference to it in an <code>wsdlLocation</code>attribute of the <code>@WebService</code> annotation:</p>
<pre class="brush: java;">
@WebService(
...
        wsdlLocation=&quot;META-INF/wsdl/MeasurementProviderService.wsdl&quot;
)
</pre>
<h2>Putting all together</h2>
<p>After the creation of the Facade Bean and its exposure as a Web Service, we need to delegate the call to the SensorManagerBean, providing the actual implementation. In order to do so, add a private member of type <code>SensorManager</code> inside of the facade bean and annotate it with the <code>javax.ejb.EJB</code> annotation. The container will intialize the member using Dependency Injection and provide a valid reference which can be simply used inside of the method.</p>
<pre class="brush: java; highlight: [4,5,20];">
...
public class MeasurementProviderFacadeBean implements MeasurementProviderFacade
{
	@EJB(mappedName=&quot;de.techjava.sensor/SensorManager&quot;)
	private SensorManager sensorManager;

	/**
	 * Simple delegate to the business method of the sensor manager
	 */
	@WebMethod(
			operationName=&quot;GetSensorDataOperation&quot;,
			action=TNS + &quot;/GetSensorDataOperation&quot;
	)
	public @WebResult(name=&quot;measurement&quot;, targetNamespace=TYPES) List&lt;Measurement&gt; getSensorData(
			@WebParam(name=&quot;sensor-id&quot;, targetNamespace=TYPES) SensorID id,
			@WebParam(name=&quot;timespan&quot;, targetNamespace=TYPES) Timespan timespan) throws SensorDataOperationFault
	{
		try
		{
			return sensorManager.getSensorData(id, timespan);
		} catch (SensorManagerException e)
		{
			throw new SensorDataOperationFault(&quot;Error accessing the Sensor Manager: &quot; + e.getMessage() + &quot;&quot;);
		}
	}
}
</pre>
<p>Here is the call in Web Service Explorer:<br />

<a  href="http://www.techjava.de/wp-content/uploads/ws-explorer.png" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/ws-explorer.png');" ><img style="margin: 5px;" title="WS Explorer" src="http://www.techjava.de/wp-content/uploads/ws-explorer.png" alt="image WS Explorer" /></a></p>
<h2>Outline</h2>
<p>In this article we showed how to expose the functionality implemented in an EJB 3 Session Bean using Web Service Technology. In fact, the creation of a FacadeBean was not required since one could annotate the <code>SensorManager</code>-Bean directly, but we separated the implementation Bean from the exposing Bean to make it easier to understand. Even if we didn&#8217;t match the WSDL from the J2EE 1.4 example exactly, we came very close. Merely some message-related datatypes have different names. In this example we used the Document/Literal/Wrapped style of Web Services in order to gain maximum interoperability. Even though the creation of the Web Service is a simple task using the annotations. The number of tools and dependencies has dramataically reduced since J2EE 1.4 and the development became less error-prone. Together with other EJB3 improvements it makes the JEE framework suitable for development in the context of enterprise distributed systems.</p>
<h2>References and Resources</h2>
<p>The example source code is available for download (
<a  href="http://www.techjava.de/download/examples/ws4jee.zip" onclick="javascript:pageTracker._trackPageview('/downloads/download/examples/ws4jee.zip');" >ws4jee.zip</a>). Just import the projects from the archive into Eclipse Worskspace. Make sure to set up the JRE and JBoss Server instance for the projecst to work.</p>
<ul>
<li>
<div>[2008,techreport] 
<a  href="#JAVAEE" class="toggle">bibtex</a>  
<a  href='http://java.sun.com/javaee/5/docs/tutorial/doc/' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/java.sun.com/javaee/5/docs/tutorial/doc/');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>E. Jendrock, J. Ball, D. Carson, I. Evans, S. Fordin, and K. Haase, &quot;The Java EE 5 Tutorial,&quot; 2008.</div>
<div class="bibtex" id="JAVAEE">
         <code>@techreport{JAVAEE, <br />
 &nbsp;&nbsp;author =	{Eric Jendrock and Jennifer Ball and Debbie Carson and Ian Evans and Scott Fordin and Kim Haase}, <br />
 &nbsp; title =	{The Java EE 5 Tutorial}, <br />
 &nbsp; url = {http://java.sun.com/javaee/5/docs/tutorial/doc/}, <br />
 &nbsp; month =	{Oct}, <br />
 &nbsp; year =	{2008}<br />
}</code>
    </div>
</li>
<li>
<div>[2007,book] 
<a  href="#IHNS_2003" class="toggle">bibtex</a>  
<a  href='Oliver Ihns, Dierk Harbeck, Stefan M. Heldt, Holger Koschek, Roman Schlömmer, Jo Ehm, Carsten Sahling' title='Go to document'><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>O. Ihns, D. Harbeck, S. M. Heldt, H. Koschek, R. Schl&#5954405;r, J. Ehm, and C. Sahling, <em>EJB 3 professionell. Grundlagen- und Expertenwissen zu Enterprise JavaBeans 3 fr Einsteiger, Umsteiger und Fortgeschrittene , publisher	DPunkt Verlag</em>, , 2007.</div>
<div class="bibtex" id="IHNS_2003">
         <code>@Book{IHNS_2003, <br />
 &nbsp;&nbsp;author =	{Oliver Ihns and Dierk Harbeck and Stefan M. Heldt and Holger Koschek and Roman Schlömmer and Jo Ehm and Carsten Sahling}, <br />
 &nbsp; title =	{EJB 3 professionell. Grundlagen- und Expertenwissen zu Enterprise JavaBeans 3 für Einsteiger, Umsteiger und Fortgeschrittene }, <br />
 &nbsp; publisher	{DPunkt Verlag}, <br />
 &nbsp; year =	{2007}, <br />
 &nbsp; month =	{Jul}, <br />
 &nbsp; url = {Oliver Ihns, Dierk Harbeck, Stefan M. Heldt, Holger Koschek, Roman Schlömmer, Jo Ehm, Carsten Sahling}<br />
}</code>
    </div>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2010/01/functionality-web-services-jee/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Configuring JBoss Datasource for Firebird DB</title>
		<link>http://www.techjava.de/topics/2010/01/configuring-jboss-datasource-for-firebird-db/</link>
		<comments>http://www.techjava.de/topics/2010/01/configuring-jboss-datasource-for-firebird-db/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 00:33:17 +0000</pubDate>
		<dc:creator>shuron</dc:creator>
				<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[Datasource]]></category>
		<category><![CDATA[firebird]]></category>
		<category><![CDATA[jaybird]]></category>
		<category><![CDATA[jca]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[rar]]></category>
		<category><![CDATA[server-side]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=537</guid>
		<description><![CDATA[
Accessing a relational database system from Java is a basic step required for many applications. The JEE architecture defines a standard for gaining this access, calls Java Connector Architecture (JCA). This article is a short HOWTO of configuring JCA-compliant datasource to a Firebird 2.x RDBMs using JBoss AS 5.1.0 as example. This tutorial is based [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 5px; float:right;" title="FirebirdPhoenix_Logo" src="http://www.techjava.de/wp-content/uploads/FirebirdPhoenix_Logo-150x150.gif" alt="FirebirdPhoenix_Logo" width="150" height="150" /><br />
Accessing a relational database system from Java is a basic step required for many applications. The JEE architecture defines a standard for gaining this access, calls Java Connector Architecture (JCA). This article is a short HOWTO of configuring JCA-compliant datasource to a Firebird 2.x RDBMs using JBoss AS 5.1.0 as example. This tutorial is based on a Windows installation, but can be easily ported to Linux, or other OS.</p>
<p>For the configuration of the datasource two steps are required:</p>
<ul>
<li>Deployment of the Firebird RAR resource adapter (<code>jaybird-*.rar</code>)</li>
<li>Creation of the <code>firebird-ds.xml</code> configuration</li>
</ul>
<p><span id="more-537"></span></p>
<h2>RAR Resource Adapter</h2>
<p>The RAR Resource Adapter is a version of RDBMs drivers packaged in a special way, defined by the JCA specifcation. The<br />

<a  href="http://www.ibphoenix.com/main.nfs?page=ibp_download_jaybird" target="_blank" onclick="javascript:pageTracker._trackPageview('/external/www.ibphoenix.com/main.nfs');" >latest versions of Type 4 JCA-JDBC Firebird Driver</a> (JayBird) can be downloaded from the IBPhoenix site. Inside of the downloaded archive you will find <code>jaybird-*.rar</code> (The version used during the creation of this tutorial was jaybird-2.1.6.rar). Since deployment in JBoss AS is performed by simple file copy, make sure to put the RAR-adapter-file into the deployment location of the application server. (e.G. ${JBOSS_ROOT}\server\default\deploy\).</p>
<p>After deployment, you can check the status of the resource adapter, by looking on the Administration Console of the JBoss (by default accessing the server URL http://localhost:8080/admin-console/ if run locally).</p>
<h2>Datasource Description</h2>
<p>After a successful deployment of the Resource RAR, the configuration of the datasource has to be created. The Firebird datasource configuration is supplied in a file, located in the default deployment location. JBoss AS auto-deplyoer will automatically look for the  <code>*-ds.xml</code> files, so we name it e.G. <code>firebird-ds.xml</code>.</p>
<p>The following datasource configuration defines a local transactional datasource. You just need to replace placeholders USERNAME, PASSWORD and path to your database-file (In the used installation the file was located in: <code>c:\databses\tesdb.fdb</code>)</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

  &lt;!-- ==================================================================== --&gt;
  &lt;!-- New ConnectionManager setup for firebird dbs using jca-jdbc xa driver--&gt;
  &lt;!-- Build jmx-api (build/build.sh all) and view for config documentation --&gt;
  &lt;!-- ==================================================================== --&gt;

&lt;connection-factories&gt;
	&lt;local-tx-datasource&gt;
		&lt;jndi-name&gt;DataSourceFirebirdDS&lt;/jndi-name&gt;
		&lt;connection-url&gt;jdbc:firebirdsql:localhost/3050:c:${/}databses${/}tesdb.fdb&lt;/connection-url&gt;
		&lt;driver-class&gt;org.firebirdsql.jdbc.FBDriver&lt;/driver-class&gt;
		&lt;transaction-isolation&gt;TRANSACTION_REPEATABLE_READ&lt;/transaction-isolation&gt;
		&lt;connection-property name=&quot;lc_ctype&quot; type=&quot;java.lang.String&quot;&gt;ISO8859_1&lt;/connection-property&gt;
		&lt;connection-property name=&quot;maxStatements&quot;&gt;10&lt;/connection-property&gt;
		&lt;user-name&gt;USERNAME&lt;/user-name&gt;
		&lt;password&gt;PASSWORD&lt;/password&gt;
		&lt;min-pool-size&gt;0&lt;/min-pool-size&gt;
		&lt;max-pool-size&gt;10&lt;/max-pool-size&gt;

		&lt;blocking-timeout-millis&gt;5000&lt;/blocking-timeout-millis&gt;

		&lt;idle-timeout-minutes&gt;15&lt;/idle-timeout-minutes&gt;
		&lt;check-valid-connection-sql&gt;SELECT CAST(1 as INTEGER) FROM rdb$database&lt;/check-valid-connection-sql&gt;
		&lt;track-statements&gt;false&lt;/track-statements&gt;
		&lt;prepared-statement-cache-size&gt;0&lt;/prepared-statement-cache-size&gt;
		&lt;metadata&gt;
			&lt;type-mapping&gt;Firebird&lt;/type-mapping&gt;
		&lt;/metadata&gt;
	&lt;/local-tx-datasource&gt;
&lt;/connection-factories&gt;
</pre>
<h2>Usage</h2>
<p>The datasource in the example above is registered in the <code>java</code> JNDI namespace and is called <code>DataSourceFirebirdDS</code>. In the source code, this resource should be accessible via <code>java:/DataSourceFirebirdDS</code>. Here is the example using Dependency Injection (DI):</p>
<pre class="brush: java;">
@Ressource(mappedName = &quot;java:/DataSourceFirebirdDS&quot;)
private DataSource firebirdDataSource;
</pre>
<p>In order to use the datasource in a JPA, the persistence unit has to be configured. For example, for using Hibernate, the following persistence unit can be configured.</p>
<pre class="brush: xml;">
...
&lt;persistence-unit name=&quot;testunit&quot;&gt;
	&lt;jta-data-source&gt;java:/DataSourceFirebirdDS&lt;/jta-data-source&gt;
	&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
	...
	&lt;properties&gt;
		&lt;property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.FirebirdDialect&quot;/&gt;
		&lt;property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot; /&gt;
		...
	&lt;/properties&gt;
&lt;/persistence-unit&gt;
...
</pre>
<p>Then in the DAO for manipulation of Persistent Entities, the Persistence Context can be injected by:</p>
<pre class="brush: java;">
@Stateless
public class TestDAOBean implements TestDAO {

	@PersistenceContext(unitName = &quot;testunit&quot;)
	private EntityManager manager;

	...
}
</pre>
<p>Have fun and please provide some feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2010/01/configuring-jboss-datasource-for-firebird-db/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Multiple HTTP-Header values concatinating</title>
		<link>http://www.techjava.de/topics/2008/02/multi-http-header/</link>
		<comments>http://www.techjava.de/topics/2008/02/multi-http-header/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 15:02:36 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[multiple header]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://www.techjava.de/topics/2008/02/multi-http-header/</guid>
		<description><![CDATA[The specification part
We continued the search for the reason of error described in the 
previous post. After some search in HTTP Specification executed by 
Prof. Turau: &#8220;&#8230; Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a [...]]]></description>
			<content:encoded><![CDATA[<h2>The specification part</h2>
<p>We continued the search for the reason of error described in the 
<a  href="http://www.techjava.de/topics/2008/02/using-soap-on-nokia-6131-nfc/">previous post</a>. After some search in HTTP Specification executed by 
<a  href="http://www.ti5.tu-harburg.de/staff/Turau/Default.htm" onclick="javascript:pageTracker._trackPageview('/external/www.ti5.tu-harburg.de/staff/Turau/Default.htm');" >Prof. Turau</a>: &#8220;&#8230; Multiple message-header fields with the same field-name <strong>MAY</strong> be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]&#8230;&#8221;</p>
<p>For example Accept Header:<br />
Accept         = &#8220;Accept&#8221; &#8220;:&#8221; #( media-range [ accept-params ] ) </p>
<p>But not Content-Type Header:<br />
Content-Type   = &#8220;Content-Type&#8221; &#8220;:&#8221; media-type</p>
<h2>The server-side implementation</h2>
<p>Besides Nokia Bug, putting 
<a  href="http://www.techjava.de/topics/2008/02/using-soap-on-nokia-6131-nfc/">multiple Content-Type headers</a> in one request, there is an additional error server-side. I followed the JBoss call hierarchy which is:</p>
<pre class="brush: java;">
org.jboss.ws.server.StandardEndpointServlet#doPost(HttpServletRequest req, HttpServletResponse res);
org.jboss.ws.server.ServiceEndpointManager#processSOAPRequest();
new org.jboss.ws.server.ServletHeaderSource(HttpServletRequest req, HttpServletResponse res);
org.jboss.ws.server.ServiceEndpoint#handleRequest(HeaderSource headerSource, ServletEndpointContext context, InputStream inputStream);
org.jboss.ws.server.ServletHeaderSource#getMimeHeaders();
</pre>
<p>During the whole processing, the headers are retrieved from the <strong>HttpServletRequest</strong> by the <strong>ServletHeaderSource</strong> which is the only implementation of <strong>HeaderSource</strong>:</p>
<pre class="brush: java;">
public MimeHeaders getMimeHeaders()
{
    Enumeration e = req.getHeaderNames();
    if(e == null)
        return null;
    MimeHeaders headers = new MimeHeaders();
    String name = null;
    for(; e.hasMoreElements(); headers.addHeader(name, req.getHeader(name)))
        name = (String)e.nextElement();

    return headers;
}
</pre>
<p>Afterwards, if you call getHeader on the MimeHeaders object the string array is constructed from the existing data and returned:</p>
<pre class="brush: java;">
public String[] getHeader(String name)
{
    ArrayList tmp = new ArrayList();
    for(int n = 0; n &lt; headers.size(); n++)
    {
        MimeHeader mh = (MimeHeader)headers.get(n);
        if(mh.getName().equalsIgnoreCase(name))
            tmp.add(mh.getValue());
    }

    String values[] = null;
    if(tmp.size() &gt; 0)
    {
        values = new String[tmp.size()];
        tmp.toArray(values);
    }
    return values;
}
</pre>
<p>This means, that the implementation of the HttpServletRequest returns concatinated list of values for the duplicate headers.</p>
<h2>Specifications again</h2>
<p>Now, I looked in Java Servlet Specifications about the getHeader method:</p>
<h3>Servlet 2.1</h3>
<p>Returns the value of the requested header. The match between the given name and the request header is case-insensitive. If the header requested does not exist, this method returns null.</p>
<h3>Servlet 2.2</h3>
<p>The getHeader method allows access to the value of a header given the name of the header. Multiple headers, such as the Cache-Control header, can be present in an HTTP request. If there are multiple headers with the same name in a request, the getHeader method returns the first header contained in the request.</p>
<h3>Servlet 2.3 and 2.4</h3>
<p>The getHeader method returns a header given the name of the header. There can be multiple headers with the same name, e.g. Cache-Control headers, in an HTTP request. If there are multiple headers with the same name, the getHeader method returns the first head in the request. </p>
<h2>Results</h2>
<p>So it seems to be a Tomcat Bug, as long as Tomcat provides the implementation for the HttpServletRequest&#8230; This bug is integrated in JBoss, because they use Tomcat implementation. Never the less, JBoss use the getHeader method relies on the correct implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2008/02/multi-http-header/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exposing functionality using Web Services and J2EE 1.4</title>
		<link>http://www.techjava.de/topics/2008/02/ws4j2ee14/</link>
		<comments>http://www.techjava.de/topics/2008/02/ws4j2ee14/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 16:30:23 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[j2ee]]></category>
		<category><![CDATA[server-side]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://www.techjava.de/topics/2008/02/ws4j2ee14/</guid>
		<description><![CDATA[Abstract
In this article we describe how to implement a simple Web Service using old fashioned Java EE 1.4. The dummy functionality is implemented in Session Beans and exposed via document-literal Web Service following the recommendations of W3C and WS-I.
Introduction
Before we get in to technical details about the implementation a short overview of planned is helpful. [...]]]></description>
			<content:encoded><![CDATA[<h3>Abstract</h3>
<p>In this article we describe how to implement a simple Web Service using old fashioned Java EE 1.4. The dummy functionality is implemented in Session Beans and exposed via document-literal Web Service following the recommendations of W3C and WS-I.</p>
<h3>Introduction</h3>
<p>Before we get in to technical details about the implementation a short overview of planned is helpful. The main idea of this article is to show how a web service can be implemented using Java Enterprise Edition. Especially, this article tries to achieve two goals: show how existing EJB functionality can be exposed using Web Service technology and how Web Service technology can be linked to something stable, most of us have experience with. Many people follow the new trend of saying that EJB is ineffective and heavyweight &#8211; we don&#8217;t want to argue about this thesis. In this article we show a progmatic EJB development approach using &#8220;code-by-convention&#8221; combined with 
<a  href="http://www.generative-programming.org/" onclick="javascript:pageTracker._trackPageview('/external/www.generative-programming.org/');" >Generative-Programming</a> techniques. We develop the EJB functionality and Web Service definition independent from each other and link them later together &#8211; we are sure that this is the only approach to keep both parts simple, clean and reusable. During the WSDL design we follow a certain style of type and element selection, that results from some experiences of using generators and integration with non-Java environments. Our use case is a little synthetic in order to show the variety of types and seems to introduce structural complexity, which can be avoided. We implement the examples using open source products only.</p>
<p>The article starts with a short introduction which could look a little lyrical for some technicians of you. Then the requirements to the selected software are listed, followed by the practical use case. Then we jumpstart the EJB development cycle, design the Web Service and finally put both implementations together. In the outline, we discuss the testing possibilities&#8230;</p>
<h3>Requirements</h3>
<p>In order to develop, generate, package and finally deploy and run the component, exposing its functionality we need special software. Following selections has been made:</p>
<ul>
<li>Sun&#8217;s JDK (&gt; 1.4.2)</li>
<li>Apache Ant (&gt; 1.6.5)</li>
<li>XDoclet (1.2.3)</li>
<li>Sun&#8217;s Java Web Service Developer Pack (1.6)</li>
<li>JBoss AS (4.0.5 GA)</li>
<li>Eclipse IDE (&gt; 3.3), recommended WTP installation</li>
</ul>
<p>First of all we need to setup our environment. In order to make development under MS Windows convenient, we used to setup the entire environment variables in a single shell script:</p>
<pre class="brush: xml;">
@echo off
echo ----------------------------------------
echo Project Environment
echo ----------------------------------------
set DEVEL=c:\environment
set ANT_HOME=%DEVEL%\libraries\ant\1.6.5
set JAVA_HOME=%DEVEL%\compiler\j2sdk1.5.0_01
set JAVAC_EXEC=%DEVEL%\compiler\j2sdk1.5.0_01\bin\javac.exe
set JWSDP_HOME=%DEVEL%\compiler\jwsdp-1.6
set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%PATH%;%DEVEL%\bin;%JWSDP_HOME%\jaxrpc\bin
echo Environment variables:
echo ANT home : %ANT_HOME%
echo JAVA home : %JAVA_HOME%
echo PATH set to : echo %PATH%
echo ----------------------------------------
echo CLASSPATH set to : echo %CLASSPATH%
echo ----------------------------------------
cmd
</pre>
<p>For usage under Linux/MacOS the script should be adjusted correspondingly. </p>
<p>Eclipse is used as IDE for the whole development. In order to avoid any dependency to certain Eclipse functionalities we use Apache Ant as a build tool. In order to use the build tools these should be configured. In Preferences of Eclipse we set up Apache Ant and XDoclet. In <strong>Window -&gt; Preferences -&gt; Ant -&gt; Runtime </strong>set up the <strong>Ant Home </strong>pointing to the Ant installation directory. In <strong>Window -&gt; Preferences -&gt; XDoclet </strong>set up <strong>XDoclet Home</strong> to XDoclet installation directory and set the version to 1.2.3.</p>
<h3>Project Setup</h3>
<p>Even if we don&#8217;t want to rely on the build and shortcommings of Eclipse in the area of EJB development, we want to use maximum of support if possible.</p>
<p>Create a new <strong>EJB Project </strong>and select the following Project Facets: <strong>EJB Module 2.1</strong>, <strong>XDoclet 1.2.3</strong> and <strong>Java 1.4</strong>. We use the following project structure: all hand-written Java files go to /java/src directory, all Doclet-generated goes to /java/generated, the compiled files go to /java/class and the resulting archives (jars and ears) go to /java/build. The additional /metadata directory contains source and descriptor files needed for the project. To set all this up go to <strong>Project Properties -&gt; Java Build Path</strong>. As long as we control XDoclet from an Ant script, we deactivate the XDoclet Builder in <strong>Project Preferencies -&gt; XDoclet</strong> and in <strong>Project Preferences -&gt; Builders</strong>. Before we begin with the implementation we have to set up the Ant script, that will build and package our project. The script unifies different tools we use to a single toolchain and contains several targets. These are EJB-Doclet generation target, WS-Compile target, Web-Doclet target, target for compilation of the Java classes and, finally, creation of a JAR and EAR files. In order to hold the build file project independent we use properties files that contain project specific settings. In order to access XDoclet and WSCompile from Ant the corresponding task definitions must be included and the libraries must be put to directories in classpath. For this purpose we used to create a library project in the same workspace, containing the libraries (called <strong>general</strong>).</p>
<pre class="brush: xml;">
...
&lt;path id=&quot;class.path.local&quot;&gt;
  &lt;fileset dir=&quot;../general/lib&quot;&gt;
    &lt;include name=&quot;**/*.jar&quot;&gt;&lt;/include&gt;
    &lt;include name=&quot;**/*.zip&quot;&gt;&lt;/include&gt;
  &lt;/fileset&gt;
&lt;/path&gt;
&lt;path id=&quot;class.path.jwsdp&quot;&gt;
  &lt;path refid=&quot;class.path.local&quot;&gt;&lt;/path&gt;
&lt;/path&gt;
&lt;path id=&quot;class.path.doclet&quot;&gt;
  &lt;path refid=&quot;class.path.ant&quot;&gt;&lt;/path&gt;
&lt;/path&gt;
&lt;taskdef name=&quot;wscompile&quot; classname=&quot;com.sun.xml.rpc.tools.ant.Wscompile&quot; classpathref=&quot;class.path.jwsdp&quot;&gt;&lt;/taskdef&gt;
&lt;taskdef name=&quot;xdoclet&quot; classname=&quot;xdoclet.DocletTask&quot; classpathref=&quot;class.path.doclet&quot;&gt;&lt;/taskdef&gt;
&lt;taskdef name=&quot;ejbdoclet&quot; classname=&quot;xdoclet.modules.ejb.EjbDocletTask&quot; classpathref=&quot;class.path.doclet&quot;&gt;&lt;/taskdef&gt;
&lt;taskdef name=&quot;wseedoclet&quot; classname=&quot;xdoclet.modules.wsee.WseeDocletTask&quot; classpathref=&quot;class.path.doclet&quot;&gt;&lt;/taskdef&gt;
...
</pre>
<p>In order to demonstrate the implementation we introduce a use case. This is sonstructed for the demonstration purposes and shows the usage of different types.</p>
<h3>Use Case</h3>
<p>The constructed system is capable of providing the measurements of some sensors. The sensors are identified by numers and can be queried by the user by providing the timespan of measurements. As a result, the systems delivers the set of measurements for the given timespan with one measurement per minute but at most sixty measurements. Every measurement contain the id of sensor from which it has been recorded, the timestamp, the value as a byte array, the measurement unit and finally the flag if the measurement exceeds the expectation and has alarming values. </p>
<p>We start with typical EJB implementation and then adopt the resulting types to those, that should be used in a Web Service.</p>
<h3>First Session Bean powered by XDoclet</h3>
<p>Following the EJB 2.1 specification the stateless session bean class must implement the <strong>javax.ejb.SessionBean</strong> interface. We follow the 
<a  href="http://en.wikipedia.org/wiki/Adapter_pattern" onclick="javascript:pageTracker._trackPageview('/external/en.wikipedia.org/wiki/Adapter_pattern');" >Class Adapter design pattern</a> and create an abstract session bean that serves as a super class of all session beans.</p>
<pre class="brush: java;">
public abstract class AbstractSessionBean implements SessionBean
{
	/** Logging facility */
	protected static Logger LOG = Logger.getLogger(AbstractSessionBean.class);
	/** Session context */
	protected SessionContext	sessionContext;

	/**
	 * @see javax.ejb.SessionBean#ejbActivate()
	 */
	public void ejbActivate() throws EJBException, RemoteException
	{
	}

	/**
	 * @see javax.ejb.SessionBean#ejbPassivate()
	 */
	public void ejbPassivate() throws EJBException, RemoteException
	{
	}

	/**
	 * @see javax.ejb.SessionBean#ejbRemove()
	 */
	public void ejbRemove() throws EJBException, RemoteException
	{
	}

	/**
	 * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
	 */
	public void setSessionContext(SessionContext sessionContext) throws EJBException, RemoteException
	{
		this.sessionContext = sessionContext;
	}
}
</pre>
<p>Using such an adapter we can avoid code repetition in functional session beans. It could be also a good idea to put the logging facility into this abstract class. Any functional bean extends AbstractSessionBean and overwrites the ejbCreate() method which is used to setup the working copy of a Bean. Mostly, references to other beans are initialized in this method. Due to the usage of XDoclet, we follow the Factory pattern implemented in the EJB-Util class, which simplifies access to other EJBs.</p>
<p>In our example we flatten the exception handling to the minimum and introduce one exception class for every functional bean, which is thrown by any error during processing. Therefore, any functional methods throw this exception. Usually, exceptions should be topic-related instead of being bean-related.</p>
<p>Information needed for XDoclet generation is stored in the corresponding XDoclet tags inside of the JavaDoc comments. For the full list of XDoclet tag please refer to the 
<a  href="http://xdoclet.sf.net/" target="_blank" onclick="javascript:pageTracker._trackPageview('/external/xdoclet.sf.net/');" >XDoclet site</a>. We only explain the tags, we use. The <strong>ejb.bean</strong> tag indicates that a class is an EJB, providing a <strong>name</strong>, <strong>display-name</strong>, <strong>description</strong> as well as JNDI-Names of LocalHome interface and of the bean itself. The visibility is controlled over the <strong>view-type</strong> tag, the transactionality over <strong>transaction-type</strong> tag. Every business method we want to be included to business interfaces (Remote or Local) should be tagged with <strong>ejb.interface-method</strong> with corresponding <strong>view-type</strong>. Using this simple rule set we can easily implement business logic layer based on the stateless session beans:</p>
<pre class="brush: java;">
/**
 * ...
 * @ejb.bean name=&quot;SensorManager&quot;
 *  description=&quot;A Bean responsible for sensor operations&quot;
 *  display-name=&quot;SensorManagerBean&quot;
 *  jndi-name=&quot;techjava/SensorManagerrBean&quot;
 *  local-jndi-name=&quot;techjava/SensorManagerLocalHome&quot;
 *  type=&quot;Stateless&quot;
 *  transaction-type=&quot;Container&quot;
 *  view-type=&quot;both&quot;
 * ...
 */
public class SensorManagerBean extends AbstractSessionBean
{

	/**
	 * Max number of returned values
	 */
	private static final long MAX_DURATION = 60;

	/**
	 * Retrieves data from sensors
	 * @param sensorId id of sensor to query
	 * @param timespanStart start of the time period
	 * @param timespanEnd end of the time period
	 * @return a collection of Measurement POJOs or an empty collection
	 * @throws SensorManagerException if something goes wrong
	 * @ejb.interface-method view-type=&quot;both&quot;
	 */
	public Collection getSensorData(Long sensorId, Date timespanStart, Date timespanEnd)
          throws SensorManagerException
	{
		Collection ret = new Vector();
		LOG.debug(&quot;Entering getSensorData()&quot;);
		if (sensorId == null || timespanStart == null || timespanEnd == null)
		{
			throw new SensorManagerException(&quot;Missing a mandatory parameter, that was null (not set)&quot;);
		} else if (!timespanStart.before(timespanEnd)) {
			throw new SensorManagerException(&quot;The timespan is defined by the start that should be before end&quot;);
		}

		for (long i = 0; i &lt; getNumberOfElements(timespanStart, timespanEnd); i++)
		{
			Date date = new Date(timespanStart.getTime() + i*1000*60);
			if (date.after(timespanEnd))
			{
				break;
			}

			Measurement measurement = createMeasurement(sensorId, date, i);
			ret.add(measurement);
		}

		LOG.debug(&quot;Leaving getSensorData(). Returning &quot; + ret.size() +&quot; values&quot;);
		return ret;
	}

        /**
	 * retrieves the number of measurements in timespan
	 * @param timespanStart
	 * @param timespanEnd
	 * @return
	 */
	public long getNumberOfElements(Date timespanStart, Date timespanEnd) {	... }

	/**
	 * Creates a measurement instance
	 * @param sensorId
	 * @param timestamp
	 * @param number
	 * @return
	 */
	public Measurement createMeasurement(Long sensorId, Date timestamp, long number) { ... }
}
</pre>
<p>In order to generate the artifacts required by the specification from the written bean, we need to call a corresponding EJBDoclet task. The task itself is configuring only main generation options, during the subtasks are invoked for artifact generation. We used to separate classes of different purpose by packages and massively use the <strong>packageSubstitution</strong> subtask for this purpose. Remote, local, local home and remote home interfaces, util factory class and both EJB and a vendor-specific descriptors are generated using corresponding tasks.</p>
<pre class="brush: xml;">
&lt;ejbdoclet destdir=&quot;${ejb.distdir}&quot; verbose=&quot;true&quot; ejbspec=&quot;2.1&quot;&gt;
	&lt;fileset dir=&quot;${ejb.srcdir}&quot;&gt;
		&lt;include name=&quot;${ejb.include}&quot; /&gt;
	&lt;/fileset&gt;
	&lt;fileset dir=&quot;${ejb.distdir}&quot;&gt;
		&lt;include name=&quot;${ejb.include}&quot; /&gt;
	&lt;/fileset&gt;
	&lt;packageSubstitution packages=&quot;ejb.entity&quot; substituteWith=&quot;interfaces.entity&quot; /&gt;
	&lt;packageSubstitution packages=&quot;ejb.session&quot; substituteWith=&quot;interfaces.session&quot; /&gt;
	&lt;packageSubstitution packages=&quot;ejb.facade&quot; substituteWith=&quot;interfaces.facade&quot; /&gt;

	&lt;remoteinterface pattern=&quot;{0}Remote&quot; /&gt;
	&lt;localinterface pattern=&quot;{0}Local&quot; /&gt;
	&lt;homeinterface pattern=&quot;{0}Home&quot; /&gt;
	&lt;localhomeinterface pattern=&quot;{0}LocalHome&quot; /&gt;

	&lt;utilobject kind=&quot;physical&quot;&gt;
		&lt;packageSubstitution packages=&quot;ejb.session&quot; substituteWith=&quot;util.session&quot; /&gt;
		&lt;packageSubstitution packages=&quot;ejb.facade&quot; substituteWith=&quot;util.facade&quot; /&gt;
	&lt;/utilobject&gt;

	&lt;deploymentdescriptor
               destdir=&quot;${ejb.descriptor.distdir}&quot;
               displayname=&quot;${ejb.modulename}&quot;
               description=&quot;EJB Module ${ejb.modulename}&quot;
        /&gt;

	&lt;jboss
		destdir=&quot;${ejb.descriptor.distdir}&quot;
		version=&quot;4.0&quot;
		mergedir=&quot;metadata/merge&quot;
	/&gt;
&lt;/ejbdoclet&gt;
</pre>
<p>After generation of the classes and descriptors, which will be executed in a separate directory, it is a good idea to copy the descriptors back to the primary source folder, in order to allow for Eclipse to work with generated descriptors. Now we can compile the hand written code, together with generated code, put the results in a Java archive and assembly it to an enterprise archive, which can be deployed on an application server.</p>
<h3>Hands on the Web Service Definition</h3>
<p>The design of the interface definition is in general one of the most important steps in the component development life cycle. Depending on the quality of the interface design the component becomes reuseable or remains in usage only in the application it was initially built for. Therefore, we rely on a human engineering instead of generation.</p>
<p>For the definition of our Web Service, we use a standard language for this purpose, the WSDL. A WSDL file has a following structure:</p>
<ul>
<li>Types</li>
<li>Messages</li>
<li>Operations</li>
<li>Port Type</li>
<li>Bindings</li>
<li>Services</li>
</ul>
<p>As long as we intend to use document-literal, SOAP-style Web Services, the Binding and the Service parts are straight forward. The only thing we should pay attention is the Fault definition. We start from the Port Type definition, which is the equivalence of the business interface. A Port Type has a name and a collection of operation definitions, containing references to incoming, outgoing and fault messages. The Message part defines how XML Schema Types are used in the operations. This means that the most important parts of the WSDL file are the introduced Types, which are defined using XML Schema and the Port Types, which defines Operations, which use the Types.</p>
<p>The main purpose of a WSDL file is to define an interface. In order to distinguish it from the others, the interface is named. As long as WSDL defines a web-accessible resource, we use full qualified names, similar to XML target namespace.</p>
<pre class="brush: xml;">
&lt;wsdl:definitions name=&quot;MeasurementProvider&quot;
	targetNamespace=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/&quot;
	xmlns:tns=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/&quot;
	xmlns:types=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/types/&quot;
	xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;
	xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
	xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
	&lt;wsdl:types&gt;
		&lt;xsd:schema
			targetNamespace=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/types/&quot;
			xmlns:types=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/types/&quot;
			elementFormDefault=&quot;qualified&quot;
		&gt;
			&lt;!--
				ID element for sensor
			--&gt;
			&lt;xsd:simpleType name=&quot;sensor-id&quot;&gt;
				&lt;xsd:restriction base=&quot;xsd:long&quot; /&gt;
			&lt;/xsd:simpleType&gt;
			&lt;!--
				Measurement complex type
			 --&gt;
			&lt;xsd:complexType name=&quot;Measurement&quot;&gt;
				&lt;xsd:sequence&gt;
					&lt;xsd:element name=&quot;sensorid&quot; type=&quot;types:sensor-id&quot; /&gt;
					&lt;xsd:element name=&quot;timestamp&quot; type=&quot;xsd:dateTime&quot; /&gt;
					&lt;xsd:element name=&quot;critical&quot; type=&quot;xsd:boolean&quot; /&gt;
					&lt;xsd:element name=&quot;value&quot; type=&quot;xsd:base64Binary&quot; /&gt;
					&lt;xsd:element name=&quot;unit&quot; type=&quot;xsd:string&quot; /&gt;
				&lt;/xsd:sequence&gt;
			&lt;/xsd:complexType&gt;

			&lt;!--
				Timespan complex type
			 --&gt;
			&lt;xsd:complexType name=&quot;Timespan&quot;&gt;
				&lt;xsd:sequence&gt;
					&lt;xsd:element name=&quot;start&quot; type=&quot;xsd:dateTime&quot;
						minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; /&gt;
					&lt;xsd:element name=&quot;end&quot; type=&quot;xsd:dateTime&quot;
						minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; /&gt;
				&lt;/xsd:sequence&gt;
			&lt;/xsd:complexType&gt;

			&lt;!--
				Operation Types
			--&gt;
			&lt;xsd:element name=&quot;GetSensorData&quot;&gt;
				&lt;xsd:complexType&gt;
					&lt;xsd:sequence&gt;
						&lt;xsd:element name=&quot;sensorid&quot; type=&quot;types:sensor-id&quot;
							minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; /&gt;
						&lt;xsd:element name=&quot;timespan&quot; type=&quot;types:Timespan&quot;
							minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; /&gt;
					&lt;/xsd:sequence&gt;
				&lt;/xsd:complexType&gt;
			&lt;/xsd:element&gt;

			&lt;xsd:element name=&quot;GetSensorDataResponse&quot;&gt;
				&lt;xsd:complexType&gt;
					&lt;xsd:sequence&gt;
						&lt;xsd:element name=&quot;measurements&quot; type=&quot;types:Measurement&quot;
							maxOccurs=&quot;unbounded&quot; /&gt;
					&lt;/xsd:sequence&gt;
				&lt;/xsd:complexType&gt;
			&lt;/xsd:element&gt;
			&lt;xsd:element name=&quot;GetSensorDataFault&quot;&gt;
				&lt;xsd:complexType&gt;
					&lt;xsd:sequence minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;
						&lt;xsd:element name=&quot;reason&quot; type=&quot;xsd:string&quot;
							minOccurs=&quot;0&quot; maxOccurs=&quot;1&quot; /&gt;
					&lt;/xsd:sequence&gt;
				&lt;/xsd:complexType&gt;
			&lt;/xsd:element&gt;

		&lt;/xsd:schema&gt;
	&lt;/wsdl:types&gt;
...
	&lt;!--
		Port Type (interface declaration)
	--&gt;
	&lt;wsdl:portType name=&quot;MeasurementProviderPortType&quot;&gt;
		&lt;wsdl:operation name=&quot;GetSensorData&quot;&gt;
			&lt;wsdl:input message=&quot;tns:GetSensorDataRequest&quot; /&gt;
			&lt;wsdl:output message=&quot;tns:GetSensorDataResponse&quot; /&gt;
			&lt;wsdl:fault message=&quot;tns:GetSensorDataFaultMessage&quot;
				name=&quot;GetSensorDataFault&quot; /&gt;
		&lt;/wsdl:operation&gt;
	&lt;/wsdl:portType&gt;
...
&lt;/wsdl:definitions&gt;
</pre>
<h3>Web Service Implementation</h3>
<p>The created WSDL file is used for further Java code generation. For this purpose we use WSCompile, a tool supplied with Sun&#8217;s Java Web Service Developer Pack. The tool need a configuration file (<strong>wsdl-config.xml</strong>) storing the location of the WSDL file and namespace-to-package mappings. As a result of its execution, the tool generate Java classes for every custom type defined in XML Schema and the descriptor for JAX-RPC mapping required by the container for serialization and deserialization. In addition, it creates a Service interface, that is a interface to the factory of generated Port Type interfaces. The tool also generate implementation stubs for every Port Type, which can be ignored. </p>
<pre class="brush: xml;">
&lt;configuration xmlns=&quot;http://java.sun.com/xml/ns/jax-rpc/ri/config&quot;&gt;
	&lt;wsdl
	    location=&quot;./metadata/MeasurementProviderService.wsdl&quot;
	    packageName=&quot;de.techjava.sensor.interfaces.stubs&quot;
	&gt;
	     &lt;namespaceMappingRegistry&gt;
            &lt;namespaceMapping
            	namespace=&quot;http://www.techjava.de/2008/ws4j2ee14/measurement/types/&quot;
            	packageName=&quot;de.techjava.sensor.valueobjects&quot;
            /&gt;
	     &lt;/namespaceMappingRegistry&gt;
	&lt;/wsdl&gt;
&lt;/configuration&gt;
</pre>
<p>The WS Compile is usually called from the command line, but we use the Ant Task for this. Important are the features passed to the generator: <strong>documentliteral</strong>, <strong>wsi</strong>, <strong>searchschema</strong>, <strong>serializeinterfaces</strong> and <strong>explicitcontext</strong>. The path to the generated JAX-RPC mapping file is provided by the <strong>mapping</strong> attribute. Pay attention on the tool call, because depending on parameters given it generates Java classes from WSDL or vice versa.</p>
<pre class="brush: xml;">
&lt;wscompile fork=&quot;true&quot; import=&quot;true&quot; base=&quot;java/class&quot;
	sourceBase=&quot;java/generated&quot; verbose=&quot;true&quot;
	features=&quot;documentliteral, wsi, searchschema, serializeinterfaces, explicitcontext&quot;
	mapping=&quot;java/generated/META-INF/jaxrpc-mapping.xml&quot;
	config=&quot;metadata/wsdl-config.xml&quot;
	xSerializable=&quot;true&quot;
&gt;
	&lt;classpath&gt;
		&lt;path refid=&quot;class.path.local&quot; /&gt;
		&lt;path refid=&quot;class.path.ant&quot; /&gt;
		&lt;pathelement path=&quot;${java.class.path}&quot; /&gt;
	&lt;/classpath&gt;
&lt;/wscompile&gt;
</pre>
<p>After we generated the Java representation of the Web Service interface, we can integrate it with our EJB implementation. In order to do this, we used to create a 
<a  href="http://en.wikipedia.org/wiki/Fa%C3%A7ade_pattern" onclick="javascript:pageTracker._trackPageview('/external/en.wikipedia.org/wiki/Fa%C3%A7ade_pattern');" >Facade</a> session bean, that implements the Port Type interface. The methods of the facade bean provide some parameter validation, form the values needed for the calculations, invoke the corresponding EJBs, receive results or exceptions and, finally, form the response object or fault. The XDoclet annotation of the facade bean follows the one discussed above, but differs from it slightly. The <strong>view-type</strong> attribute of the <strong>ejb.bean</strong> tag should hold the value <strong>remote-service-endpoint</strong>. In addition, the <strong>ejb.interface</strong> tag provide information about the Java Port Type interface and about the special Endpoint interface, that is required for the container. In order to generate the Endpoint interface, we add the <strong>service-endpoint</strong> subtask to the ejbdoclet task.</p>
<pre class="brush: java;">
...
/**
 * @ejb.interface
 *  service-endpoint-class=&quot;de.techjava.sensor.interfaces.session.MeasurementProviderFacadeConnectorEndpoint&quot;
 *  service-endpoint-extends=&quot;de.techjava.sensor.interfaces.stubs.MeasurementProviderPortType&quot;
 * @wsee.port-component
 * 	name=&quot;MeasurementProviderService&quot;
 * 	local-part=&quot;MeasurementProviderService&quot;
 * 	display-name=&quot;MeasurementProviderService&quot;
 * 	description=&quot;MeasurementProvider Bean exposed as a web service&quot;
 */
public class MeasurementProviderFacadeBean
	extends AbstractSessionBean
	implements MeasurementProviderPortType
{
	private SensorManagerLocal sensorManagerLocal = null;

	/**
	 * Creates a link to SensorManager
	 * @see de.techjava.sensor.ejb.session.AbstractSessionBean#ejbCreate()
	 */
	public void ejbCreate()
		throws EJBException
	{
		try
		{
			sensorManagerLocal = SensorManagerUtil.getLocalHome().create();
		} catch (CreateException e)
		{
			throw new EJBException(&quot;Error creating new Session Manager instance&quot;);
		} catch (NamingException e)
		{
			throw new EJBException(&quot;Session Manager Local Home could not be found in JNDI&quot;);
		}
	}

	/**
         * Method called on web service message receipt
	 * @ejb.interface-method view-type=&quot;remote-service-endpoint&quot;
	 */
	public GetSensorDataResponse getSensorData(GetSensorData parameters)
		throws GetSensorDataFault
	{
		LOG.debug(&quot;Received a web service request getSensorData()&quot;);
		if (parameters == null
                  || parameters.getTimespan() == null
                  || parameters.getTimespan().getEnd() == null
                  || parameters.getTimespan().getStart() == null)
		{
			LOG.debug(&quot;Leaving getSensorData() with error&quot;);
			throw new GetSensorDataFault(&quot;Wrong request, check mandatory parameters&quot;);
		}
		if (sensorManagerLocal == null)
		{
			LOG.debug(&quot;Leaving getSensorData() with error&quot;);
			throw new GetSensorDataFault(&quot;Sensor Manager is not available&quot;);
		}

		Long sensorId = new Long(parameters.getSensorid());
		Date timespanStart = parameters.getTimespan().getStart().getTime();
		Date timespanEnd = parameters.getTimespan().getEnd().getTime();

		try
		{
			Collection simpleMeasurements = sensorManagerLocal.getSensorData(sensorId, timespanStart, timespanEnd);
			Vector measurements = new Vector(simpleMeasurements.size());
			Iterator simpleMeasurementI = simpleMeasurements.iterator();

			// convert types from EJB to generated XSD representations
			while(simpleMeasurementI.hasNext())
			{
				SimpleMeasurement sm = (SimpleMeasurement) simpleMeasurementI.next();
				Measurement measurement = convertMeasurement(sm);
				measurements.add(measurement);
			}

			GetSensorDataResponse response = new GetSensorDataResponse();
			response.setMeasurements((Measurement[]) measurements.toArray(new Measurement[measurements.size()]));
			LOG.debug(&quot;Leaving getSensorData().&quot;);
			return response;

		} catch (SensorManagerException e)
		{
			LOG.debug(&quot;Leaving getSensorData() with error&quot;);
			throw new GetSensorDataFault(e.getMessage());
		}
	}

}
</pre>
<p>In addition, the special J2EE Web Service descriptor webservices.xml needs to be created. For this purpose we use WSEE-Doclet, that introduces its own tags. The <strong>wsee-port-component</strong> provides display-name, web-service-description-name and port-component-name in the attributes <strong>name</strong>, <strong>local-part</strong> and <strong>display-name</strong>. The WSEE-Doclet is started from an Ant task and has one subtask <strong>wsee-deploymentdescriptor</strong> which is used to generate the required webservice.xml file.</p>
<pre class="brush: xml;">
...
&lt;wseedoclet destDir=&quot;${ejb.descriptor.distdir}&quot; jaxrpcMappingFile=&quot;jaxrpc-mapping.xml&quot; wseeSpec=&quot;1.1&quot; force=&quot;true&quot; verbose=&quot;true&quot;&gt;
	&lt;fileset dir=&quot;${ejb.srcdir}&quot;&gt;
		&lt;include name=&quot;**/*.java&quot; /&gt;
	&lt;/fileset&gt;
	&lt;wsee-deploymentdescriptor /&gt;
&lt;/wseedoclet&gt;
...
</pre>
<h3>Outline</h3>
<p>For testing of Web Services is an important step of development. Especially, the resulting SOAP messages should be reviewed at least once, to ensure that the  description is completed correctly, and no malformed XML structures are used. In order to play around with fresh-deployed Web Service open a browser of you choice and enter the URL of  the web service overview of your application server. If JBoss (>4.0.5) runs locally, this will be http://localhost:8080/jbossws/. You should see a list of deployed web services. By clicking on a wsdl-button you can retrieve the version of WSDL after deployment (containing the target URL of the endpoint interface). Using this WSDL you can run tests of your web service. We use Eclipse&#8217;s Web Service Explorer to run developer tests (WTP installation needed). You can access it under <strong>Run -> Launch the Web Service Explorer</strong>. Switsch to <strong>WSDL-Page</strong> by clicking on the second button from right, in the upper right corner, enter the URL and hit <strong>Go</strong>. Fill the form generated for each method, send the request and analsye the response. If you want to create more advanced tests (and test suites) please refer to 
<a  href="http://www.soapui.com/" onclick="javascript:pageTracker._trackPageview('/external/www.soapui.com/');" >SOAP-UI Project</a>.<br />
<img src="http://www.techjava.de/wp-content/uploads/WS4J2EE14/wsexplorer.png" alt="Eclipse's Web Service Explorer" /></p>
<h3>Resources</h3>
<p>You can download the zip file (
<a  href="http://www.techjava.de/wp-content/uploads/WS4J2EE14/detechjavaws4j2ee14sensor_20080219_src.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/WS4J2EE14/detechjavaws4j2ee14sensor_20080219_src.zip');" >de.techjava.ws4j2ee14.sensor_20080219_src.zip</a>) containing the example above. </p>
<h3>References</h3>
<ul>
<li>
<div>[2004,techreport] 
<a  href="#SUN_2004_JWSTUTORIAL" class="toggle">bibtex</a>  
<a  href='http://java.sun.com/webservices/docs/1.4/tutorial/doc/index.html' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/java.sun.com/webservices/docs/1.4/tutorial/doc/index.html');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>S. Microsystems, &quot;The Java Web Services Tutorial,&quot; 2004.</div>
<div class="bibtex" id="SUN_2004_JWSTUTORIAL">
         <code>@techreport{SUN_2004_JWSTUTORIAL, <br />
 &nbsp;&nbsp;author =	{Sun Microsystems}, <br />
 &nbsp; title =	{The Java Web Services Tutorial}, <br />
 &nbsp; month =	Jun, year =	{2004}, <br />
 &nbsp; url = {http://java.sun.com/webservices/docs/1.4/tutorial/doc/index.html}<br />
}</code>
    </div>
</li>
<li>
<div>[2003,book] 
<a  href="#IHNS_2003" class="toggle">bibtex</a>  
<a  href='http://www.ejbkomplett.de/' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/www.ejbkomplett.de/');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>O. Ihns, S. M. Heldt, R. Wirdemann, and H. Zuzmann, <em>Enterprise JavaBeans komplett, publisher	Oldenburg</em>, , 2003.</div>
<div class="bibtex" id="IHNS_2003">
         <code>@Book{IHNS_2003, <br />
 &nbsp;&nbsp;author =	{Oliver Ihns and Stefan M. Heldt and Ralf Wirdemann and Henning Zuzmann}, <br />
 &nbsp; title =	{Enterprise JavaBeans komplett}, <br />
 &nbsp; publisher	{Oldenburg}, <br />
 &nbsp; year =	{2003}, <br />
 &nbsp; month =	{Oct}, <br />
 &nbsp; url = {http://www.ejbkomplett.de/}<br />
}</code>
    </div>
</li>
<li>
<div>[2000,book] 
<a  href="#CZARNECKI_2003" class="toggle">bibtex</a> </div>
<div>K. Czarnecki and U. W. Eisenecker, <em>Generative Programming, publisher	Addison-Wesley</em>, , 2000.</div>
<div class="bibtex" id="CZARNECKI_2003">
         <code>@Book{CZARNECKI_2003, <br />
 &nbsp;&nbsp;author =	{Krzysztof Czarnecki and Ulrich W. Eisenecker}, <br />
 &nbsp; title =	{Generative Programming}, <br />
 &nbsp; publisher	{Addison-Wesley}, <br />
 &nbsp; year =	{2000}, <br />
 &nbsp; month =	{May}, <br />
 &nbsp; }</code>
    </div>
</li>
<li>
<div>[1994,book] 
<a  href="#GAMMA_1994" class="toggle">bibtex</a> </div>
<div>E. Gamma, R. Helm, R. Johnson, and J. Vlissides, <em>Design Patterns: Elements of Reusable Object-Oriented Software</em>, , 1994.</div>
<div class="bibtex" id="GAMMA_1994">
         <code>@Book{GAMMA_1994, <br />
 &nbsp;&nbsp;author = {Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides}, <br />
 &nbsp; title = {Design Patterns: Elements of Reusable Object-Oriented Software}, <br />
 &nbsp; year = {1994}<br />
}</code>
    </div>
</li>
<li>
<div>[,techreport] 
<a  href="#XDOCLET" class="toggle">bibtex</a>  
<a  href='http://xdoclet.sourceforge.net/xdoclet/index.html' title='Go to document' onclick="javascript:pageTracker._trackPageview('/external/xdoclet.sourceforge.net/xdoclet/index.html');" ><img src='http://www.techjava.de/wp-content/plugins/bib2html/external.png' width='10' height='10' alt='Go to document' /></a></div>
<div>&quot;XDoclet Project,&quot;.</div>
<div class="bibtex" id="XDOCLET">
         <code>@techreport{XDOCLET, <br />
 &nbsp;&nbsp;author =	{}, <br />
 &nbsp; title =	{XDoclet Project}, <br />
 &nbsp; url = {http://xdoclet.sourceforge.net/xdoclet/index.html}<br />
}</code>
    </div>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2008/02/ws4j2ee14/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JBoss: avoid session loss on redeploy</title>
		<link>http://www.techjava.de/topics/2005/09/jboss-avoids-session-lost-on-redeploy/</link>
		<comments>http://www.techjava.de/topics/2005/09/jboss-avoids-session-lost-on-redeploy/#comments</comments>
		<pubDate>Thu, 29 Sep 2005 02:45:58 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[server-side]]></category>

		<guid isPermaLink="false">http://www.techjava.de/topics/2005/09/jboss-avoids-session-lost-on-redeploy/</guid>
		<description><![CDATA[I&#8217;ll test the feature of JBoss described 
here.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll test the feature of JBoss described 
<a  href="http://members.capmac.org/~orb/blog.cgi/tech/java/Redeploy_web_apps_w.writeback" onclick="javascript:pageTracker._trackPageview('/external/members.capmac.org/~orb/blog.cgi/tech/java/Redeploy_web_apps_w.writeback');" >here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2005/09/jboss-avoids-session-lost-on-redeploy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
