Previous section   Next section

8.1 wscompile — JAX-RPC Stub and Tie Generation Utility

8.1.1 Availability

J2EE 1.4 reference implementation and Java Web Services Developer's Pack.

8.1.2 Synopsis

wscompile [options] config-file

8.1.3 Description

The wscompile utility is a tool supplied by the JAX-RPC reference implementation. It is driven by a configuration file (the format of which is shown in Examples Example 8-1 through Example 8-5) and a set of command-line options.

The basic function of wscompile is to generate and compile artifacts that are required to link a JAX-RPC client application or web service implementation to a particular JAX-RPC runtime. Like wscompile itself, these artifacts are implementation-dependent. Providing a tool that creates them removes the need for developers to concern themselves with the way in which these artifacts are constructed, and allows much of the complexity of the JAX-RPC infrastructure to be hidden.

Depending on the content of the configuration file and the command-line options supplied, wscompile may generate some or all of the following:

Although wscompile is capable of creating both client- and server-side artifacts, in most cases, it is used in connection with a web service client application. Artifact generation for the server side is usually performed as part of the preparation of a deployable web archive, using the wsdeploy utility or the J2EE 1.4 deploytool command.

8.1.4 Options

The operation of the wscompile utility is determined in part by its command-line options, of which exactly one of -gen, -define, and -import must appear. The behavior of this command is also partly determined by which of three elements (service, modelfile, and wsdl) appear in the configuration file. These elements are described in detail in Section 8.1.5. The presence or absence of one of these elements may have an effect on the validity or meaning of the command-line options. When this is the case, it is noted along with the description of the options concerned.

-classpath path
-cp path

Synonymous options that specify a semicolon- (Windows) or colon-separated (Unix) list of directories, as well as JAR and ZIP files that contain classes that are required in order to compile the client- or server-side artifacts created by wscompile. This option is typically used to supply the location of the compiled Java class files that represent the service endpoint interface when the configuration file contains a service element (see Section 8.1.5). It is not necessary to include the JAR files that contain the class files for the JAX-RPC reference implementation.

-d directory

The pathname of a directory below which compiled class files are placed (unless subject to the -nd option described later in this list). The specified directory must already exist. If this option is omitted, the working directory is used instead.

-define

This option may only be used when the configuration file contains a service element. It causes wscompile to construct its internal model of the service based on a Java interface definition, and writes a WSDL file describing the service to the directory indicated by the -nd option (see later in this list). This option can also be used together with -model as a way to create a model file without also generating stubs and/or tie classes.

-f:featurelist
-features:featurelist

Specifies a comma-separated list of suboptions that should be turned on. The available features are described later in Section 8.1.7.

-g

Includes debugging information when compiling the generated Java source files.

-gen
-gen:client
-gen:server
-gen:both

Specifies whether artifacts for the client-side, server-side, or both are to be generated. The option -gen is equivalent to -gen:client. See Section 8.1.6 later in this chapter for a description of what is generated in each case.

-httpproxy:host[:port]

Provides the host and port information for the HTTP proxy to be used when accessing external resources such as a WSDL definition or a schema document that it refers to. This option is not required when a direct connection can be made. The port, if not specified, defaults to 8080.

-import

Imports a service definition in the form of a WSDL document and generates the files listed later in Section 8.1.6. This option can only be used when the configuration file contains a wsdl element.

-keep

Causes generated Java source files to be retained after compilation. By default, these files are deleted. If a WSDL file is generated, it is not deleted, even if the -keep option is not used.

-model file

Writes a copy of the internal representation of the web service — created from a Java interface definition or a WSDL document — to the given file. This file is in binary format and is typically created so that it can be supplied to wsdeploy via the jaxrpc-ri.xml file. A human-readable version of this file can be obtained by using the -Xdebugmodel option.

-nd directory

Specifies the directory in which files that are not Java source files or compiled Java class files should be placed. This directory must already exist. By default, these files are placed in the directory specified using the -d option, or else in the working directory if that option is also not specified. Currently, only the generated WSDL file is placed in this directory.

-O

Causes generated code to optimize when compiled.

-s directory

Specifies the directory in which generated source files should be placed. This directory must already exist. If this option is not specified, these files are placed in the directory given by the -d option, or in the working directory if that option is also omitted. Generated source files are deleted once they are compiled unless the -keep option is used.

-verbose

Prints extra messages that indicate what wscompile is doing.

-version

Displays the version number of the wscompile utility in use and exits. Any other arguments are ignored.

-Xdebugmodel:file

Writes a human-readable version of the model file for the service to the given file.

-Xprintstacktrace

