+

Search Tips   |   Advanced Search

Develop SCA services with existing Java code

We can develop an Service Component Architecture (SCA) service implementation when starting with an existing Java application.

There are two ways to develop an SCA service implementation:

The bottom-up development approach provides a simplified way to begin developing SCA services for the Java developer that does not desire to work with WSDL or XML schema (XSD) authoring or when building new SCA services that expose existing legacy implementations with Java interfaces.

The top-down development approach takes advantage of the interoperable XML-based WSDL, and XSD interface and data definitions.

This task describes the steps when using the bottom-up development approach to develop an SCA service implementation when starting with Java.

When using the bottom-up development methodology, begin by writing a Java interface and implementation that describes the desired business logic. This implementation is then packaged into an application archive file such as a WAR file or a JAR file that is subsequently is used by an SCA component configured with deployment information containing the bindings when the SCA application is deployed.

Best practice: It is a best practice to use the top-down methodology to develop SCA service implementations because this approach leverages the capabilities of the XML interface description and provides a greater ease in interoperability across platforms, bindings, and programming languages. To learn more about using the top-down methodology, read about developing SCA services from existing WSDL files. bprac

Supported configurations: The product uses XML marshalling as defined by JAXB to marshal and unmarshal data across a remotable interface. If we start with a remotable Java interface for the implementation rather than starting with a WSDL portType interface, be careful when selecting the input and output Java data types and ensure you understand which data is preserved across JAXB marshalling and unmarshalling. However, when authoring an implementation on a local interface, we can use any Java type because local interfaces use pass-by-reference semantics, which implies no data is copied..

The data marshalling and unmarshalling used to instantiate the copying of data over remotable interfaces is defined by the JAXB specification rather than by Java serialization or the java.io.Serializable or java.io.Externalizable interfaces. Because of this behavior, certain existing Java types are not suitable for use on remotable interfaces, as these types are not serialized using Java serialization. For data types that are not annotated, the class is introspected and its Java properties determine the data that is preserved in the copy. For data types that take advantage of JAXB annotations, we can customize the mapping of Java classes to XSD types and of Java instances to XML documents. Custom Java serialization routines such as the readObject() or writeObject() are not applicable in this scenario. The SCA runtime environment takes an XML centric view of the business data and leverages the JAXB standards to define the mappings between the Java programming model and the XML data format on the wire. gotcha

  1. Access the existing Java interface to expose as an SCA service.

  2. Determine if you are using a local or a remotable interface.

    • For a remotable interface, add the @Remotable annotation to the Java interface. The input and output Java data types on the remotable interface use pass-by-value semantics which implies the data is copied using XML serialization as defined by JAXB.

  3. Complete the implementation of the SCA service. Write a Java implementation of the generated Java interface that reflects the business logic. The Java implementation is a Plain Old Java Object (POJO) implementation of the original interface.

  4. Annotate the Java implementation. Add the @Service annotation to the Java implementation to specify this is an SCA service. When you complete this step, we have created an SCA component implementation.

  5. Define a component within a composite definition using this component implementation. In the deinition of your composite, define a component that refers back to the original Java interface and the SCA implementation.

    1. Under the <component> element, create a <implementation.java> child element that refers to the class name of the POJO component implementation.

    2. Under the <component> element, create a <service> child element.

    3. Under the <service> element, create a <interface.java ..> element that refers back to the original Java interface. The @name attribute of the <service> element must match the unqualified class name of the Java interface.

    You now have a component with a well-defined component name and service name with a well-defined interface.

    In addition to these aspects of the 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.java>, <imterface.java> and <service> elements described in this step.

  6. Deploy the SCA service by creating the SCA business level application from a deployable composite.

    In the previous step, you defined a component providing the 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 developed an SCA service using the bottom-up methodology by starting with an existing Java interface or implementation.


Example

The following example illustrates how to create a component implementation of a remotable SCA service interface starting from existing Java code:

  1. Start with Java interface myintf.NameGetter using type mypkg.Person.
    //NameGetter.java
    package myintf;
    import mypkg.Person;
    public interface NameGetter {
        public String getName(Person p);
    }
    
    //Person.java
    
    package mypkg;
    
    public class Person {
    
        protected String firstName;
        protected String lastName;
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String value) {
            this.firstName = value;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String value) {
            this.lastName = value;
        }
    }

    In this example, the mypkg.Person class is well-suited for use over a remotable interface, because it follows the JavaBeans pattern and contains a public getter and setter pair for its important data fields. The XML wire format used by the runtime environment will serialize and deserialize this class. However, other existing Java types that do not adhere to the JavaBeans pattern can cause problems as they dol not serialize correctly and data loss occurs. For this reason, it is a best practice to use a top-down development approach, starting from schema definitions and generating JAXB classes for use in the application programming model. See the developing SCA services from existing WSDL files to learn more about the top-down development approach.

  2. Because we are creating a service with a remotable interface, add the @Remotable annotation.
    //NameGetter.java
    package myintf;
    
    import mypkg.Person;
    import org.osoa.sca.annotations.Remotable;
    
    @Remotable
    public interface NameGetter {
        public String getName(Person p);
    }

  3. Unless we have an existing Java implementation, write a Java implementation of the generated Java interface that reflects the business logic.
    package myintf;
    import mypkg.Person;
    
    public class NameGetterImpl implements NameGetter {
    
        public String getName(Person p) {
            // Example "business logic"
            return p.getFirstName() + " " + p.getLastName();
        }
    
    }

  4. Add the @Service annotation to the Java implementation.
    package myintf;
    import mypkg.Person;
    import org.osoa.sca.annotations.Service;
    
    @Service(NameGetter.class)
    public class NameGetterImpl implements NameGetter {
    
        public String getName(Person p) {
            // Example "business logic"
            return p.getFirstName() + " " + p.getLastName();
        }
    
    }

  5. Create a component using the component implementation. You will create a component definition in a composite that references the original Java implementation class, as well as its Java interface. 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 we can modify or omit for other components using this component implementation.
    <composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
        targetNamespace="http://org.services.naming" 
            name="NameServices">
    
          <component name="NamingServicesComponent">
             <implementation.java class="myintf.NameGetterImpl"/>
             <service name="NameGetter">
    
                 <!-- The interface.java is not  required because the run time can introspect it. -->
    
                 <interface.java interface=myintf.NameGetter/>
    
                 <!-- The choice of bindings is not important for the example.  Here, both the                 SCA default and web services bindings are configured. -->
                 <binding.ws/>
                 <binding.sca/>
             </service>
         </component> 
    
    </composite>

  6. After the 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 ready to deploy the SCA service by creating an SCA business level application.


Related concepts

  • SCA in WebSphere Application Server: Overview
  • SCA components
  • SCA composites
  • SCA domain


    Related tasks

  • Develop SCA services from existing WSDL files
  • Develop SCA service clients
  • Deploy and administering business-level applications
  • Specify bindings in an SCA environment
  • Manage policy sets using the administrative console

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