by Humphrey Sheil

Can’t we just keep it simple?

news
Jan 9, 200615 mins

Use SOAs to add real value, not complexity, to Java enterprise applications

Presently, service-oriented architecture (SOA) is the hot topic in software development across all technology platforms, especially Java Platform, Enterprise Edition (Java EE) and .Net. However, if we compare the hype surrounding SOAs to what we saw in the late 1990s with Enterprise JavaBeans (EJB) and servlets (in other words, the nascent Java EE platform), there is no comparison. In 1998, EJB rode the Internet wave and represented a fundamental shift away from the hegemony of CORBA and the standard client-server model as dictated by PowerBuilder, Oracle Forms, and others. SOA, in terms of new technology, is not that disruptive. SOA is an idea, concept, or set of best practices for building and exposing functionality in applications. By contrast, Java EE is a fully developed technology stack, designed to be all things to all people.

My primary concern with SOA is an endemic problem across the enterprise Java habitat: complexity. My secondary concern is that SOA is often positioned as a solution to be applied mindlessly across all layers of a Java EE application when this makes no sense. This article aims to distil SOA down to its basic elements and understand them. Once we’ve done that, we can then understand the more complex components of the SOA ecology. Finally, we can understand where SOA adds real value in a Java EE application and, equally, where it adds needless complexity.

The article is structured as follows: First, I provide my own definition of SOA as a standard reference point for the following sections. From there, we examine the primary software engineering problem I believe SOA intends to solve before moving on to objectively examine SOA itself. From this review, I then propose an SOA taxonomy based on complexity requirements. Finally, I propose default implementations of the three main SOA categories identified in the taxonomy section.

What is SOA?

SOA has many definitions. Here is mine:

An SOA is a macro-level design pattern applied at an application’s architectural level that:

  • Selectively exposes that application’s functionality as a set of discrete components
  • Enables these components to be used to build more complex components and applications
  • Features only message-based inter-component communication

That’s it. What did I leave out? Quite a few topics, if the truth be told, including:

  • Security
  • Transactions
  • Stateful versus stateless conversations
  • Messaging metadata
  • Messaging characteristics
  • Messaging protocol
  • Message content
  • Concrete technical implementation

These topics are important, but they muddy the waters. My definition distils SOA down to its core precepts, without losing the essence of the concept itself.

Note my reference to design patterns in the definition. This is key, in my opinion. SOA is not a new technology; in fact, one of its most attractive propositions is that it can leverage existing technologies easily and lend them a new lease on life. To my mind, SOA is like a blueprint, a set of best practices, or perhaps even a specification on how the next generation of software applications should be designed and implemented.

Fundamental SOA enablers

From the definition above, we should then be able to identify the minimal set of software services that must be provided to make up an SOA-enabled application. Succinctly, these services are:

  • A messaging layer, allowing the transmission and reception of messages over a specific protocol. In SOA parlance, this layer is called an enterprise service bus or ESB (so-called because you can charge more money for something with the word “enterprise” in the title).
  • A component model, i.e., some minimal contract to which an application must conform to send and receive messages from the message bus.

And, once again, that’s it. Depending on your specific business requirements, these two services can increase dramatically in terms of complexity, but, at the very core, the combination of a messaging layer and common component model represent SOA.

Specifically, I exclude the automatic lookup and discovery of services from my definition of SOA—in most Java EE scenarios, this would be overkill. One of the driving ideas behind the Universal Description, Discovery, and Integration (UDDI) protocol is the belief that companies will eventually buy and sell to each other using software services that trawl through a vast repository of services, searching based on metadata (cheapest, most local, best quality, etc.). This dream is, at best, at least 10 years away, and may never come to fruition—people do business and make deals, not software.

Java EE applications should not automatically, for example, discover a login or payment service to use—these services are set once, at initialization time. Don’t get me wrong, implementations of these services shouldn’t be hard-coded into an application either, but you don’t need SOA to solve that particular problem.

Next, let’s move on to consider what need SOA addresses and what, if anything, it replaces.

Why SOA?

The last two major waves of software development for enterprise applications centered on the client-server and n-tier architectures. While the n-tier architecture possesses some strong advantages over the client-server architecture in terms of ease of deployment, platform support, performance, and scalability, neither architecture solves one key software-engineering problem in the enterprise computing space: how to reuse functionality written for one application in another.

As software developers and architects, we have never adequately solved the issue of software reuse. And as you read further, you will see that I do not believe SOA can solve it either. Nevertheless, software reuse is, to my mind, the number one reason for the advent of SOA, at least for Java EE applications.

