Service Component Architecture (SCA) is a specification, or rather, a collection of specifications designed to describe a model for building applications and systems using a Service Oriented Architecture. SCA provides a model for how to create applications which are a composition of services and business functions.
The benefits of SCA over other SOA technologies are not always immediately obvious. When building a Service Oriented Architecture from scratch, a homogeneous system is usually envisioned, where all the components of the system are using the same Web service standards and a common programming language. The problem often is that these environments are not always realistic. There are usually existing legacy applications that need to be incorporated into the system which often don't fit well to the heterogeneous environment. What if the WebService standards chosen to glue the architecture together falls out of fashion? What if there is a newer standard that must be used to use services from outside vendors, or a different method is preferred to expose your companies services to third parties? Is it time to rewrite all the services? Not with SCA.
The Apache Tuscany project is an open source project devoted to creating implementations of the SCA specifications (as well as SCA's "cousin" specifications Service Data Objects (SDO) and Data Access Service (DAS)). I'll be focusing on Apache Tuscany's SCA implementation in this article as it is freely available and easy to use. It should be noted, however, that there are several companies that are working on their own product implementations of the SCA specifications.
The binary distribution of Apache Tuscany's Java SCA implementation is available here: http://incubator.apache.org/tuscany/sca-java-releases.html The latest version as of this writing is 1.0.1-incubating and the examples in this article were written to this version.
Once you have the binary distribution downloaded and unzipped, have a look at the Hello World Web Service example.
It is located in the <tuscany_home>/samples/helloworld-ws-service directory.
Listing 1. Directory layout of Hello World Web service example
helloworld-ws-service/
src/
main/
java/
helloworld/
HelloWorldImpl.java
HelloWorldServer.java
HelloWorldService.java
resources/
wsdl/
helloworld.wsdl
helloworldws.composite
test/
java/
helloworld/
HelloWorldServerTestCase.java
target/
sample-helloworld-ws-service.jar
build.xml
pom.xml
README |
Tuscany uses a Maven build system, so hopefully, the layout is familliar. The main program is contained in the three
Java files, HelloWorldService.java is the interface for the service, HelloWorldImpl.java
is the implementation of the service, and HelloWorldServer.java is the executable which has the main method that loads up the SCA runtime.
The file where we will spend the most time is helloworldws.composite.
Listing 2. helloworldws.composite
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://helloworld"
xmlns:hw="http://helloworld"
name="helloworldws">
<component name="HelloWorldServiceComponent">
<implementation.java class="helloworld.HelloWorldImpl" />
<service name="HelloWorldService">
<interface.wsdl interface="http://helloworld#wsdl.interface(HelloWorld)" />
<binding.ws uri="http://localhost:8085/HelloWorldService"/>
</service>
</component>
</composite> |
This composite file is where our SCA composite is defined. Here we define what components are in
our composite and what services are exposed or references required by our components in the composite.
This is a very simple composite containing one component named HelloWorldServiceComponent that exposes
one service named HelloWorldService that is to be exposed using the Web service binding based at the
URI http://localhost:8085/HelloWorldService . Also denoted is that the service is implemented by the
Java class helloworld.HelloWorldImpl.
To take the sample for a spin, make sure you have ant 1.6.5 or higher installed, type
ant run, click Enter, and you should get the following:
Listing 3. Running Hello World Web service server
Buildfile: build.xml
run:
[java] Dec 10, 2007 8:53:09 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8085/HelloWorldService
[java] HelloWorld server started (press enter to shutdown)
|
Now you can open another console window and change directory into the <tuscany_home>/samples/helloworld-ws-reference
directory. This is where the sample for the WebService client resides. Type ant run to run
the client against our already running server. You should see the following:
Listing 4. Running Hello World Web service client
Buildfile: build.xml
run:
[java] Injected helloWorldService
[java] Called getGreetings
[java] Hello World
BUILD SUCCESSFUL |
Instead of running the client you could also use the Web Service Definition Language
(WSDL) served from http://localhost:8085/HelloWorldService?wsdl
and create your own web service client. Up to you. When you are done, click Enter in the console window with the server running to shut it down.
Now here is where we get to what I think is cool about SCA. We already have a service created, and now we can expose that exact same service in a different way just by making a few changes to the composite file.
Listing 5. Updated helloworldws.composite file
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://helloworld"
xmlns:hw="http://helloworld"
name="helloworldws">
<service name="HelloWorldService" promote="HelloWorldServiceComponent/HelloWorldService">
<interface.wsdl interface="http://helloworld#wsdl.interface(HelloWorld)" />
<binding.ws uri="http://localhost:8085/HelloWorldService"/>
</service>
<service name="HelloWorldService" promote="HelloWorldServiceComponent/HelloWorldService">
<interface.java interface="helloworld.HelloWorldService"/>
<tuscany:binding.jsonrpc/>
</service>
<component name="HelloWorldServiceComponent">
<implementation.java class="helloworld.HelloWorldImpl"/>
</component>
</composite>
|
These changes now expose the HelloWorldServiceComponent using both the Web service binding and a JSON-RPC binding. I had to move things around a little from the way they were for this to work, but I think it is more clear this way. First, we have the HelloWorldService exposed using the Web service binding. This service definition defines the WSDL interface to use, the URI where the SOAP Web service should live, and which component this service is promoting.
The next section is for the JSON-RPC service. It defines the Java interface being used and also which component should be promoted, which happens to be the same one the SOAP Web service is promoting. The JSON-RPC binding is not an "official" SCA binding which is why it is available in the Tuscany XML namespace instead of the default OSOA SCA one. This is done to prevent potential naming collisions between non-standard bindings from different vendors.
To update the JAR file with our change to helloworldws.composite we need to rebuild
the sample by running the ant command. Alternatively, you could rebuild the project
using Maven by running the mvn command.
Once the build is complete, here is what the output from ant run now gives us:
Listing 6. Running Hello World Web service server with JSON-RPC binding
Buildfile: build.xml
run:
[java] Dec 10, 2007 9:01:14 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8085/HelloWorldService
[java] Dec 10, 2007 9:01:14 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8080/HelloWorldService
[java] Dec 10, 2007 9:01:14 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8080/SCADomain/scaDomain.jsb>
[java] HelloWorld server started (press enter to shutdown) |
This shows that we still have our SOAP-based Web service running, just as before,
at http://localhost:8085/HelloWorldService, but now we also have a JSON-RPC service
running at http://localhost:8080/HelloWorldService (and a helper JavaScript being served
at http://localhost:8080/SCADomain/scaDomain.js, but never mind
that now). Pointing a Web
browser to http://localhost:8080/HelloWorldService?smd will give the Simple Method Description
for the JSON-RPC service. That was it! Just a simple modification and our existing service is
now exposed using a completely different technology. It didn't have to be JSON-RPC
either;
Tuscany has a RMI binding, a DWR binding, and several others. You could even write your own binding
if you wanted to!
Let's make a few more additions to see our JSON-RPC service in action.
We could repackage our application into a WAR file and install it into a JavaEE™
application server, but, as it happens, Tuscany has an HTTP binding that can be used
to expose static Web resources, and since all we need to show off our simple JSON-RPC
service is a static HTML page, this will work perfectly. First, let's add our HTML file.
Let's call the file HelloWorldJSONRPC.html and place it in
<tuscany_home>/samples/helloworld-ws-service/src/main/resources/web directory.
This file and the completed composite file are available in the sample code attached to this article.
Listing 7. HelloWorldJSONRPC.html
<html>
<head>
<title>Tuscany JSON-RPC HelloWorld Example</TITLE>
<script type="text/javascript" src="/SCADomain/scaDomain.js"></script>
<script language="JavaScript">
function getGreeting() {
var name = document.getElementById("name").value;
jsonRpcClient = new JSONRpcClient("/HelloWorldService");
jsonRpcClient.HelloWorldService.getGreetings(name, handleResponse);
}
function handleResponse(result) {
document.getElementById('greeting').innerHTML=result;
}
</script>
</head>
<body>
<h2>Tuscany JSON-RPC HelloWorld Sample</h2>
<p>
Name please:
<input type="text" id="name" size="30" value="World" />
<input type="button" value="Submit" onclick="getGreeting()" />
<div id='greeting'>None Yet.</div>
</p>
</body>
</html> |
This file takes advantage of the JavaScript file we overlooked earlier.
This JavaScript is served by the JSON-RPC binding and provides JavaScript JSON-RPC functions.
The next script section creates a getGreeting function that will use the JavaScript JSON-RPC
library to create a JSON-RPC client for our HelloWorldService and then calls the getGreetings
method on that service.
Now I will show how to modify the composite file to use the HTTP binding to expose this HTML file.
Listing 8. Even more updated helloworldws.composite file
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://helloworld"
xmlns:hw="http://helloworld"
name="helloworldws">
<service name="HelloWorldService" promote="HelloWorldServiceComponent/HelloWorldService">
<interface.wsdl interface="http://helloworld#wsdl.interface(HelloWorld)" />
<binding.ws uri="http://localhost:8085/HelloWorldService"/>
</service>
<service name="HelloWorldService" promote="HelloWorldServiceComponent/HelloWorldService">
<interface.java interface="helloworld.HelloWorldService"/>
<tuscany:binding.jsonrpc/>
</service>
<component name="HelloWorldServiceComponent">
<implementation.java class="helloworld.HelloWorldImpl"/>
</component>
<component name="example">
<tuscany:implementation.resource location="web"/>
<service name="Resource">
<tuscany:binding.http/>
</service>
</component>
</composite> |
This new component definition will exposes the resource directory "web" using the HTTP binding.
Run ant or mvn to rebuild the project and then use ant run again to run the sample. You should see the following:
Listing 9. Running Hello World Web service server with HTTP resource binding added
Buildfile: build.xml
run:
[java] Dec 10, 2007 9:06:38 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8085/HelloWorldService
[java] Dec 10, 2007 9:06:38 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8080/HelloWorldService
[java] Dec 10, 2007 9:06:38 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8080/SCADomain/scaDomain.js
[java] Dec 10, 2007 9:06:38 AM org.apache.tuscany.sca.http.jetty.JettyServer
addServletMapping
[java] INFO: Added Servlet mapping: http://localhost:8080/example/*
[java] HelloWorld server started (press enter to shutdown) |
As you can see, we have our SOAP service, JSON-RPC service, and helper JavaScript
exposed, as well
as a servlet mapping for our newly added resource at http://localhost:8080/example/. We can now point
a Web browser to http://localhost:8080/example/HelloWorldJSONRPC.html and see our super-fancy service in action.
Figure 1. Hello World Service accessed by JSON-RPC
In this article I've shown how to take an existing SCA service using a SOAP Web service binding and extend the service to also be exposed using JSON-RPC. All of this was done without touching the code implementing the service at all. I hope that this shows how SCA is a powerful architecture that helps to futureproof your SOA applications. Services composed using SCA can use any of the bindings available with their SCA runtime implementation. As new technologies enter the scene new bindings and implementation types will be created for them that can easily be incorporated into existing SCA infrastructure.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample Hello World Web service example | example_code.zip | 2KB | HTTP |
Information about download methods
- Participate in the discussion forum.
-
SCA application development,
Part 1: An overview of Service Component Architecture
-
SCA application development,
Part 2: SCA client and implementation model for Java
-
The Apache Tuscany project website
-
Specification for JSON-RPC
-
Brief page explaining Simple Method Description (SMD)
- Browse the
technology bookstore
for books on these and other technical topics.
Comments (Undergoing maintenance)






