JBoss 3.2.7 Document/Literal Web Service Tutorial

Back to Web Services Resources and Tutorials

Setting Up Your Environment

In addition to JBoss 3.2.7 and Java 1.4, you will need Ant. Links are below. The versions may differ by the time you see this; results are not expected to vary, but the version numbers are provided here as a record of what versions were used during the production of this tutorial:

After installing these packages, prepend the bin directories of the Ant and J2SE packages to your path, and verify that the "all" configuration of your JBoss server starts correctly. Note: Ant isn't strictly necessary to step through this tutorial, but in production you will want to transfer the manual steps into an Ant build file. To simplify command lines, now would be a good time to set the classpath you'll use for compiling the web service. A Windows example is shown here:
set JBOSS_HOME=C:/jboss-3.2.7
set JBOSS_LIB=%JBOSS_HOME%/lib
set JBOSS_SERVER_LIB=%JBOSS_HOME%/server/all/lib
set JBOSS_WS_LIB=%JBOSS_HOME%/server/all/deploy/jboss-net.sar
set CP=%JBOSS_WS_LIB%/axis-ws4ee.jar;%JBOSS_WS_LIB%/wsdl4j.jar;%JBOSS_SERVER_LIB%/jboss-saaj.jar;%JBOSS_SERVER_LIB%/jboss-jaxrpc.jar;%JBOSS_LIB%/jboss-common.jar;%JBOSS_WS_LIB%/commons-discovery.jar;%JBOSS_WS_LIB%/commons-logging.jar

Back to Top

Starting with a WSDL File

As was mentioned in the introduction to this tutorial, we will emphasize interoperability and the use of the WSDL file as the starting point. Create a directory to hold this project and create a subdirectory called wsdl. For this tutorial, the project directory is called tutorial. Within the wsdl directory, create a file called tutorial.wsdl.

A simple example WSDL file for this tutorial can be found here. This isn't a WSDL tutorial, so the details of the file won't be discussed here, other than to note that the portType defines a single operation, "PingRequest", the style is "document" and the use attribute is "literal". The WS-I Basic Profile 1.1 restricts style/use values to RPC/Literal and Document/Literal, while .NET tools (as of this writing) do not support RPC/Literal, so Document/Literal appears to be the best choice for interoperability.

Back to Top

Generating a Simple Service

In JBoss 3.2.7, the recommended tool to use for web service generation is the WSDL2Java tool from the Apache Axis. To ensure compatibility with the JBoss distribution, you should use the version of WSDL2Java contained in JBoss, rather than from a download of Axis. This tool is found in the axis-ws4ee.jar file in the deploy/jboss-ws4ee.sar directory of your JBoss 3.2.7 "all" server configuration.

