WAS v8.5 > Develop applications > Develop SCA composites > Develop SCA applications

Develop SCA service clients

We can develop a SCA service client starting with either a Java interface or a WSDL file for the SCA service to invoke. We can develop SCA service clients that can both access and invoke an SCA service that are based on the Service Component Architecture specification. An SCA client can consume a diverse set of services such as enterprise beans, web services, and other SCA services, through the capabilities of the respective SCA bindings and using the Plain Old Java Object (POJO) client programming model.

To develop SCA service clients, we can start with either an existing Web Services Description Language (WSDL) file and use the wsimport tool to generate the Java interface or we can start with an existing Java interface.

Develop SCA client components starting with an existing WSDL file

When we have an existing WSDL file that describes your SCA service interface as a WSDL portType, along with XSD schema definitions of your business data, we can use the wsimport tool to generate the SCA Java representations of your business service interfaces and your business data. The wsimport tool generates Java classes used to write a Java implementation that reflects your business logic. We can use the generated output of the proxy class and the JAXB data binding types in your Java client to invoke the SCA service using the simple POJO programming model.

The generated annotated Java classes that correspond to your business data contain all the necessary information the JAXB runtime environment requires to build and parse the XML for marshaling and unmarshaling. In other words, the data programming model is limited to object instantiation and the use of getter and setter methods, and we do not need to write code to convert the data between the XML wire format and the Java application.

Now that we have the generated annotated Java classes, use the Java interface and data type classes to create the reference proxy as described in the developing SCA clients starting with a Java interface section.

Develop SCA client components starting with a Java interface

When we have a Java interface to your SCA service, obtained either by starting from a WSDL and generating the Java classes or by starting with Java code, use the Java interface and data type classes to create the reference proxy. If your client is designed so that its reference proxy is injected from the SCA container, the Java interface is the same type as your proxy field and this file contains the corresponding @Reference annotation. We can only create the static reference from another SCA component implementation that acts as a client of the original service. If your reference proxy is created programmatically, create a proxy variable that has the same type as your Java interface, and use an API such as CompositeContext.getService(Class <B>interfaze, …) to create the reference proxy. The generated Java interface type is the interface parameter that is passed to this API. Read about locating and invoking SCA services to learn more about creating the reference proxy dynamically.

Regardless of whether the proxy is created by injection methods or programmatically, the Java interface is the class of the proxy and the generated JAXB types are the parameter types which includes inputs, outputs, and exceptions.

Considerations for local and remotable interfaces

It is important to understand that a remotable interface uses an XML wire format for data. Therefore, clients must use a JAXB-based programming model for the data types. In contrast, a local interface uses pass-by-reference semantics, so there is no data copy. Using the local interface, data is read and written without any special programming model such as JAXB.

Though WSDL-based interfaces are always remotable, we can also mark a Java interface not generated from a WSDL file as remotable by annotating it with the @Remotable annotation. The @Remotable annotation results in a data copy with XML serialization as defined by JAXB.

Defining the remotable interface is straightforward when we start with a WSDL interface, because we use the wsimport tool to generate the JAXB data types that we use when we write your SCA client. The remotable interface is less apparent when starting from a remotable Java interface, unless the Java types are decorated with JAXB annotations. XML serialization behaves differently than Java serialization. For an POJO not annotated, Java serialization preserves instance data including private fields, whereas JAXB serialization preserves JavaBeans properties.

The focus of this topic is the use of remotable interfaces.

We can develop a component that consumes or acts as a client of the target service using a component reference. In addition to consuming a service from another component's reference, the product also provides a mechanism for consuming an SCA service over the default binding from a non-SCA component.

  1. Determine if you are developing the SCA service client starting with an existing WSDL file or with an existing Java interface.
  2. Develop the client Java interfaces and data types from a WSDL file if you are not starting with an existing Java interface. Use the wsimport command to generate the SCA service client Java interfaces.

  3. Create the reference proxy based on the Java interface.

    1. Create a reference proxy field or setter method that has the same type as the generated Java interface
    2. Annotate this field or setter with the @Reference annotation.

    Now we have completed the steps required to add the reference to your Java component implementation

  4. Create a component definition using the Java implementation.

    In the composite definition, add a <reference> element that refers back to the original interface and the field or setter of your SCA implementation. The reference is added as a child element of your component. The component is part of a composite definition.

    The <reference> name attribute must correspond to the field or setter containing the @Reference annotation. For a field containing the @Reference annotation, the name attribute must match exactly. For a setter containing the @Reference annotation, use the usual Java conventions for translating an annotated setter into a corresponding field, which in turn must match the name attribute.

    For the interface:

    • If your SCA client development started with an existing WSDL file, create an <interface.wsdl> element as a child element of the <reference> element that points to the WSDL portType.

    • If your SCA client development started from existing Java interface, create an <interface.java> element as a child element of the <reference> element that points to the original Java interface. This is optional, since the runtime environment can introspect the Java interface.

    In addition to these aspects of your component definition described by these development procedures, there are other aspects of defining a component. These aspects include adding bindings, configuring property values, defining intents, attaching policy sets, and resolving references. We can create multiple components using this same implementation, but all component definitions are the same with respect to the <implementation.wsdl> element and <reference> element described in this step.

  5. Deploy the SCA component by creating the SCA business level application from a deployable composite.

    In the previous step, you defined a component providing your SCA service within a composite definition. This composite is either a deployable composite, or one used recursively as a composite implementation of a component in a higher-level composite. To learn how to deploy the SCA service, read about deploying and administering business-level applications.


