There are a number of stages in the program lifecycle during which a program author or user can specify the functionality of a class or set of classes. Some examples of tools used at different stages are detailed in Table 1. Originally, of course, the base functionality is declared by the class author in source code, and that source code is translated into an executable by a compiler.
Authors or users can employ post-processors such as instrumentation tools to insert new method calls into an existing executable image. A popular example of this is the tool ATOM [SE94], which works on executable images for the Alpha processor; similar functionality is available for Java with BIT [LZ97]. Most often, this instrumentation is used for performance analysis or as an interface to platform simulation. An important guarantee typically made by instrumentation tools is that the semantics of the original program are not changed. However, Shasta [SG97] processes executable images to run on distributed shared memory systems. Object Design Incorporated's ObjectStore PSE [Obj98] also uses a post-processor, to insert persistence methods into existing code. Rational Software Corporation's tool Purify [Rat98] changes code to detect memory leaks.
Multiple third-party components (classes or more often collections of interacting classes) are integrated during application composition. In Java, these components are known as Beans and are often handled in visual builders. This composition allows consumers of code--either end-users or programmers using components in their own application--to modify certain properties of the component. However, users can only modify those properties foreseen by the original author; they cannot independently add features except through the basic object-oriented techniques of inheritence.
After application composition, the classes are eventually loaded into the environment. During execution, the bytecodes can be translated into native local platform instructions by a Just-In-Time compiler (JIT). JITs only reimplement the bytecodes in a different language; they do not add new functionality (although JITs may transform the code for optimization, for example unrolling loops or reordering instructions).