Other SOA uses exist—the most well-known are Jini and grid computing. Important characteristics for a Jini-based environment are:

  • Automatic discovery of components/services
  • Self-healing

However, these characteristics don’t apply or simply don’t hold the same importance for Java EE applications. I configure the location of my database using a JDBC (Java Database Connectivity) URL once and once only. I expect the database to provide fault tolerance and graceful failover (for example, Oracle Real Application Clusters, or RAC), and I specifically don’t want my Java EE application to try and auto-discover another database instance to use if my production instance goes down. On the other hand, a color printer that automatically advertises itself to an office with 2,000 workstations is a good thing and a key benefit to Jini-enabled hardware.

Equally, in a truly global grid-computing environment, automatic discovery and enlistment of computing resources to solve a problem at hand is a key part of the infrastructure—it isn’t in a Java EE environment where the hardware is sized up-front to meet a defined user population and performance service-level agreement.

My point is, then, that SOA means different things to different people. In this article, I am concerned with SOA from a Java EE architect’s perspective. And I believe that means functionality reuse. Other advantages to SOA from a Java EE perspective include:

  • Loosely-coupled components, which is always a good thing in software design
  • Potential total enforcement of “coding to the interface, not the implementation” by introducing the ESB as the messaging layer
  • Asynchronous messaging, which increases application scalability

Let’s examine the issue of software reuse in more detail by asking three specific questions:

  • Why is reusing software a very good thing?
  • How is SOA mooted to address the issue of software reuse?
  • Does the promise of SOA in enabling software reuse live up to reality?

Firstly, software reuse is a good thing for these reasons:

  • Efficiency in terms of time and cost—being able to take a suitable component off the shelf that meets a stated business requirement saves time and money on any project.
  • Superior characteristics, including, but not limited to, stability, performance, manageability, documentation, and configurability. Why? Because the more a component is reused across projects, the more a team/company has invested in it, and it will improve over time.
  • A well-designed reusable framework has a positive impact wherever it is used and can encapsulate best thinking on how to solve common problems—concrete design patterns if you will.

So we want reusability. What is the simplest way to get it? By packaging it as a set of well-defined components that meet a discrete functional requirement. Then, if another application needs the same component, it can be dropped in and used. There are other details to consider here, such as how do I configure it (Why, hello Inversion of Control, how are you?), but these details detract from the main thrust of my current point: to reuse lines of code written in any programming language, that code must have been designed as a set of discrete components or refactored to become that set.

Check out my first article for JavaWorld, “Frameworks Save the Day” (September 2000), for more details on software reuse as applied to Java EE projects.

Next, how does SOA approach the problem of software reuse? By building on the component model and by introducing an important mandatory requirement: that components communicate with each other via messages delivered on the ESB, thus ensuring loose coupling. In fact, the most widely deployed SOA implementation, Web services, can stitch together components developed in different programming languages by making the messaging layer technology neutral.

Lastly, does the promise of SOA in delivering software reuse live up to reality? No. I believe that SOA would solve the software reuse problem if it was invented in 1945, around the same time as the ENIAC (Electronic Numerical Integrator and Computer). But it wasn’t, and billions of lines of code now exist that have been written between then and now—in COBOL, C, C++, Java, C#, and a myriad of other languages, some long forgotten but still in production somewhere.

The bulk of this code mass is not written as a set of discrete components that can be hooked together to create new applications, and no amount of SOA orchestration magic powder will address that. In fact, I postulate that the lion’s share of work in any SOA brown-field project is spent refactoring the very same codebase that SOA is designed to give a new lease on life to.

Now, let’s examine some of the problems with SOA when applied specifically to a Java EE application.

A criticism of SOA

The criticisms of SOA in this section stem from three sources:

  • Deficiencies of SOA itself, based mainly on the immature implementations currently available
  • Thoughts on the complexity of SOA
  • Examinations of how vendors position SOA in the wider Java EE ecology of products and approaches

So, looking at SOA critically then:

  • There is no formal specification in the same way that Java EE has a specification. When one is eventually published, most likely, it will be too complex and won’t address the 80:20 rule (80 percent of applications need simple SOA; 20 percent need more powerful/complex capabilities).
  • The issue of stateful conversations is still widely debated and is certainly not adequately solved by the default implementation of SOA—Web services. Stateless conversations, on the other hand, are very well supported.
  • In the absence of a formal specification or recommendation, Web services has become synonymous in many people’s eyes with SOA, when, again, Web services is often overkill.
  • SOA adds complexity by default. Say what you like about hard coding and tight coupling; you don’t need reams of XML configuration files to get a simple application working!
  • SOA-enabling your application or product on its own achieves nothing. The business value comes from being able to expose discrete pieces of functionality through the SOA to other applications and modules. For example, if your validation routines for ordering widgets are poorly written in a JSP (JavaServer Pages) page’s embedded Java code, then you will need to refactor this code into a well-defined server-side object with an API before the SOA can call it—so many vendors gloss over this important point.
  • In some cases, vendors position SOA as a replacement for Web application frameworks! To my mind, a WAF is an ideal consumer of functionality defined through SOA, but it is complementary, definitely not competitive.
  • Contrary to what some vendors would have you believe, some applications do not need SOA at all and should simply use a decent Model-View-Controller Web framework with an efficient persistence strategy. Short-sighted? I don’t think so, and even if SOA characteristics are required, as stated above, the single most important prerequisite is a well-defined business logic layer that can be attached to an enterprise service bus, not the ESB itself.