Causes stack traces to be printed for all exceptions encountered during execution of wscompile.

8.1.5 Configuration File

The wscompile utility uses an XML configuration file, typically called config.xml, to indicate where the definition of a web service may be found, and to provide additional information that may be required while generating and compiling the requested artifacts. A typical example of a configuration file is shown in Example 2-9 in Chapter 2.

The top-most element of the file is always a configuration element. This element may contain exactly one child element, which determines both the location of the web service definition and the form in which it is held. This element must be one of the following:

service

Specifies that the service is defined by a Java interface

wsdl

Specifies a service defined by a WSDL document

modelfile

Specifies a service defined in a JAX-RPC model file

Each of these elements has its own set of attributes and child elements that can be used to control the actions taken by wscompile. All of the elements in the configuration file are defined in the XML namespace associated with the URI http://java.sun.com/xml/ns/jax-rpc/ri/config, which is usually assigned to be the default namespace.

8.1.5.1 The service element

This element is used when the web service endpoint interface is defined as a Java interface. The attributes and child elements permitted with the service element are shown in Example 8-1. Values must be supplied for all of these attributes.

Example 8-1. The service element in the wscompile configuration file
<service name="name" targetNamespace="URI" typeNamespace="URI"
         packageName="name">
  <interface name="name" servantName="className" 
             soapAction="string" soapActionBase="string">
          <!-- Any number allowed -->
    <handlerChains>       <!-- 0 or 1 allowed --> 
       <!-- handlerChains content shown later -->
    </handlerChains>
  </interface>
  <typeMappingRegistry>      <!-- 0 or 1 allowed --> 
    <!-- typeMappingRegistry content shown later -->            
  </typeMappingRegistry>
  <handlerChains>             <!-- 0 or 1 allowed -->
   <!-- handlerChains content shown later -->
  </handlerChains>
    <namespaceMappingRegistry>   <!-- 0 or 1 allowed -->
    <!-- namespaceMappingRegistry content shown later -->
  </namespaceMappingRegistry>
</service>

The name attribute provides the name that is used when generating the Service interface and implementation class for this service. If this attribute has the value BookService, for example, then the generated interface is called BookService and the implementation class is called BookService_Impl. These classes, along with all of the others generated by wscompile, is placed in the package whose name is supplied by the packageName attribute.

The targetNamespace and typeNamespace attributes are used when constructing the logical WSDL definition for this service. Elements of the WSDL definition that would reside in the schema part (such as XML schema complex types created from value types included in the interface definition) are assigned the namespace given by the typeNamespace attribute, while those that would appear elsewhere (e.g., port names, operation names, message definitions, etc.) have the namespace given by the targetNamespace attribute.

Within the service element, there can be any number of interface elements, each of which maps a Java interface definition to a portType of the corresponding WSDL definition. Although it is possible to include more than one interface element in a service definition, the effects of doing so when the server-side artifacts are created are perhaps not what you would expect. Although the client-side artifacts correctly represent each interface element as a separate portType within the service, and the generated Service object has a method (such as getBookQueryPort( )) that returns an instance of the stub object for each interface, on the server side, each interface is effectively mapped as a separate service, in the sense that it has its own WSDL definition.

Of the attributes of the interface element, only name is mandatory, supplying the fully qualified name of the compiled Java interface that defines the endpoint methods. The servantName attribute supplies the name of the server-side implementation class for this interface. This attribute was meaningful during the early releases of the JWSDP when both the client-side and server-side artifacts were generated from one configuration file by a utility called xrpcc. In later releases, however, the server-side generation was taken over by the wsdeploy utility, which expects the servant name to be specified in the jaxrpc-ri.xml file. Therefore, this attribute is no longer used.

The optional soapAction and soapActionBase attributes can be used to determine the value of the SOAPAction header for the SOAP messages generated when the methods of this interface are invoked. There are three cases to consider:

Each interface may have one nested handlerChains element. This element configures one or more SOAP message handlers that are activated whenever a request, response, or fault message is processed for any of the methods in the interface. The syntax of this element is described later in Section 8.1.5.4.

Following the interface elements, the schema definition allows a typeMappingRegistry element, a handlerChains element, and a namespaceMappingRegistry element. Only one instance of each of these elements is permitted. Although allowed by the schema definition, the namespaceMappingRegistry element is ignored, as is the handlerChains element. Handler chains should instead be configured by nesting the handlerChains element inside the interface element. The syntax and meaning of each of these elements are described later in this section.

8.1.5.2 The wsdl element

The wsdl element is used in place of service when the service definition is contained in a WSDL document rather than framed in terms of Java classes. You are likely to use this element when constructing clients for web services implemented by third parties. The syntax of this element is shown in Example 8-2.

