By Johan O. Nielsen and Alex J. Plans
A new drive in the Java community seeks to expand the language’s applicability to safety-critical where failure puts lives at risk. Once final, this new profile for the popular language will help enable software engineers to write Java programs with unprecedented levels of reliability.
Safety-critical systems may be involved in supporting life, such as an implantable defibrillator unit, or may be involved in tasks where a mistake can imperil lives, such as an automotive drive-by-wire steering system. The greater the risk to life and property, the more critical the need for robust software. The JSR-302 Experts Group aims to have safety-critical Java meet the requirements of the DO-178B standard Level A, which certifies software for avionics systems.
Software designs must be reliable, either by providing high-availability through system error detection and fail-over or by being fail-safe. Fail-safe designs are those that will always enter a safe state regardless of the failure mechanism.
To do this, software not only must be deterministic, with no possibilities of an unknown or unexpected response, but also undergo rigorous testing of all possible branches within the software. The ideal programming language for safety-critical software would allow succinct implementation of the design, avoid error-prone constructs, ensure a high degree of checking by the compiler, and still enable traceability from source level to object code level.
Newer, more expressive languages do well on the first three but easily suffer on the last. Older and simpler languages often do poorly on the first three but offer good traceability. The choice is not trivial.
Traceability from source level to object code level means that actions at the source level can be mapped to the object code and vice versa. Traceability helps meet the requirements on safety-critical software. If the language generates branches in the object code that do not correspond to actions at the source level, testing and documentation become more difficult and costly.
Similarly, the language should produce finished code that is 100 percent testable to prevent “dead code” within the program. Safety-critical systems can be very difficult and expensive to develop and often require long operational lifetimes. Popular languages like Java can help ease staffing issues and reduce long-term maintenance costs.
Ada or C++
Two major languages available to safety-critical system developers today are C++ and Ada. Both are powerful object-oriented languages that enable the developer to prevent software elements from interacting. Neither, however, possesses all the desired technical and cost-effectiveness characteristics of the ideal language.
C++ is popular and has widespread tool support, which help assure a steady supply of qualified programmers and powerful development tools. Unfortunately, the language requires that programs perform heap management—allocating and freeing memory—on their own. It also explicitly uses pointers to locations in memory, which create opportunities for error.
Errors like memory leaks may arise, which constitute a failure to free allocated memory, which causes elimination of available memory and eventual software failure. Explicit use of pointers to memory also can complicate analysis to identify leaks during design. Pointers also open the door for errors where one program compromises another by altering the wrong memory locations. If design tools do not automatically enforce the standards, errors can creep in anyway.
Problems like these prompted the U.S. Military to develop the Ada language, which provides features for safety-critical applications like preventing developers from creating functions accidentally that compromise other functions. Ada also has design rules and architectural constructs that simplify and speed code testing.
Ada also has its drawbacks, however. Ada development tools are relatively limited, and its identity as a military language has limited Ada’s widespread adoption. Experienced Ada programmers are hard to come by, and the language is expensive to certify.
Java for safety
Java, on the other hand, has state-of-the-art development tools, many experienced programmers, and a structure that enforces object-oriented programming constructs to prevent design flaws. Java also has a secure architecture designed to take the risk out of downloading and running applications programs of uncertain origin. It’s so-called “sandbox” operating environment prevents programs from accidentally interacting, and prevents malicious programs from seizing system control.
Java originally was for non-real-time desktop computers. Later, the Real-Time Specification for Java (RTSJ) bounded application response times and helped make Java more deterministic. Still, current Java standards fall short in one crucial area: traceability.
Java programs run under an interpreter called the Java Virtual Machine, which interprets Java Bytecodes and controls software execution. This can create headaches for safety-critical system designers. Java’s breadth of capabilities implies a need for a large interpreter, which any given Java program will not exercise. This means Java programs inevitably include unnecessary code that testing cannot reach.
Some of Java’s automatic features complicate timing and resource analysis. One of the most significant is Java’s automatic “garbage collection,” which eliminates memory leaks by automatically freeing unused memory. In some implementations, this operation runs as a background process. As a result, however, garbage collection is non-deterministic and outside of user control. It can occur at any time, so that timing and resource aspects may vary from run to run depending on when during the execution garbage collection is initiated. Such variability is unacceptable for safety-critical systems.
Another implementation strategy for garbage collection is to have the Java compiler intersperse code of its own with code that implements the Java source. This approach can help software developers bound garbage collection in time. This approach is not satisfactory for safety-critical systems, however, because it inserts additional paths into the code and thus prevents traceability from Java source to final code.
Still, Java is appealing, and language proponents do not want to give up on safety-critical applications. The JSR-302 Expert Group formed in August 2006 to define the baseline language specification and programming guidelines for such applications.
The JSR-302 Group’s approach has been to start with the RTSJ as its basis. From there the JSR-302 Group is taking steps to limit the size of programs and the Java engine by restricting the Safety-Critical Java (SC Java) implementation to the core features that a system must have in order to operate.
This reduction will not change the programming language significantly, so SC Java will be easy for today’s Java programmers to adopt. Instead, the specification will simply restrict which predefined classes will be available to the safety-critical developer. Some restructuring of Java may also be required in order to avoid the accidental use of forbidden constructs. In addition, programmers will have to follow new programming rules to avoid introducing timing uncertainty.
These changes will eliminate some of the standard features of Java but give the language greater predictability for program execution. SC Java will also provide the means for avoiding features such as garbage collection, dynamic class loading, and just-in-time compilation. In combination, these restrictions will permit replacement of the full Virtual Machine with inline code implementing the actual functions in use, a key to determinism and testability.
SC Java deliverables
When the definition of SC Java is complete, the JSR-302 Group plans on delivering the specification, a reference implementation, and a test suite. The specification will define SC Java as precisely as possible, and is expected to include templates that provide a top-level structure for applications. The reference implementation will provide an example of correctly handling the specification that can serve as a guide for other implementations. The test suite will allow developers to verify that their implementations are in compliance with the specification.
The work of the JSR-302 Group is only a beginning. The industry must provide new analysis tools that will help developers enforce the programming restrictions of SC Java. The industry may also develop SC Java implementations containing additional safety-related features and create application notes showing effective uses of tool sets. These activities are beyond the scope of JSR-302, however, and will fall to individual vendors.
The time for a safety-critical implementation of Java has arrived. The languages currently in use suffer restrictions that contribute to high development costs for such applications. An ability to leverage Java’s strengths in providing software security as well as leverage the widespread expertise and support for Java is a key element of the new specification that will help lower costs and speed development.
Johan O. Nielsen is a senior software engineer at DDC-I in Phoenix, and the company’s representative member of the Safety-Critical Java Expert Group (JSR 302). Alex J. Plans is a senior software engineer at DDC-I.