But I do believe that an SOA has an intrinsic value once it is appropriately positioned and not regarded as a silver bullet for both existing and new applications. Let’s now examine how a staged approach to adding SOA characteristics to your application will add business value proportional to the cost of implementation.

A proposed SOA taxonomy

By now, you probably appreciate my zeal in keeping things as simple as possible. But I’m not after simplicity per se; my main driver is pragmatism. As applied to software projects, I define pragmatism as the correct balance between commercial and project realities on one hand and software design/engineering best practices on the other. Simply put, let’s build the best system we can, leveraging the resources we have available to us.

A great example of pragmatism comes from civil engineering history. Isambard Brunel (sometimes called the man who built the world) regularly built wooden bridges while constructing railroads even when he knew that iron bridges would be better. He constantly juggled the best engineering solution against the pressures from railroad company shareholders who wanted the rail line open and the initial capital investment controlled. Sound familiar?! Exactly the same principles apply to the software engineering discipline.

With this spirit of pragmatism in mind, I propose that we subdivide the SOA world into three sections: simple, medium, and complex, where the benchmark for separation is quite simply the features required to meet the business needs. If you need a simple SOA, then don’t waste time and money on a complex SOA.

Simple SOA: Level 1

Example implementations of a simple SOA:

  • Your own queue implementation with plain-old Java objects (POJOs) receiving and sending messages to the queue
  • Java Message Service (JMS) queue/topic with message-driven beans (MDBs) as consumers of messages

Key SOA concepts covered by the simple-complexity scenario:

  • Enterprise service bus
  • Component model for producers/consumers

Medium-complexity SOA: Level 2

Example implementations of a medium-complexity SOA:

  • JMS queue/topic with MDBs as consumers of messages, with additional attributes now enabled, including security, transactions, use of JMS metadata attributes on the core message classes, etc.
  • Web services, for example Apache Axis

Key SOA concepts covered by the medium-complexity scenario are the same as the simple SOA plus:

  • Error/retry queues for increased robustness and reliability
  • Introduction of XML as the message payload content instead of serialized Java objects to support other technologies, specifically .Net

Complex SOA: Level 3

Example implementations of a complex SOA include:

  • JMS queue/topic with MDBs as consumers of messages, with additional attributes now enabled, including security, transactions, use of JMS metadata attributes on the core message classes, etc.
  • Web services
  • Vendor/industry-specific SOA-enabling toolkits (especially for financial services)

Key SOA concepts covered by the complex scenario are the same as the medium complexity SOA plus:

  • A well-defined and rigorous component model (for example Java Business Integration, service component architecture, or something similar)
  • Enhanced vendor support, especially in the creation of new producer/consumer components to slot into the SOA
  • Finally, I see the need for a component registry to detail the services available on a particular SOA implementation

Conclusion

SOA as an architecture is here to stay and will become as embedded in our minds as “client-server” or “n-tier.” However, it is still relatively immature and falls prey to subjective vendor positioning at present. My advice? Start small and keep your SOA as simple as possible. Do not equate SOA to Web services by default, and do not try to force the SOA design pattern on all layers of your Java EE application, particularly the Web layer.

Which SOA implementation do I recommend for most Java EE applications? A Level 2 SOA implemented as a JMS queue with MDBs as message consumers, and POJOs or stateless session beans as message producers. However, if you are sure you will need to integrate with non-Java applications, consider a Web services implementation. It is important that the solution you adopt now has headroom for growth in the future. How far ahead to look is often the cue for debate, but I propose that the farthest forward we can look for any software application is 36 months. If you see additional SOA requirements in that timeframe, look to build them in now.

Humphrey Sheil, is chief technical architect for CedaropenAccounts, a UK supplier of enterprise applications for service industries. Sheil specializes in integration engagements. He holds a master’s of science in computer science from University College Dublin, Ireland and maintains his Weblog here.