a JEgg

What is JEgg

JEgg is a framework designed to reduce the complexity and cost of developing robust, multithreaded Java applications. Simpler code is faster to get into production, and saves development dollars.

Effective use of the Active Object design pattern, in which each active object has its own logical thread of execution, can facilitate the development of simpler, more robust multithreaded applications. JEgg provides a framework that supports this pattern and takes it a step further by supporting asynchronous, message-based communication between active objects.

The message-oriented aspect is essential to writing better code. Passing a message to an object is much safer than calling a method on it, and message-oriented objects are intrinsically loosely coupled and highly cohesive. Morever, the restriction to message-passing active objects is really no restriction at all; any Java object can be a message. The central difference is that an object's public interface is really the set of message types that it can "handle" instead of its public methods.

Multithreaded development in terms of JEgg active objects is much simpler than "straight Java" because the framework allows each active object to be implemented as if it were executing on its own distinct thread, without using the java.lang.Thread class. Instead, JEgg objects are assigned to physical threads via an application-level configuration file which allows JEgg objects to be assigned to separate threads or to the same thread(s), in any combination, without changing code or rebuilding the system.

Design of a complex application is never easy, but the execution independence of JEgg active objects, together with one-at-a-time message handling semantics, dramatically simplifies multithreaded application development without reducing the sophistication that you require. In fact, higher levels of sophistication become cost effective because your code is more focused.

How to JEgg

The essential steps in a constructing a JEgg-based application are:

  • Design your application in terms of active objects that communicate by exchanging messages rather than through method invocations.
  • Construct the active objects by implementing a special JEgg framework interface, or for convenience, by extending a special base class provided by the framework.
  • Write the application descriptor, which is a simple XML file that describes which objects will send messages to which objects.
  • Execute the application using the JEgg application launcher, which reads the application descriptor, loads the application eggs (active objects), and "wires" them together (so they can communicate). The framework also provides a mechanism for eggs to dynamically create and locate other eggs at runtime, as necessary.

Designing an application in terms of messaging active objects may require you to think a little differently, but it should quickly feel natural since it's completely object-oriented. Additionally, the JEgg framework includes facilities to make the implementation easy so that you spend more time write application code and much less time writing "infrastructure" and error-handling code. Error handling is always necessary - no framework can avoid that - but the error handling that's left for you to implement should be at the application level.

More Details

JEgg objects are called eggs because their external aspect is featureless, like an egg. They have essentially no program API (public methods) because they aren't needed - eggs only communicate by sending and receiving messages. Each message is delivered by the framework to the egg it's addressed to and handled by your application logic. One-at-a-time message semantics is enforced by the framework which ensures that a given egg is not delivered its next message until it has finished handling the current message. The framework provides a way for an egg to send a message in response to the current message without having to explicitly reference the egg that sent the current message being handled. Also, a mechanism is supported to allow message "broadcast" to a group of eggs.

The physical artifacts of a JEgg application are the application eggs, the message types they exchange, and whatever other passive classes your application needs. Relationships between the eggs are expressed not in code but in the JEgg application descriptor which is a simple XML file that essentially enumerates the application eggs and describes which eggs will exchange messages with which other eggs. The framework also allows these relationships to be specified dynamically, or not at all. Eggs can register themselves with a built-in naming service that other eggs can use to look them up in order to send them messages.

The XML descriptor also allows you to assign eggs to one or more message dispatchers. In JEgg parlance, a message dispatcher is called a "basket" (really, what else would you call it?). Sometimes you can put all of your eggs in one basket, in which case they will all execute on the same physical thread, having their messages delivered by the same message dispatcher. jEggs that can take a long time to handle a message should be assigned to their own individual message dispatcher, or basket, but this assignment is made in the application descriptor, not code, so it's easy to change. Often, though, the application will have eggs that execute relatively infrequently, and those eggs can certainly all go in the same basket.

During execution, the message dispatcher assigned to an egg queues incoming messges for that egg and delivers them one-at-a-time to the egg by using reflection to deliver a given message to the egg's overloaded handle method which has an argument type that most closely matches the message's concrete type. Conceptually, each egg handles mesesges completely independently of what any other egg is doing. Physically, multiple eggs may be handling messages on the same Java thread, but not concurrently. The needs of your application will determine which eggs require a dedicated physical thread and which can share.

So, where are the threads? They are the message dispatchers that deliver the messages to your eggs, one at a time. Conceptually, each egg executes completely independently of all other eggs, and this dramatically simplifies application design. Behind the scenes, Java threads are assigned to the message dispatchers that deliver messages to the eggs, and the application descriptor allows you to assign eggs to the same dispatcher or a different one. Consequently,

  • You don't have to think about physical threads while you are writing the application logic. Each egg logically executes independently of every other egg.
  • You effectively assign eggs to threads at configuration time, in the JEgg XML application descriptor, based on the needs of the egg. The assignment is not done in code which has to be recompiled if you change your decision.

See the FAQ and the JavaDocs for more details, especially the jegg.* package documentation. Also see the samples.