JBoss.org Community Documentation

Chapter 3. Building services

3.1. Creating POJOs
3.2. Wiring POJOs together
3.3. Configuring a service
3.4. Testing a service
3.5. Packaging a service

Before we talk about building services using POJOs it is necessary to define what we mean by these terms.

POJOs

The term POJO is an acronym for Plain Old Java Object and was first coined while Rebecca Parsons, Josh MacKenzie, and Martin Fowler were preparing for a talk at a conference in September 2000. It describes the practice of encoding business logic in regular java objects instead of components such as EJB 2.1 Entity Beans. The benefit of this approach is that you're not required to implement any special interfaces. This not only keeps your code simple but allows it to be used in a wider variety of environments and makes it easy to unit test.

Definition: A POJO declares business methods, which define behaviour, and properties, which represent state. Some properties represent associations to other POJOs.

For experienced developers this should sound familiar as it mimicks almost exactly the proposals set out in the JavaBeans specification. JavaBeans describes a component model for User Interface development emphasizing simplicity and standardized naming conventions for property accessor methods. The idea was that this would allow automatic discovery of an object's properties so that an instance could easily be created and populated with state at runtime. The main use case was creating and configuring visual user interface components such as text boxes, buttons, and tables from within an Integrated Development Environment (IDE).

Definition: A Java Bean is a reusable software component that can be manipulated visually in a builder tool.

Importantly a Java Bean is not required to inherit from any particular base class or interface. Also while Java Beans are primarily targeted at builder tools they are entirely usable by programmers with conventional text editors.

Strictly speaking a Java Bean should include support for events and persistence but in many cases developers choose not to implement these features and simply follow the standardized naming conventions for property accessor methods; i.e. get and set. This 'lightweight' form of Java Bean is commonly referred to as simply a 'bean' and is semantically equivalent to a POJO.

The terms POJO and bean are therefore interchangeable and you will encounter both in the microcontainer documentation and configuration files.

Services

The word 'service' has many definitions in the English language but in the context of developing Java applications it is helpful to define it as follows:

  1. A service should perform work that is useful to multiple clients, thereby preventing each client from having to perform the work themselves.

  2. A service should have a name that clients can lookup at runtime to gain access. This provides a standard way to access different kinds of services and removes the need for clients to explicitly create them before they can be used.

  3. Internal changes to a service should not affect any clients. In practice this means that clients should access a service using a well defined interface so that the implementation can be changed without having to recompile any clients.

Using this definition we can now answer some simple questions:

Q) Is a POJO a service?

A) No, because although it performs work that is useful to multiple clients you cannot access it using a name. Also clients have to explicitly create a POJO themselves either directly using the new operator or indirectly using a factory.

Q) Does a class have to implement an interface in order to provide a 'well-defined' interface?

A) Not necessarily. Providing that we don't remove fields or methods from a class, or restrict access to them, we can always change its implementation without needing to recompile any clients. See the section entitled Resolution of Symbolic References from the Java Language Specification for more details.

The 'well-defined' interface in this respect is composed from the original class's fields and methods together with their access modifiers.

Note

Implementing an interface is only necessary if we want to allow a client to choose between alternative implementations . i.e. if the client is compiled against an interface then we can provide as many different implementations of the interface as we like without having to recompile the client. This is because the interface ensures that the method signatures do not change.

What then must we do in order to create a service using a POJO? The answer is to provide a naming mechanism that allows us to register a reference to the POJO instance with a name. Clients can then lookup the POJO reference using the name at runtime and use it to perform work. The POJO class is not required to implement an interface unless it is important that the client can choose between alternative implementations.

JBoss Microcontainer provides such a naming mechanism in the form of a Controller so that we can deploy our POJO services into a runtime environment such as Java SE and look them up from within our applications.

Since robust implementations of Java EE services are already available from JBoss.org and other communities it is common for companies to focus on creating more 'business-oriented' services. For this reason we shall look at creating, configuring and testing a simple Human Resources service that could potentially be used by a number of different applications.