devxlogo

Serialize JVM Execution Context with a New Programming Library

Serialize JVM Execution Context with a New Programming Library

elare Technologies’ ATCT (Asynchronous Transfer of Control Threading) is a versatile new programming library that implements a “separation of concerns” approach?one of the key precepts of aspect-oriented programming?to enable programmers and framework developers to create scalable systems capable of complex execution paths with very simple source code.

This article presents two specific situations in which ATCT makes the developer’s job easier, asynchronous messaging and Java scripting. Applied to asynchronous messaging, it simplifies the structure of the code and makes it linear. Applied to scripting engines, ATCT overcomes a current limitation of the JVM. Finally, some internal details about the library are provided with a look under the hood.

ATCT and Asynchronous Messaging
Today, most asynchronous messaging technologies use some form of callback mechanism. Programmers implement one or more interfaces that define a behavioral contract with the underlying messaging engine. When the proper circumstances arise, the engine calls into the client code via a method designated for that purpose. One very popular Java messaging technology is JMS. In the case of JMS 1.1, the interface is called MessageConsumer and the method is onMessage(). The JMS specification guaranties that your code is invoked for each incoming message.

Figure 1 shows a sequence diagram that illustrates a generic asynchronous messaging call sequence. The concept applies, but is not limited, to JMS as the messaging engine. Other possible asynchronous messaging technologies include the upcoming SOAP 1.2.

Typical sequence diagram for an asynchronous messaging system
Figure 1: Typical Sequence Diagram for an Asynchronous Messaging System

To better understand Figure 1, think of Step 3: verifyCreditCard() as a request that the back end of an online travel agent would issue prior to authorizing an airplane ticket purchase. A real-life business process might include the additional steps of checking the customer’s rewards point account balance or the availability of sufficient funds. This messaging approach affects the structure of the code. Firstly, it splits the process controller code: one portion sends the request while the second processes the response. Secondly, it requires glue code to maintain some internal state data between successive calls to the messaging engine. This generally takes the form of a persistence store that tracks the details of pending transactions until the response messages are received. The store itself can be anything from a simple HashMap to a relational database.

Multiply the call sequence by the number of messages necessary to implement the complete business process and the code can rapidly become unmanageable. Enter ATCT. Using this technology, programmers can turn the code showed in Listing 1 into the more maintainable code in Listing 2. The entire business process now resides inside one single method. But more importantly, Listing 2 hides the complexity of dealing with the underlying asynchronous system (see Figure 2 for an ATCT version of the sequence diagram in Figure 1). The new code is linear, flowing from one step to the next sequentially, even though some of the method calls wrap around complex asynchronous call sequences. (View the accompanying source code for more details. Although not a working sample, it illustrates the concepts described in this section.)

ATCT Sequence Diagram for an Asynchronous Messaging System
Figure 2: ATCT Sequence Diagram for an Asynchronous Messaging System

The next section covers how using ATCT with new enhancements to the JVM extends current scripting engines.

ATCT for Scripting Engines
The simplicity and wide cross-platform availability of the JVM have spawned many alternative languages that target it as their run-time environment. Some languages are native compilers that directly generate bytecode, while the others are run-time interpreters. Two types of interpreters exist: the ones that implement their own internal execution stack and those that rely on the JVM’s internal stack. However, all these languages share a common limitation inherent to the JVM itself: no way to control the execution stack of the Java bytecode interpreter. Consequently, the interpreters that rely on the JVM cannot offer continuation: the ability to suspend/resume a method’s execution at will. Continuation is a fundamental requirement for scripting a series of asynchronous events.

The programmers of the Apache Cocoon framework are keenly aware of this limitation and discussed it at length. Their powerful Web development framework allows the creation of Web sites using XML documents. It also includes the interesting ability to control the flow between a series of Web pages using a simple script interpreted at run time. This functionality relies on the scripting engine’s ability to support continuation. The JVM’s lack of support for this feature drastically limits the choice of scripting languages that developers can use with Cocoon or in any other similar situation.

To be able to suspend/resume the execution of bytecode would require storing the following state information about the JVM:

  • Program state: bytecode of the object’s class
  • Data state: the content of the instance variable inside the Java class
  • Execution state: the content of the VM’s pc register, allowing it to sequentially execute the code at the proper location; plus the content of the stack associated with the Thread executing the bytecode. The stack is made of a series of frames. Each frame holds the content of the local variables declared in each of the methods for which the VM has not reached an exit point yet.
  • Currently, Sun offers no direct way to access the execution state. ATCT is the first portable technology to offer unrestricted Java continuation. Curious about how Velare solved this problem? The next section breaks it down.

    Under the ATCT Hood
    Java owes part of its success to some key features, including:

  • Reflection: the ability to discover at run-time the true nature of an object
  • Serialization: the ability to store the complete state of an object’s instance and restore it at a later date.
  • A very simple and consistent multithreading programming model?even on platforms without native support for threads?based on the Thread class
  • Unlike many of the other standard Java objects, Sun unfortunately did not make the Thread class serializable, preventing developers from saving the JVM’s execution context.

    ATCT provides an elegant and powerful solution to the continuation and serialization problems. Its ATCThread class contains a complete bytecode interpreter with its own private execution context. This solution is pure Java and portable across virtual machines. Effectively working as a secondary interpreter, ATCThread uses reflection to draw on the JVM for much of its core services while supplementing it with the following:

  • Method discrimination, allowing programmers to decide which interpreter should execute any given method
  • The ability to force a context switch between interpreters at will from anywhere in the code
  • Tail call elimination, support for shortcutting the return path from a method when it is immediately followed by a return instruction inside the body of the calling method
  • ATCThread provides the following methods to completely control the execution of bytecode in the secondary interpreter:

  • start(): starts the execution of a method in the secondary interpreter, using an internal Thread
  • suspend(): pauses the secondary interpreter. While it is in that suspended state, a developer can serialize the interpreter to a file and store it indefinitely.
  • resume(): resumes execution of the bytecode in the secondary interpreter
  • ATCT offers another way to momentarily suspend the ATCThread interpreter: declare a method as throwing an ATCSignal exception. When the ATCT interpreter runs into an invocation of that method, it simply ignores the method body and returns control to the native interpreter. Called from the native JVM interpreter, the same method body would be executed normally. Similarly, ATCThread uses the AISignal exception to discriminate the code that it should execute.

    This tried and tested code-marking technique is already familiar to EJB and RMI developers. If it is not flexible enough for your situation, the ATCT API lets you implement custom discrimination heuristics. The upcoming Java 1.5 will offer an interesting alternative scheme with its new declarative programming style.

    ATCT Adds Features to Java
    Velare Technologies is adding some interesting new features to core Java with ATCT. The library simplifies the programmer’s job in the two areas reviewed in the previous sections. Other possible uses include game scripting engines (using continuation), a simple failover scheme, grid computing, and the creation of some simple agent frameworks where an ATCThread could be sent across the network and deserialized on a different JVM.

    devxblackblue

    About Our Editorial Process

    At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

    See our full editorial policy.

    About Our Journalist