Example 8-2. The wsdl element in the wscompile configuration file
<wsdl location="URI" packageName= "name">
  <typeMappingRegistry>       <!-- 0 or 1 allowed -->
    <!-- typeMappingRegistry content shown later -->
  </typeMappingRegistry>
  <handlerChains>             <!-- 0 or 1 allowed -->
    <!-- handlerChains content shown later -->
  </handlerChains>
  <namespaceMappingRegistry>  <!-- 0 or 1 allowed -->
    <!-- namespaceMappingRegistry content shown later -->
  </namespaceMappingRegistry>
</wsdl>

The location attribute is usually a URL that can be used to fetch the WSDL document, but may also be the pathname of a file. The packageName attribute supplies the name of the Java package in which the generated artifacts are placed by default. It is possible to arrange for code to be placed in different packages based on the XML namespace of the item from which it is generated by using the namespaceMappingRegistry element, which is described later in this section. The typeMappingRegistry and handlerChains elements can be used to modify the type mapping registry and the set of SOAP handlers associated with the endpoints generated from the WSDL document, as described later in Section 8.1.5.5 and Section 8.1.5.4.

8.1.5.3 The modelfile element

This element is used when the service definition resides in a model file created by a previous invocation of wscompile. The modelfile element has a single (mandatory) attribute and may not have any child elements:

<modelfile location="URI"/>

The URI specifies the location of the model file and may be either a URL or the pathname of a file.

8.1.5.4 The handlerChains element

A handlerChains element configures a chain of SOAP message handlers for either or both of the client and server side of a web service endpoint. It may be used in both the config.xml file and the jaxrpc-ri.xml file, which is discussed in conjunction with the wsdeploy utility, later in this chapter. The syntax of this element is shown is Example 8-3.

Example 8-3. The handerChains element
<handlerChains>
  <chain runAt="client|server" roles="URI list">     <!-- 0, 1 or 2 allowed -->
    <handler className="name" headers= "QName list"> <!-- Any number allowed -->
      <property name="name" value= "value"/>         <!-- Any number allowed -->
    </handler>
  </chain>
</handlerChains>

A handlerChain element may contain up to two nested chain elements, in which one must have the runAt element set to the value client, and the other set to the value server. The wscompile utility processes the appropriate entry depending on whether it is generating client- or server-side artifacts.

The roles attribute of the chain element contains a space-separated list of URIs representing the SOAP actors on behalf of which the SOAP message handlers (see Section 6.8) in the chain can act. If this attribute is omitted, it is assumed that the chain acts on behalf of the SOAP actor next and the ultimate recipient of the message. SOAP message handlers have complete access to a SOAP request message before it is transmitted, as well as to SOAP response and fault messages before they are processed as method call replies. A message handler typically adds or removes and processes SOAP header blocks, but may also inspect or modify the message body.

The SOAP message handlers in a chain are added as children of the chain element. Each handler element has a mandatory className attribute that supplies the name of the Java class that contains the handler implementation. This class must provide a public, no-argument constructor and implement the javax.xml.rpc.handler.Handler interface. The optional headers attribute is a space-separated list of QNames for the headers that the handler can process. Each QName consists of a namespace prefix and a local element part, such as tns:SecurityHeader. The namespace prefix must be defined and associated with a URI on this element or on one of its parents. If this attribute is omitted, the handler makes no statement about the set of headers it can handle. For a description of the way in which this attribute is used, refer to Section 6.8.2.4.

Configuration information may be passed to a handler using one or more nested property elements. The values configured here are made available to the handler implementation class when it is initialized in the form of a java.util.Map.

8.1.5.5 The typeMappingRegistry element

The typeMappingRegistry element is used to add serializers and deserializers to the type mapping registry associated with each service endpoint interface. This element may contain up to three child elements that modify the type mapping registry in different ways. The syntax of this element is shown in Example 8-4.

Example 8-4. The typeMappingRegistry element
<typeMappingRegistry>
  <import> <!-- 0 or 1allowed -->
    <schema namespace="URI" location="URI"/> <!-- Any number allowed -->
  </import>
  <typeMapping encodingStyle="URI">          <!-- Any number allowed -->
    <entry schemaType="QName" javaType="type"
                   serializerFactory="className" deserializerFactory=
                        "className"/>        <!-- Any number allowed -->
  </typeMapping>
  <additionalTypes> <!-- 0 or 1 allowed -->
    <class name="className"/>                <!-- Any number allowed -->
  </additionalTypes>
</typeMappingRegistry>

