4 2011 605– 619c World Scientific Publishing Company DOI: 10.1142/S0218194011005281 VERIFYING JAVA OBJECT INVARIANTS AT RUNTIME THU-TRANG NGUYEN Hanoi University of Technology 1, Dai Co
Trang 1Vol 21, No 4 (2011) 605– 619
c
World Scientific Publishing Company
DOI: 10.1142/S0218194011005281
VERIFYING JAVA OBJECT INVARIANTS AT RUNTIME
THU-TRANG NGUYEN
Hanoi University of Technology
1, Dai Co Viet, Hai Ba Trung, Hanoi, Vietnam
trangntt-it@hut.edu.vn
College of Technology, Vietnam National University
144, Xuan Thuy, Cau Giay, Hanoi, Vietnam
Received 10 February 2009 Revised 17 February 2010 Accepted 13 June 2010
An object invariant consisting of a set of properties that must hold for all instances of
a class at any time is usually used in object-oriented design However, verifying object invariants at runtime is always a challenging task in software verification This paper proposes a method for verifying invariants of Java objects at runtime using AOP Sup-pose that a software application is designed using UML models and its constraints are specified in OCL expressions, the software is then implemented, by default, using the UML design They propose to construct verifiable aspects which are automatically gener-ated from OCL constraints These aspects can be woven into Java code to check whether object invariants are violated at runtime Benefiting from AOP in separation of crosscut-ting concerns and weaving mechanisms, generated aspects can do the verification task whenever values of objects’ attributes are changed A Verification Aspect Generator (VAG) tool has been developed allowing the automatic generation of verifying aspects from the UML/OCL constraints.
Keywords: Software verification; OCL invariant; runtime; AspectJ; AOP.
1 Introduction
Object-oriented programming has become a dominant programming paradigm in industry with its preeminent style for implementing complex programs including a large number of interacting components Successful implementation of object tech-nology requires a method that integrates a development process and a modeling language with suitable construction techniques and tools
The Unified Modeling Language (UML) [16] is a family of graphical notations helping to specify, to visualize, to construct, and to document the artifacts of
605
Trang 2software systems [4] It is used particularly in software systems of object-oriented style The UML represents a collection of best engineering practices that have proven successful in modeling large and complex systems
A UML diagram, for instance a class diagram, is typically not refined enough
to provide all the relevant aspects of a specification of additional constraints about the objects in the model Practice has shown that describing such constraints in natural language will always result in ambiguities In order to write unambiguous constraints, so-called formal languages have been developed However, traditional formal languages are easily manageable to specialists with a strong mathematical background, but difficult to use for average system modelers The OCL (Object Constraint Language) [14,27] has been developed to overcome this obstacle The OCL is a textual extension of the UML It promises ease of use, object-orientation and the adaptability of well-known formal analysis methods [15] The OCL allows to describe three principal types of constraints: invariant, precondi-tion and post-condiprecondi-tion From the OCL specificaprecondi-tion, invariants must hold for all instances of a class at any time [14]
Indeed, the guarantee of the correctness and quality of software systems is becoming more and more important and considered as the dominant research goal
in software engineering In this aspect, one of the most challenging tasks is the ver-ification of object-oriented applications due to their popular efficiency in software development
Many papers have dealt with the verification of object invariants in object-oriented applications [5,7,19,22] However, the works reported so far only focused
on the invariant verification by reasoning but none of them concerns the execution time of the program
With the development of software engineering, Aspect-Oriented Programming (AOP) [23] has emerged as a new methodology This provides a possible separa-tion of cross-cutting concerns by introducing a new unit of modularizasepara-tion as an aspect, which can be woven into the core modules following the weaving rules The power of AOP comes from the economical way in which the weaving rules can be expressed AspectJ [1,13,18] is a general-purpose, aspect-oriented extension to the Java programming language
In this paper, we propose a method for the verification of the object-invariants correctness at runtime If we use UML/OCL as an object modeling and specifying language for the software system, the UML model is then implemented in Java by programmers We consider the transformation of the OCL constraints in the model
to aspects in AspectJ Aspects are then woven to the implemented Java code by the AspectJ compiler to obtain the final program When the final program executes, the woven code can detect whether values of objects’ attributes violate their invariants
To automatically apply this method in the practice, we have developed a Ver-ification Aspect Generator tool and called it by the abbreviation VAG This tool accepts as inputs the UML model in an xmi file and the OCL invariants in an ocl file, and it provides verifying aspects specialized in AspectJ as outputs This tool also allows users to save these aspects into aj files, which are then woven into the
Trang 3Java application The proposed method and tool can be used in the testing phase
of software development, including unit test, integration test, acceptance test, etc
to ensure the invariant preservation throughout the program execution
This paper is organized as follows Section 2 briefly introduces the background
of UML, OCL and AspectJ Section 3 presents our contribution, a method to verify Java object invariants at runtime Implementation of the support tool is presented
in Sec 4 Section 5 discusses related works In Sec 6, we conclude the paper and give some future works
2 Background
We present in this section an overview of UML/OCL, a language for specifying the structure and constraints of object-oriented applications After that, we give a sketch of AspectJ, a practical aspect-oriented extension to Java
2.1. UML and OCL
The Unified Modeling Language (UML) [6] is a standard from the Object Man-agement Group (OMG) [20], proposed as a semi-formal specification language for object-oriented specification and design
The Object Constraint Language (OCL) [14, 27] is an attempt to extend the UML by a more formal specification language UML itself contains several different diagrams for example state diagrams, collaboration diagrams, sequence diagrams, etc whereas OCL is a textual specification language, which is suitable for refinement
of the UML diagrams by writing constraints on them
One of the most important diagrams of the UML is the class diagram, which describes the types of objects in the system and the various kinds of static relation-ships that exist among them Class diagrams also show the properties and operations
of a class and the constraints that apply to the way objects are connected
In order to illustrate UML class diagrams and OCL constraints, we give an example of a simple credit banking system This system describes the relationship and activities between a bank and its customers The customers may be companies
or persons A customer of a bank (a person or a company) can open one or many credit accounts in the bank A given mortgage is used to secure an arbitrary amount
of credit accounts and each credit account must be secured by at least one mortgage This model is specified by a class diagram in Fig 1 with four classes:Person, Company,CreditAccountandMortgage
The OCL expressions typically specify invariant conditions that must hold for the system being modeled or queries over objects described in a model When the OCL expressions are evaluated, they do not have side effects (i.e., their evaluation cannot alter the state of the corresponding executing system)
In the context of UML class diagrams, OCL is used to describe class invariants, pre-conditions and post-conditions of methods Following the OCL specification [14], invariants must hold for all instances of classifiers at any time The pre-conditions
Trang 4CreditAccount Company
−value:double
−description:string
−accountNo:long
−opennedDate:Date
−monthlyInterest:double
−vbalance:double
−duration:int +getBalance():double +deposit(amount:double):void +withdraw(amount:double,feeRate:double):void
−companyNo:int
−name:strin
−taxCode:long
−address:string
−expireDate:Date
*
mortgages mortgages
securities
owner
company
employee credits
*
credits company
*
value
Person
−gender:string
−age:int
−monthlyIncome:double
−name:string
Fig 1 An example of class diagrams.
for a method describe the requirements on the program state before the method invocation The post-conditions for a method describe the requirements on the state after the method invocation
Further, the concept of associations with multiplicities in UML can be under-stood as an abbreviation for relations with certain constraints, which can be expressed in OCL It is easy to see that the multiplicity expressed at one end
of the association can be converted directly to an invariant at the other end
In this paper, we consider to use OCL for specifying Java object invariants and for checking them at runtime The following constraints represent invariants of the classes in the model:
(1) The age of a person must be greater than 0 This invariant is shown in Listing1
Listing 1 A simple invariant for age
c o n t e x t P e r s o n inv m i n i m u m A g e : s e l f age > 0
(2) The balance of a credit of a person must be at least 100 USD, and the balance
of a credit of a company must be at least 1000 USD These invariants are illustrated in Listing2
Listing 2 Associated invariants for balance of CreditAccount in P erson and Company
c o n t e x t P e r s o n inv m i n i m a l A m o u n t P e r s o n : s e l f credits - > f o r A l l ( balance > = 1 0 0 )
c o n t e x t C o m p a n y
Trang 5(3) The sum payable of all monthly rates of all credits of a person may not surpass 50% of his/her monthly income and after paying all the rates the Person must have at least 1000 USD available Listing3illustrates these invariants
Listing 3 Associated invariants for some attributes of CreditAccount in Company
c o n t e x t C o m p a n y inv m i n i m a l A m o u n t C o m p a n y : s e l f credits - > f o r A l l ( balance > = 1 0 0 ) inv m i n i m a l I n c o m e : m o n t h l y I n c o m e
-s e l f c r e d i t -s m o n t h l y R a t e * -s e l f c r e d i t -s balance - > -sum ( ) > = 1 0 0 0
The first OCL constraint, called a simple property, concerns only attributes
of one class The last two constraints, called the associated constraints, relate to attributes of some objects in the model
The first invariant means that, when the program is executed, for all objects of thePersonclass, at any time, the value of theageattribute has to be greater than 0 Similarly, the value of thebalanceattribute of anAccount object, which belongs to a Personobject is always at least 100 USD EveryAccountobject belongs to aCompany class has to be greater than 1000 USD, etc
The problem given here is how to verify whether any attribute value of Java objects violates OCL invariants in the model at runtime of the program If there is any violation, the program must take some actions such as logging and/or tracing this violation according to the system requirements
2.2. AspectJ
AOP has been widely applied to different languages but the most influential imple-mentation is AspectJ [1, 13, 18] AspectJ is a seamless aspect-oriented extension
of the Java programming language [2] that enables clean modularization of these crosscutting concerns An AspectJ compiler produces class files that conform to the Java byte-code specification, allowing any compliant Java virtual machine (JVM)
to execute those class files By using Java as the base language, AspectJ passes on all the benefits of Java and makes it easy for Java programmers to understand the AspectJ language The task of integrating the crosscutting concern code and the
primary application to run as a complete system is called weaving.
In AspectJ, the implementation of the weaving rules by the compiler is called crosscutting; the weaving rules cut across multiple modules in a systematic way in order to modularize the crosscutting concerns AspectJ defines two types of cross-cutting: static crosscutting and dynamic crosscutting
Dynamic crosscutting runs additional code when certain events occur during program execution The semantics of dynamic crosscutting is commonly under-stood and defined in terms of an event-based model Most of the crosscutting that happens in AspectJ is dynamic Dynamic crosscutting augments or even replaces the execution flow of core program in a way that cuts across modules, thus modify-ing the system behavior For example, to specify that a certain action be executed before the execution of certain methods or exception handlers in a set of classes,
Trang 6simply specify the weaving points and the action to take upon reaching those points
in a separate module
Dynamic crosscutting includes concepts of joinpoint, pointcuts and advices As
a program executes, different events fire These events are called joinpoints
Join-points are identifiable Join-points such as method calls, constructor invocations, excep-tion handlers, or other points in the execuexcep-tion of a program In AOP, everything revolves around joinpoints, since they are the places where the crosscutting actions
are woven in A pointcut is a well-defined location in aspect when it should match the joinpoint so it corresponds with a grouping for specific joinpoints An advice is
a piece of method-like code used to define additional behaviors at joinpoints that executes when the application reaches a joinpoint In AspectJ, the advice code can execute at three different places when a joinpoint is matched: before, around, and after the called method
While dynamic crosscutting modifies the execution behavior of the program, static crosscutting modifies the static structure of the types (the classes, interfaces, and other aspects) and their compile-time behavior There are four broad classifi-cations of static crosscutting: member introduction (inter-type declaration), type-hierarchy modification, compile-time error and warning declaration, and exception softening Inter-type declarations allow programmers to modify the static structure
of classes (methods and relationships between classes) The most common function
of static crosscutting is to support the implementation of dynamic crosscutting
In this paper, we use inter-type declaration to support dynamic crosscutting in verifying invariants
Aspects in AspectJ are then defined in a similar manner as Java classes, but they add joinpoint, pointcuts, advices, inter-type declarations type-hierarchy modifica-tion, compile-time error and warning declaramodifica-tion, exception softening and ordinary Java member declarations They are the unit in which crosscutting concerns are modeled in AspectJ
With static and dynamic crosscutting, Aspect-Oriented Programming technol-ogy is strong enough to do any actions: logging, tracing, throwing exceptions, pre-venting joinpoint execution, etc when a joinpoint is matched
3 Verifying Object Invariants at Runtime
In order to check constraint conformance of Java objects at runtime, we pro-pose a verification process summerized as follows (Fig 2) (i) Firstly, designers compose the UML models and OCL constraints from the analysis document (ii) Java source code is then implemented from UML models by developers (iii) We define rules allowing verification aspects to be generated from UML/OCL constraints
Advices in these aspects are then woven into the Java application by AspectJ compiler to obtain the final program The weaving process must follow special weav-ing rules of pointcuts in the aspects The final program now contains pieces of
Trang 7(self-verifying code)
AspectJ advices Java codes
generate
implement
weave
UML model
OCL constraints
Final program
Fig 2 Verification process overview.
self-verifying code, which are pieces of normal executable code but they can check invariant violation by themselves at any time during the execution
Listing 4 A template for aspect generation
p r i v i l e g e d p u b l i c a s p e c t A s p e c t N a m e {
p o i n t c u t P o i n t c u t N a m e ( O b j e c t T y p e obj ):
t a r g e t ( obj )&& set ( A t t r i b u t e T y p e O b j e c t T y p e a t t r i b u t e );
a f t e r ( O b j e c t T y p e obj ): P o i n t c u t N a m e ( obj ){
// C h e c k if t h e v a l u e of t h e a t t r i b u t e is c h a n g e d
if ( a t t r i b u t e of the o b j e c t v i o l a t e s i n v a r i a n t c o n d i t i o n )
p r i n t I n f o ; }
}
Recall that coding phase can be done by developers while weaving phase can be done
by AspectJ compiler Therefore, the main problem in our method is how to build verification aspects from UML/OCL constraints In order to generate verification aspects, we have built some templates of aspect for corresponding type of invariant One of these templates is illustrated in Listing 4 Two main phases needed to take into account in the process of automatically generated aspects: OCL Parsing and Aspect Generation
3.1. OCL parsing
In order to grasp OCL constraints’ semantics, they must be parsed to a syntax tree Firstly, OCL constraints are used as the input to analyze to make a Concrete Syntax Tree (CST) The CST and UML specification are then transformed to an Abstract Syntax Tree (AST) Finally, this AST is used as the input to generate verification aspects
3.2. Generating verification aspects
From the AST input, it is not difficult to get information of OCL constraints from its leaves In detail, from the leaves, we can identify the value ofcontext(corresponding
to a class name in UML model), relationship name between classes, attributes of
Trang 8classes or operators, basic values, and collection operations (such asforAll,select, sum,count ) Two principal kinds of invariant are presented in OCL:
• Simple or combined invariants: In the expressions, there are only leaves related
to attributes of one class, operators on predefined types (such as+,-,*,/,and,or, implies, etc.)
• Associated invariants: In the expressions, there are also leaves related to
asso-ciations between classes The association ends can be 1 (in 1-1 relationship or 1-end of 1-n relationship) or n (n-end of 1-n relationship) through collection
operations
After analyzing the AST to get related information about invariant expressions,
we can follow our algorithm to generate the verification aspects Whenever the value of any object attribute is changed, it is necessary to check whether it violates OCL invariants or not That means we need to add some pieces of code to verify constraints bound to attributes of an object Therefore, dynamic crosscuts need
to be implemented In this context, static crosscuts are used to support dynamic crosscuts in some particular cases
In order to determine when values of attributes are changed, pointcuts are defined to specify where the joinpoint in the core module is Since invariants are bound to attributes of objects, which are data members of a class, the joinpoint
must be field write access joinpoint [18] That means, whenever and wherever field assignment occurs, the joinpoint will be matched and advices of the matched point-cut will be exepoint-cuted to verify this change Advices contain pieces of code for checking invariants, which are inserted before or after setting new value to attributes
3.2.1 Simple/combined invariants
To verify simple or combined invariants,a we use just dynamic crosscuts Each attribute in a simple/combined invariant corresponds to a pointcut statement For this pointcut, there must be pieces of verification code that are advices to check if the new value of this attribute satisfies the OCL invariants
If the invariant expression is violated, some loggings should be given such as the invariant violation or other information of related objects For the logging pur-pose, to get any attributes’ value of related objects, the generated aspect should be declared asprivileged That means the aspect can access directly any attributes of objects regardless of their access modifiers
Listing 5 A sample aspect for a simple invariant
p r i v i l e g e d p u b l i c a s p e c t P e r s o n V e r i f i e r {
p o i n t c u t p c _ v e r i f y _ a g e _ P e r s o n ( P e r s o n obj ):
t a r g e t ( obj )&& set ( int P e r s o n age );
aCombined invariants combine several simple invariants concerning only attributes of one class.
Trang 9a f t e r ( P e r s o n obj ): p c _ v e r i f y _ a g e _ P e r s o n ( obj ){
// C h e c k a f t e r t h e v a l u e of a g e is c h a n g e d
if (!( obj age > 0 ) )
p r i n t D y n a m i c J P I n f o ( t h i s J o i n P o i n t );
p r i n t S t a t i c J P I n f o ( t h i s J o i n P o i n t S t a t i c P a r t );
}
p r i v a t e v o i d p r i n t S t a t i c J P I n f o ( J o i n P o i n t S t a t i c P a r t sp ){
S o u r c e L o c a t i o n sl = sp g e t S o u r c e L o c a t i o n ();
S y s t e m out p r i n t l n ( " S o u r c e l o c a t i o n : "
+ sl g e t F i l e N a m e () + " : " + sl g e t L i n e ( ) ) ; }
p r i v a t e v o i d p r i n t D y n a m i c J P I n f o ( J o i n P o i n t jp ){
}
}
Let us consider again the combined invariant1in Sec.2.1 In order to check these invariants of thePerson class, we have to verify the invariant expression whenever the value of the age attribute is changed A pc_verify_age_Person pointcut should
be declared for the set(int Person.age) field write access joinpoint In general, an afteradvice is declared and implemented to perform verification tasks That means whenever the age attribute of the Person object is set anywhere, the joinpoint is matched and theafteradvice then is executed
To illustrate our solution that is described above, we present a sample code fragment for a simple case in Listing 5, according to the template presented in Listing5
These above source code checks if theageattribute of Person objects is not satis-fied invariant “age > 0” when then the system will print out some loggings Similarly,
we can check other simple or combined invariants that relate only attributes of one class
3.2.2 Associated invariants
Associated constraints contain the relation between objects appearing in OCL state-ment In the example in Sec.2.1, the OCL invariant in Listing2shows the relation between a person/company and its credit accounts
Generally, the relation between a composition class and a part class is imple-mented as references to objects of the part class in the composition class The objects of the part class is considered as attribute values of the composition class
In the example, a person/company may be associated with several credit accounts Credit account is thus expressed as an attribute of the Person/Company class Listing6 shows an example the Person class in which the association is imple-mented as aCollectionofCreditAccount) objects
Listing 6 Association in the Person class
p u b l i c c l a s s P e r s o n {
p r i v a t e int P e r s o n N o ;
Trang 10p r i v a t e C o l l e c t i o n < C r e d i t A c c o u n t > c r e d i t s =
new A r r a y L i s t < C r e d i t A c c o u n t > ( ) ;
p u b l i c v o i d s e t C r e d i t s ( C o l l e c t i o n < C r e d i t A c c o u n t > c r e d i t s ){
t h i s c r e d i t s = c r e d i t s ;
}
p u b l i c b o o l e a n a d d C r e d i t A c c o u n t ( C r e d i t A c c o u n t cc ){
r e t u r n c r e d i t s add ( cc );
}
p u b l i c b o o l e a n r e m o v e C r e d i t A c c o u n t ( C r e d i t A c c o u n t cc ){
r e t u r n c r e d i t s r e m o v e ( cc );
}
//
}
In this case, the association is only kept in thePerson, not in CreditAccount If
a before advice is used to verify the balance attribute of CreditAccount objects as the case of simple/combined invariants, the advice will be executed whenever the value of thebalanceattribute is changed regardless of the owner of theCreditAccount However, the OCL invariant in Listing2assert that the balance of a person should
be at least 100 USD while the balance of a company should be at least 1000 USD Therefore, it is necessary to know who owns the credit card, a person or com-pany, to check the right invariant Here, we can maintain the relation inside the CreditAccount object by creating a reflecting reference (called a reflector) —Person object — to theCreditAccount In AspectJ, this task can be done by static crosscut-tings with inter-type declarations: Declaring apersonReflectorand acompanyReflector
in an aspect but forCreditAccountclass
ThePersonReflectordeclared for the CreditAccount is the reflector of the Person who owns the credit account Therefore, this PersonReflector of the CreditAccount needs to be updated whenever any object of the CreditAccount collection in the Personis changed
This update can be done by pointcuts for addCreditAccount(CreditAccount) method, removeCreditAccount(CreditAccount) method, and credits field write access withafteradvices These pointcuts and advices are illustrated in Listing7 In these advices, we also need to check the invariant conformation for any changed object
Listing 7 A sample pointcut to update the reflector
// In t h e C r e d i t A c c o u n t V e r i f i e r a s p e c t
p o i n t c u t p c _ v e r i f y _ s e t _ c r e d i t s _ P e r s o n ( P e r s o n obj1 ,
C o l l e c t i o n < C r e d i t A c c o u n t > o b j 2 ):
t a r g e t ( o b j 1 ) && a r g s ( o b j 2 ) && set (* P e r s o n c r e d i t s );
a f t e r ( P e r s o n obj1 , C o l l e c t i o n < C r e d i t A c c o u n t > o b j 2 ):
p c _ v e r i f y _ s e t _ c r e d i t s _ P e r s o n ( obj1 , o b j 2 ){
for ( C r e d i t A c c o u n t o b j T e m p : o b j 2 ){
if (!( o b j T e m p balance > 1 0 0 ) ) {
o b j T e m p s e t P e r s o n R e f l e c t o r ( o b j 1 );
o b j T e m p s e t C o m p a n y R e f l e c t o r ( n u l l );