Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > Develop SCA composites > Develop SCA applications
Develop SCA service clients
We can develop a Service Component Architecture (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 by using the Plain Old Java Object (POJO) client programming model.
To develop SCA service clients, you can start with either an existing WSDL file and use the wsimport tool to generate the Java interface or you 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, you 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 that you can use 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 that the Java Architecture for XML Binding (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 you 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, you can also mark a Java interface that is 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.
Define the remotable interface is straightforward when you start with a WSDL interface, because you use the wsimport tool to generate the JAXB data types that you use when you 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 that is 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.
Procedure
- Determine if you are developing the SCA service client starting with an existing WSDL file or with an existing Java interface.
- 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.
- Create the reference proxy based on the Java interface.
- Create a reference proxy field or setter method that has the same type as the generated Java interface
- 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
- 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 that contains the @Reference annotation. For a field that contains the @Reference annotation, the name attribute must match exactly. For a setter that contains 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.
- 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.
- 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>- Run the wsimport command from the WAS_HOME/bin/ directory.
(Windows)
WAS_HOME\bin\wsimport.bat -keep -verbose account.wsdl(AIX) (Solaris) Run the wsimport command,
WAS_HOME/bin/wsimport.sh -keep -verbose account.wsdlAfter 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
- 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.
- 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.
- 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 … } }
- 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 you 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>
- 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 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>
- 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.
SCA in WAS: Overview
SCA components
SCA composites
SCA domain
Deploy and administering 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
Related
Considerations for developing SCA applications using EJB bindings
Service Component Architecture specifications and APIs