The import element can be used to import types from one or more external schema documents, the location of which is provided by the location attribute. The types are imported into the namespace given by the namespace attribute, which should match the targetNamespace attribute of the schema element in the document itself, but may not be the same as either the targetNamespace or typeNamespace of the service element within which this element is nested.

The typeMapping element is used to install (probably custom) explicitly named serializers and deserializers to be used when encoding and decoding SOAP elements with the encoding style specified using the encodingStyle attribute. Typical values for this attribute are http://schemas.xmlsoap.org/soap/encoding/, which represents SOAP section 5 encoding rules, and " ", which represents literal encoding. The nested entry elements each create a mapping between a Java type given by the javaType attribute and a corresponding XML schema type specified by the schemaType attribute. The mapping indicates the factories to be used to get serializer and deserializer classes that are to perform the conversion between the Java type and the XML representation given by the schema type, or vice versa. Since there is currently no way to write portable serializers and deserializers (and the API for creating these objects in the reference implementation is not public), it is unlikely that this element will be frequently used.

The additionalTypes element is used to arrange for serializers and deserializers for specified Java types to be generated and included in the type mapping registry. Each nested class element causes an additional serializer/deserializer pair to be included. For example, the following extract arranges for serializers for one- and two-dimensional arrays of strings to be added to the registry:

<additionalTypes>
  <class name="java.lang.String[ ]"/>
  <class name="java.lang.String[ ][ ]"/>
</additionalTypes>

It is not necessary to use this element to include serializers and deserializers for types that are explicitly referred to in the service endpoint interface (i.e., appear as method parameters or return types). For a discussion of this subject, refer to Section 6.9.

This element is permitted with both the service and wsdl elements, but is ignored when used with the wsdl element.

8.1.5.6 The namespaceMappingRegistry element

The namespaceMappingRegistry element can be used to create a set of mappings from XML namespaces to Java packages. The format of this element is shown in Example 8-5.

Example 8-5. The namespaceMappingRegistry element
<namespaceMappingRegistry>
  <namespaceMapping namespace="URI" packageName= "name"/>
       <!-- Any number allowed -->
</namespaceMappingRegistry>

Although the schema allows this element to appear within either a service or wsdl element, it is actioned only when used with a wsdl element. By default, the packageName attribute of the wsdl element determines where all generated classes are placed in the package hierarchy. Using the namespaceMapping element, you can individually assign generated artifacts to packages based on their owning namespace. This is particularly useful if your WSDL document imports one or more XML schemas and you would like to logically separate the implementation classes for the types obtained from these schemas from each other and/or from your own schema types.

As an example of the use of this element, consider the following config.xml file:

<configuration        
   xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">         
    <wsdl location="http://localhost:8080/Books/BookQuery?WSDL"         
          packageName="ora.jwsnut.chapter6.wsdlbookservice">

    <namespaceMappingRegistry>
        <namespaceMapping namespace=
               "urn:jwsnut.chapter2.bookservice/types/BookQuery" 
               packageName="ora.jwsnut.chapter2.bookserviceTypes"/>
    </namespaceMappingRegistry>
</wsdl>
</configuration>

The WSDL document imported in this case has a targetNamespace of urn:jwsnut.chapter2.bookservice/wsdl/BookQuery, while its nested schema element uses the namespace urn:jwsnut.chapter2.bookservice/types/BookQuery. The effect of this mapping is to place all classes generated from the targetNamespace of the WSDL document into the package ora.jwsnut.chapter6.wsdlbookservice, and all of those whose namespace is taken from the nested schema into the package ora.jwsnut.chapter2.bookserviceTypes. Without the mapping, all of the generated classes would have been placed in the package ora.jwsnut.chapter6.wsdlbookservice.

8.1.6 Generated Artifacts

The artifacts generated by wscompile depend on its command-line arguments and the content of the configuration file. Table 8-1 summarizes what might be created based on whether wscompile is being run to create client-side or server-side artifacts or to import a WSDL service definition. If the -gen:both option is used, then the artifacts listed in both the -gen:client and -gen:server columns are created.

Table 8-1. Artifacts generated by the wscompile utility

Artifact

-gen:client

-gen:server

-import

Stubs

   

Service interface

   

Service implementation class

   

Ties

 

 

WSDL document[1]

 

 

Serializers/deserializers

 

Java service endpoint interface[2]

Java service endpoint interface template class[3]

   

Custom classes

RPC structures[4]

[1] A WSDL document is not generated if the configuration file contains a wsdl element.

[2] The Java interface is not generated if the configuration file contains a service element.

[3] This is a class that provides dummy implementations of each method in the service endpoint interface. It is intended to be used as a starting point for an actual implementation.