Here we will use WSDL2Java to generated server-side artifacts (tie, or skeleton, plus beans for the WSDL schema types. First, under the top-level directory of your tutorial, create the following directories:

and copy your WSDL file into the wsdl directory (this is your backup) and into the wsr/wsdl directory. The wsr directory holds the files to be packaged into the web service, which in JBoss 3.2.7 is deployed as a .wsr file. The root directory of the .class files for the web service will be the top-level directory of the .wsr file; in this case, the wsr directory.

From the top-level tutorial directory, execute the following command (Windows version here, using the classpath you created in Setting Up Your Environment):

java -cp %CP% org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true --noWrapped --output src --NStoPkg http://example.com/wsdl/tutorial com.example --NStoPkg http://example.com/schema/tutorial com.example.schema wsdl/tutorial.wsdl
The "--noWrapped" option turns off support for wrapped document/literal. What this means is that WSDL2Java will not attempt to "unwrap" (sounds backwards) your PingRequest and PingResponse elements to simple Java Strings. If you did not supply this option, no classes would be generated for the documents, as each simply consists of a single String parameter. The purpose of the namespace mapping (the "--NStoPkg" option) is to simplify the Java package of the resulting classes. If we did not supply a mapping, the URI "http://example.com/wsdl/tutorial" would map to Java package "com.example.wsdl.tutorial", which is a little verbose for the purposes of this tutorial. If there is only one target Java package to specify, you can accomplish the same result with the "--package". However, here, we also want to map the schema namespace to a simpler (and different) package, so we use two occurrences of the "--NStoPkg" option. With the choices we specified above, the server-side classes will go into the com.example> package, and the bean classes representing the input and output documents will go in the com.example.schema package.

Next, modify the TutorialSOAPBindingImpl.java class to return a response to the ping request, for example:

...
com.example.schema.PingResponseType response = new com.example.schema.PingResponseType();
response.setResponseParam("This is the JBoss 3.2.7 response to request '" + request.getRequestParam() + "'");
return response;
...
Now, compile the application to the wsr directory with the following command, adjusted as needed for your platform and executed from the src directory:
javac -classpath %CP% -d ../wsr com/example/*.java com/example/schema/*.java

Back to Top

Packaging and Deploying the Service

The web service requires a web-service.xml file, found in the META-INF directory. This file is just the Axis deploy.wsdd file, a minimal template of which was generated by WSDL2Java and placed in the src/com/example directory. Copy this file to the wsr/META-INF directory, renaming it to web-service.xml (note that this is not the same as the web-service- standard webservices.xml file, but is JBoss/Axis-specific). The exploded view of your web service should look like the following:

  wsrDir
    com
      example
        - TutorialPT.class
        - TutorialService.class
        - TutorialServiceLocator.class
        - TutorialSOAPBindingImpl.class
        - TutorialSOAPBindingSkeleton.class
        - TutorialSOAPBindingStub.class
        schema
          - PingRequestType.class
          - PingResponseType.class
    META-INF
      - web-service.xml
    wsdl
      - tutorial.wsdl

Now, you can create the web service archive file by executing the following from the top-level directory of your tutorial:

jar cvf tutorial.wsr -C wsr .
This file can then be dropped onto the deploy directory of your running JBoss 3.2.7 server configuration. To verify that the web service has deployed correctly, go to the jboss-net webapp on JBoss at
http://host:port/jboss-net
(substitute your hostname and port number) and click on "View the list of deployed Web services". The next page, called "And now... Some Services" should show your web service in a listing similar to Note that the displayed name is just the port name from the service definition in the WSDL file. Clicking on the wsdl link will display the WSDL file for the web service. Note here that the deployer has changed the service binding address from the original
http://localhost:8080/tutorial
to
http://localhost:8080/jboss-net/services/TutorialService_Port
This check only verifies that the web service has deployed, but not necessarily that it has deployed correctly. In the next section, we will write a client which makes the pingRequest; this is the topic of the next section. However, for now you can test from a browser with an HTTP GET as follows:
http://localhost:8080/jboss-net/services/TutorialService_Port?method=pingRequest><requestParam>Ping</requestParam>
and in response you should see the following XML document:
<soapenv:Envelope>
  <soapenv:Body>
    <ns1:PingResponse>
      <responseParam>This is the JBoss 3.2.7 response to request 'Ping'</responseParam>
    </ns1:PingResponse>
  </soapenv:Body>
</soapenv:Envelope>

Back to Top

Comments about the Generated Stub

Because of a bug in JBoss 3.2.7, it does not appear to be possible to access a 3.2.7-based document/literal web service from a 3.2.7-generated JAX-RPC client (see NPE in Call.getTypeMapping). Although this bug is marked as "Cannot Reproduce", it is actually virtually impossible not to reproduce it if you use the Axis implementation that is included and integrated with JBoss 3.2.7). In the absence of this bug, code similar to

TutorialSOAPBindingStub stub = (TutorialSOAPBindingStub)(tutorialService.getTutorialService_Port());
stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
PingRequestType pingReq = new PingRequestType();
pingReq.setRequestParam(pingMessage);
System.out.println("Ping request string is '" + pingReq.getRequestParam() + "'");
PingResponseType pingResp = stub.pingRequest(pingReq);
System.out.println("Response string is '" + pingResp.getResponseParam() + "'");*/
would correctly invoke the web service. The bug referred to above is a client-side bug (that is, the SOAP message never actually gets sent), which suggests a different type of client might be able to access the web service.

It turns out that a SAAJ-based Java client, as well as a simple C#/.NET application, can indeed access this web service. Please see the client tutorials listed at Web Services Resources and Tutorials for more information. An alternative, if you have the option, is to use JBoss 4.0.3.

Back to Top
Back to Web Services Resources and Tutorials