Results

You have created an SCA component that can consume an existing SCA service using a WSDL or Java interface.


Example

The following example illustrates using an existing WSDL interface to generate a Java interface used to create a Java implementation that is an SCA client. If you are starting with an existing Java interface, begin with step 4 to follow this example.

  1. Copy the following sample account.wsdl WSDL file to a temporary directory.
    <?xml version="1.0" encoding="UTF-8"?> 
    
    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
         xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
         xmlns:account="http://www.myaccount.com/account"
         targetNamespace="http://www.myaccount.com/account"
         name="AccountService"> 
          <wsdl:types>          <schema targetNamespace="http://www.myaccount.com/account"
                 xmlns="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:account="http://www.myaccount.com/account"> 
                   <element name="computeAccountAverage">                  <complexType>                      <sequence>                          <element name="account" type="account:Account" />                          <element name="days" type="xsd:int" />                      </sequence>                  </complexType>              </element>              <element name="computeAccountAverageResponse">                  <complexType>                      <sequence>                          <element name="return" type="xsd:float" />                      </sequence>                  </complexType>              </element> 
                 <complexType name="Account">                  <attribute name="accountNumber" type="xsd:int" />                  <attribute name="accountID" type="xsd:string" />                  <attribute name="accountType" type="xsd:string" />                  <attribute name="balance" type="xsd:float" />              </complexType> 
              </schema>      </wsdl:types> 
         <wsdl:message name="computeAccountAverageRequest">          <wsdl:part element="account:computeAccountAverage"
                 name="parameters" />      </wsdl:message> 
         <wsdl:message name="computeAccountAverageResponse">          <wsdl:part element="account:computeAccountAverageResponse"
                 name="parameters" />      </wsdl:message> 
         <wsdl:portType name="AccountService">          <wsdl:operation name="computeAccountAverage">              <wsdl:input message="account:computeAccountAverageRequest" name="accountReq"/>              <wsdl:output message="account:computeAccountAverageResponse" name="accountResp"/>          </wsdl:operation>      </wsdl:portType> 
         <wsdl:binding name="AccountServiceSOAP" type="account:AccountService">          <soap:binding style="document"
                 transport="http://schemas.xmlsoap.org/soap/http" />          <wsdl:operation name="computeAccountAverage"> 
                <soap:operation
                     soapAction="computeAccountAverage" />              <wsdl:input name="accountReq"> 
                    <soap:body use="literal" />              </wsdl:input>              <wsdl:output name="accountResp">                  <soap:body use="literal" />              </wsdl:output>          </wsdl:operation> 
          </wsdl:binding> 
         <wsdl:service name="AccountWSDLService">          <wsdl:port binding="account:AccountServiceSOAP"
                 name="AccountServicePort">              <soap:address location=""/>          </wsdl:port>      </wsdl:service> </wsdl:definitions>
  2. Run the wsimport command from the app_server_root/bin/ directory.

    Run the wsimport command,

    After generating the template files using the wsimport command, the following Java files are generated:
    com/myaccount/account/Account.java
    com/myaccount/account/AccountService.java
    com/myaccount/account/AccountWSDLService.java
    com/myaccount/account/ComputeAccountAverage.java
    com/myaccount/account/ComputeAccountAverageResponse.java
    com/myaccount/account/ObjectFactory.java
    com/myaccount/account/package-info.java

  3. Identify the generated Java interface from the generated classes.
    //
    // Generated By:JAX-WS RI IBM 2.1.1 in JDK 6 (JAXB RI IBM JAXB 2.1.3 in JDK 1.6)
    //
    package com.myaccount.account;
    ...
    @WebService(name = "AccountService", targetNamespace = "http://www.myaccount.com/account")
    …
    public interface AccountService {
        /**
         *
         * @param days
         * @param account
         * @return
         *     returns float
         */
        @WebMethod(action = "computeAccountAverage")
        @WebResult(targetNamespace = "")
        @RequestWrapper(localName = "computeAccountAverage", targetNamespace = "http://www.myaccount.com/account",
             className = "com.myaccount.account.ComputeAccountAverage")
        @ResponseWrapper(localName = "computeAccountAverageResponse", targetNamespace = "http://www.myaccount.com/account",
             className = "com.myaccount.account.ComputeAccountAverageResponse")
        public float computeAccountAverage(
            @WebParam(name = "account", targetNamespace = "")
            Account account,
            @WebParam(name = "days", targetNamespace = "")
            int days);
    }

    This code example is a Java interface, not merely a Java class. The @WebService annotation is present in this Java interface. It is important to know that this example is not the same as the generated @WebServiceClient class, com.myaccount.account.AccountWSDLService. This class is not an interface and is actually not needed in your SCA application.

  4. Now that we have Java interface either by generating the Java interface from a WSDL file or we have an existing Java interface, you are ready to develop your SCA client from the Java interface.
  5. Place the @Reference annotation on a public or protected field or setter, with the same type as your Java interface.
    package com.myaccount.client;
    
    import bank.process.BankProcess;
    import org.osoa.sca.annotations.Reference;
    import org.osoa.sca.annotations.Service;
    
    import com.myaccount.account.*;
    
    @Service(BankProcess.class)
    public class AccountClientComponent implements BankProcess {
    
       // Note the type, ‘AccountService', is the Java interface generated from    // from the WSDL portType
        private AccountService accountServiceRef;
    
        //
        // Injected by the SCA container     //
        @Reference
        public void setAccountServiceRef(AccountService accountServiceRef) {
            this.accountServiceRef = accountServiceRef;
        }
    
        public String someMethod(String input) {
    
            //... some business logic …
    
            //  We'll show a simple example of JAXB API usage         ObjectFactory factory = new ObjectFactory();
            Account account = factory.createAccount();
            account.setAccountNumber(4);
            account.setAccountID("CHECKING");
    
            int days = 5;
    
            float avg = accountServiceRef.computeAccountAverage(account, days);
    
            //... the rest of the business logic …
        }}

  6. Create a component using the component implementation. When using a WSDL portType interface, create component definitions in the composite definition that references the original portType along with the SCA Java implementation. In SCA, a component is a configured instance of a component implementation. There are other aspects of defining a component that are not shown here such as configuring bindings, configuring property values, defining intents, attaching policy sets, and resolving references. Shown here are the aspects of component creation that are common for all component definitions using the implementation developed in this example. This example also includes bindings that we can modify or omit for other components using this component implementation.
    <?xml version="1.0" encoding="UTF-8"?> 
    <composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
         targetNamespace="http://bank.process/customer"
             name="bpComposite"> 
          <component name="BankProcessComponent"> 
              <implementation.java class="com.myaccount.client.AccountClientComponent"/>          <!-- The @name attribute corresponds to the setter that is annotated with the @Reference annotation. --> 
             <reference name="accountServiceRef">               <!-- This statement specifies the QName of the WSDL portType,
                        "http://www.myaccount.com/account#AccountService" in the syntax as                    illustrated in the interface.wsdl statement.  --> 
                 <interface.wsdl interface="http://www.myaccount.com/account#wsdl.interface(AccountService)" />              <binding.ws uri="http://localhost:9080/BankingComponent/AccountService"/> 
      <!-- This example uses the SCA web services binding.  However, it does not matter which specific binding  you choose.  We can also choose to use the SCA default binding or the SCA EJB binding.  --> 
              </reference>      </component> 
    </composite>

  7. Configure the composite definition when starting with a Java interface.

    The following snippet is another example of the syntax if you develop an SCA client starting with a Java interface rather than with a WSDL portType. To simplify this example, use the same AccountService Java interface from the previous step but in this case, assume that it was not generated from a WSDL file.

    <?xml version="1.0" encoding="UTF-8"?> 
    <composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
         targetNamespace="http://bank.process/customer"
             name="bpComposite"> 
          <component name="BankProcessComponent"> 
    
             <implementation.java class="com.myaccount.client.AccountClientComponent"/> 
             <!-- The @name value corresponds to the setter that is annotated with the @Reference annotation. -->                 <reference name="accountServiceRef"> 
                  <!-- Because the runtime can introspect the interface, it is unnecessary to specify                    the interface.java in the composite definition. This is what the interface looks like if you include it. 
    
                              <interface.java interface=”com.myaccount.account.AccountService”/>  --> 
                   <!-- The SCA binding type is omitted. It does not matter which specific SCA binding you choose. --> 
             </reference>      </component> 
    </composite>
  8. After a component is defined as part of a deployable composite, either directly or recursively through use of one or more layers of components with composite implementation, you are now ready to deploy the SCA component by creating a SCA business level application.


Related concepts:

SCA in WAS: Overview
SCA components
SCA composites
SCA domain


Related


Deploy business-level applications
Develop SCA services from existing WSDL files
Develop SCA services with existing Java code
wsimport command for JAX-WS applications
Specify bindings in an SCA environment
Use the SCA default binding to find and locate SCA services
Manage policy sets


Reference:

Considerations for developing SCA applications using EJB bindings
Service Component Architecture specifications and APIs


+

Search Tips   |   Advanced Search