[4] Creation of these files can be suppressed by using the -f:norpcstructures option.

Naturally, wscompile does not output copies of files that are supplied as input. Hence, no WSDL document is generated when the configuration file contains a wsdl element, and a Java interface is not required when one is supplied by an interface element.

When Java classes are generated, the source code is placed below the directory supplied by the -s option, but is deleted following compilation if the -keep option is not used. Compiled Java class files appear below the directory indicated by the -d argument. The WSDL document is placed in the same directory, but may be redirected to another location using the -nd option.

All serializers/deserializers appear in the same location as the objects that they serialize or deserialize. This includes the serializers/deserializers for SOAP messages, which are placed together with the stub or tie class implementations that they correspond to.

8.1.7 Features

Certain wscompile features can be enabled or disabled using the -f argument, which requires a comma-separated list of items from those listed in the following list. For example:

wscompile -f:datahandleronly,explicitcontext ......

This enables explicit binding of SOAP message headers to method arguments, and suppresses the mapping of attachments to specific Java classes.

datahandleronly

Causes the content of attachments to be mapped to a method argument of type DataHandler. When this feature is not turned on, certain attachment types are mapped to Java types such as Image or javax.xml.transform.Source. See Section 6.5 for a list of these special types.

explicitcontext

Causes message parts assigned to the SOAP message header to appear as additional method arguments in the Java service endpoint interface generated from a WSDL document. See Section 6.8.1 for further details.

infix=<name>

Specifies a string to be included in the name of generated serializers. For example, if the option -f:infix=value is used, then the name of the serializer class for a value type called

BookInfo

is BookInfo_value_SOAPSerializer instead of BookInfo_SOAPSerializer.

nodatabinding

Requests that the binding of message content to method arguments and return values that is performed for document/literal operations be suppressed. If you use this option, you will need to use the SAAJ API to construct a SOAPElement containing the XML to be placed in the body of each request message and decode the response, which will be returned as a SOAPElement. See Section 6.6.2.4 for an example of the use of this feature.

noencodedtypes

This feature causes the xsi:type attribute that appears by default in the SOAP encoding of arrays and value types to be suppressed. The SOAP section 5 encoding rules allow this attribute to be omitted if the type of the enclosed data can be discovered by reference to a schema. As an example of the difference that this makes, a value type that is encoded like this by default:

    <ns0:BookInfo id="ID1" xsi:type="ns0:BookInfo">
      <editor xsi:type="xsd:string">Paula Ferguson, Robert Eckstein</editor>
      <author xsi:type="xsd:string">David Flanagan</author>
      <price xsi:type="xsd:double">39.95</price>
      <title xsi:type="xsd:string">Java in a Nutshell</title>
    </ns0:BookInfo>

looks like this when noencodedtypes is specified:

  <ns0:BookInfo id="ID2">
    <editor xsi:type="xsd:string">Paula Ferguson, Robert Eckstein</editor>
    <author xsi:type="xsd:string">David Flanagan</author>
    <price xsi:type="xsd:double">39.95</price>
    <title xsi:type="xsd:string">Java in a Nutshell</title>
  </ns0:BookInfo>

Note that the xsi:type attribute still appears in the encoding of the basic XML schema data types that make up this object.

nomultirefs

Certain values (such as arrays) are encoded into a SOAP message as multi-reference values — that is, the value is serialized as an independent entity with an associated identifier, which is then referenced from within the message using an element with an href attribute whose value matches the value's identifier. If the same value is used more than once within a message, the use of space is reduced by serializing only one copy and including only a reference to it wherever it should appear. When the nomultirefs feature is enabled, all types appearing in the message body are serialized inline instead of using references.

norpcstructures

Switches off the output of Java classes that are used to group together parameters and return values for the methods of the service endpoint interface. These classes are used internally by the JAX-RPC runtime. Typically, you would use this option in conjunction with -import to obtain from a WSDL file only the Java classes that define the service endpoint interface — without also creating the RPC structures, which are not part of the service interface.

novalidation

Switches off validation of the WSDL document when the wsdl element is used. Using this feature can reduce the execution time of wscompile when the WSDL document is already known to be valid.

searchschema

Causes wscompile to generate serializers/deserializers and Java classes for all types that appear in the schema associated with a WSDL document, whether or not they are explicitly referenced as parts in the message definitions within the document. This feature should be used when creating client-side artifacts from a WSDL definition if there are messages that are defined in terms of abstract types, but where instances of derived types are actually used as inputs or outputs, which are not themselves explicitly named in the message definitions.

serializeinterfaces

At the time of this writing, use of this feature has no effect.


  Previous section   Next section