Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

World Congress on Software Engineering

Dynamic service update based on OSGi


Junqing Chen
Linpeng Huang
Dept. of Computer Science and Engineering, Shanghai Jiao Tong University, P.R.China
junqing2004@163.com
Huang-lp@cs.sjtu.edu.cn
is flexible to combine OSGi standards with Web
Services [12] or Java EE servers [9] to build the
service platform. Then, service platform also need to
implement dynamic service update on the fly.
OSGi components deliver through the bundles to
interact by service objects. A major problem of OSGi
component exchange at runtime is the replacement of
service objects. Shutting down all dependent
components and restarting the replaced components,
according to OSGi specification, seems overly cost [5]
and is not really dynamic service update.
In this paper, we propose two techniques to
implement the dynamic service update complying with
the OSGi framework. One technique is replacing the
old service with the new one by selecting the
appropriate updatable point, at the meantime finishing
the state transfer. The other technique implements
updating service by combining with runtime source
compilation, class reloading and the proxy design
pattern, and it is very convenient way to change the
functions of service. On the other hand, typecorrectness of the system during and after dynamic
update needs to be ensured [4]. In short, updating
service does not interrupt the clients of service under
using the two techniques and can make sure the whole
application run correctly all the time.
The rest of this paper is organized as follows: in
section 2, we give the overview of OSGi and further
describe how to update service in OSGi. In section 3,
we present how to dynamically update service under
the framework of OSGi and prove that dynamic service
updating is type-safe under our techniques in section 4.
The discussion on related work is made in section 5
and finally section 6 concludes.

Abstract
In the OSGi framework, the service updating is
achieved by updating the cooperating bundles.
However, the way of service updating requires a
temporary shutdown of bundles and can not implement
the transfer of services states. Thus it is not really
dynamic service update. In this paper, we present two
techniques to solve the problem of dynamically
updating service in OSGi. One technique is replacing
the service through interacting with other service with
the same name. The other technique is based on the
combination of runtime source compilation, class
reloading and the proxy design pattern. The technique
only needs modification of source code and little
manual changes. Finally, we also prove the dynamic
service updating is type-safe if preserving the service
dependency relationships after updates.

1. Introduction
To address changing business requirements, the
maintenance and evolution of applications become
more frequent. Services have to be shut down in the
typical process of software maintenance. However,
many applications, such as banking and air-traffic
control systems, need to run continuously in 24 hours
and can not tolerate service halting at any short time.
The approach of dynamic service update can solve the
problem [11]. Dynamic service update requires that
applications should update the cooperating services
during the running time without stopping the whole
program and is thus becoming an increasingly
important issue. At present, there are some proposed
methods to initially implement updating services
dynamically, such as OSGi.
The OSGi (open service gateway initiative) is a
consortium that has worked to define and promote
open specifications originally intended for the delivery
of managed services to networked environments. Since
the OSGi model takes on the characteristics of a
service-oriented architecture (SOA) that enables the
collaboration among these components dynamically, it

978-0-7695-3570-8/09 $25.00 2009 IEEE


DOI 10.1109/WCSE.2009.122

2. An OSGi overview
The OSGi platform [1] mainly consists of the OSGi
framework and a set of base components referred to as
bundles. A bundle is composed of a Java Archive
(JAR), which contains a manifest file, java classes,
native library and other resource (e.g. images). Bundles
are the minimal deliverable applications in OSGi and
their lifecycles are externally managed by the OSGi
493

framework, e.g. install, start, stop, update, etc. On the


other hand, the minimal unit of functionality is referred
to as an OSGi service, registered into an OSGi
framework with a set of properties [2].

If the OSGi server successfully returns an object of


type ServiceReference, the bundle has only obtained
a reference to the registered service object and been
able to use the required method.

2.1. Services in OSGi

2.2. Service update in OSGi

In OSGi, a bundle can be designed as a set of


cooperating services, which are found by OSGi Service
Registry. Furthermore, an OSGi service is defined by a
service interface, specifying the services public
methods and being implemented as a service object.
Fig.1 gives an example of a service interface with two
public methods.

In OSGi, a bundle can unregister the service if it


holds the corresponding ServiceReference object. For
example, a registering bundle can call the unregister
method or register a new service object again. The
suggested way of updating individual service objects is
updating the registering bundle. This includes stopping
and restarting the bundle, and all the services that
bundles provide must be unregistered and registered
once again. However, these ways may cause dangling
service references in client bundles just as described in
[5] and make the cost of updating service too high.
The next section, two techniques are proposed to
solve the problem and then service objects can be
dynamically updated without directly updating the
bundle.

public interface Message{


public void deliverMessage(String smg);
public boolean isFound(); }
Figure 1. Example of a service interface

2.1.1. Registering OSGi services. When a bundle


registers a service object, it needs to supply the name
of the service interface and a collection of key/value
pairs (properties). For example, in Fig.2 bundle
registers the service object (serviceobj) jointly with
properties (props), under the service interface
(message) as follows:
ServiceRegistration reg =
context.registerService(Message, serviceobj, props );
The registering bundle successfully obtains a
ServiceRegistration object. However, according to
OSGi specification, unregistering the service object is
automatically done when the bundle is stopping.
Bundle A

3. Dynamic service update


In many service-oriented systems, it is often
required that the service should be running
continuously without interrupting the clients of the
service. Therefore, in order to meet the changing
business demands, many services need to be updated at
runtime. The service is regarded as minimal unit of
functionality in an application on top of the OSGi
framework and also needs to be dynamically updated
without stopping the whole application. Dynamic
service update can achieve the aim. Two techniques are
presented to implement dynamic service update.

Bundle B

registerService(Message,serviceobj,props)

3.1. Update service with the same service


interface

getServiceReference(Message)

OSGi specification allows many different


implementations of service class under the same
service interface, so we can make use of the feature to
register many services at the same time and then
further implement dynamic service updating. The
process is just as follows:
Firstly, the new service that has the same name with
the old one is required to register in the framework
before update, because it is allowed to coexist two
version of services with the same name, but different in
service ID according to OSGi specification. Since the
new version has priority over the old one (i.e. decided
by service rank), the client automatically chooses the
new version of service.

Service Register

Figure 2. Registering and accessing OSGi services


2.1.2. Accessing OSGi services. Bundles can not
directly obtain the service objects, but search the
Service Register to require the specific services on
conditions supplying the name of the Service Interface.
For example, in Fig.2 bundle can obtain the
ServiceReference object corresponding to the service
(message) registered by bundle as follows:
ServiceReference
ref=
getServiceReference(Message);

494

Secondly, the safe update point [10] must be


indicated (by either a code analysis tool or a designer)
in order to perform state transfers correctly. For
simplicity and efficiency, the observation point can be
set in the beginning and end of the services method.
Then, if the observation point is found out in the end of
services method, it is considered as a safe update
point, not otherwise. As a matter of fact, it is not safe
to update the state in the program stack according to
the analysis in [10].
After checking a safe update point, the next task is
about the states transfer between two versions of
service. Transferring a services states is using a State
Transfer Function (STF), which consists of the getState
and setState functionality to preserve some necessary
states over the update. A STF can therefore like as:
STF(oldService, newService){
newService.setState( oldService.getState() );
}
Although the idea looks like simple, the
implementation of the STF requires the designers
knowledge of the code, because all required states of
new service must be known about in advance. The STF
for a service resembles the classical Memento design
pattern. In contrast to the Memento pattern, the STF
directly operates to service implementing classes, not
to the memento classes.
After finishing the states transfer, the bundle
registered the replaced service must be stopped and
then refresh the old service in order to make the new
service take effect immediately. As is shown in Fig.3,
after updating the service, the service ID has changed
from 20 to 21, because the new version has higher rank
than the old one. The client bundle essentially obtains
the new service object.
service interface

oldServiceImpl
ServiceID:20

3.2. Updating service with collaboration of the


proxy
The technique covers about runtime source code
compilation, class reloading and the proxy design
pattern. Through none of them are new, combined by
them, modifications to a dynamic service in OSGi can
be done and the update of service is performed in a
fully automated way.
There are four steps toward dynamic service update.
3.2.1. Monitor the changes of service class. Detecting
service implementation class changes can be achieved
by comparing modification timestamps and file sizes.
Once these changes have been detected, source code
needs to be recompiled. To guarantee the type safety
after updates, service interfaces can not be modified.
3.2.2. Compile service source code at runtime. After
a service source code change is detected, java compiler
can be made use of compiling the source code at
runtime. For example, the javac compiler included in
J2SE (Java Standard Edition) can be available to use.
The service source code change needs to comply
with the program design specifications, and once the
java compiler and dynamic linker detect any static
violations, the error message will be given for program
designer. However, the whole application will not shut
down because of this kind of errors.
3.2.3. Reload service class at runtime. The compiled
service class must be loaded before it takes effect. Java
is flexible about class loading and its class loaders are
powerful mechanism for dynamically loading software
components on the Java platform [7]. Here, the basic
idea is to load the dynamic service class using our own
URLClassLoader. Whenever the service source code is
changed and recompiled, the old service class will be
discarded for garbage collection and a new
URLClassLoader will be created to load the class
again.

client:
context.getServiceReferences();
get_ServiceID:20 ---> 21

state transfer

newServiceImpl
ServiceID:21

3.2.4. Replace the old service class with the up-todate service class. When dynamic service class reload
is transparent to its caller, we still need to change the
service instances from the old service to the new one.
In this paper, we will replace the old service instances
taking advantage of the proxy design pattern [13].
A proxy is a class functioning as a dynamic service
classs access interface which extends the service
interface. Service object do not directly invoke the
dynamic service class, but the proxy do instead. When
the dynamic service class reloads, it is just needed to
update the link between the proxy and the dynamic

Figure 3. The new service replacing the old one


In practice, however, the security issues also need to
be considered. When it comes to failure in updating
service, the application is needed to resume before
updating, and this kind of technique appropriately is
able to implement the aim, because the old service is
still working until finishing the process of updating and
can be also restarted. Furthermore, the type safe
updating will be discussed in section 4.

495

service class, and the service object continues to use


the same proxy instance to access the reload class. On
the other hand, all instances of the older service are
automatically destroyed (i.e. garbage collected). For
example, in Fig.4 the rectangle drawn with a dotted
line represents collaboration of the proxy with the
reloaded service class. The dashed line represents the
change of link between the proxy and the dynamic
service class.
The Java reflection API includes a handy utility for
creating proxies. In Fig.4 the getNewProxyInstance
method generates the service object which is registered
by the server bundle. Therefore, the client bundle does
not need any knowledge about the changes of service
class.

() contains implementations for all methods


declared in ().
Definition 2. (Type)[3] A type denotes a set of
objects. is bound to a definition that describes the
contents of the objects and operations that act on them.
Definition 3. (Type of Service) The type of a
service S is also formally defined by the tuple
<(()),(())>, where (()) is the type of
service interface () and (()) is the type of
service implementation class (). Obviously, the
result (()) (()) is true, because () must
implement (). Otherwise, the type violations should
be caused in that it does not comply with the OSGi
specification.
Definition 4. (Services Dependency). A service
1 depends on another service 2 if 1 contains
references to 2. The references mainly include
method invocations and field accesses, that is, service
invocation. The relation 1 2 is true if 1 depends
on 2. The dependency relationship applies to specific
methods. For example, 1. 2. is true if
1. invokes 2..
Considering updating service to , that is,
<(),()><(),()>, changes of the type of
service
,
denoted
<(()),(())><(()),(())>, may
coordinately take place. Since there are not changes in
the service interface during the process of updating,
thus () = () and (()) = (()). However,
(()) not only contains (()), but also refers to
the relation of service dependency on other services.
The changes of services dependency may cause type
violations and lead to some errors in program. Thus,
valid update can avoid any type violations and make
sure the program is running correctly.
Definition 5. (Valid Update Service) Update
service to is valid, if (()) (()) is true
and the services dependency relationships persist after
updates.
Definition 6. (Type safety)[3] A service is typesafe if it does not contain any type violations. A
program is type-safe if all of its components services
classes are type-safe.
Theorem 1. (Type safe update) update program
to with valid update service, if is type-safe, then
is type-safe.
Obviously, the above theorem can be directly
proven according to definition 5 and definition 6. Now,
we can come to conclusion that our dynamic service
updating comply with the type safety.
In fact, incremental service interfaces changes are
also available, because the old service dependency
relationship is always keeping unchanged. Therefore,

client:
context.getServiceReferences();

service interface

proxy

serviceImpl
(reloaded)

serviceImpl
(oldService)

serviceobj=getNewProxyInstance
(Message.class, serviceImpl) ;
registerService(Message,serviceobj,props) ;

Figure 4. Service updates with the proxy pattern

4. Type Safe Updating


Since bundles interact through services provided by
other bundles, it is possibly that there is a reasonably
complex set of service dependences in any given
bundle. Therefore, it is necessary to guarantee that our
techniques should make sure the type safety while
updating the services.
At first, some preliminary definitions about update
service are defined formally. Furthermore, the theorem
about type safe update is provided. Lastly, we prove
that our dynamic service updating is truly type-safe.
Definition 1. (Service) Generally, a service consists
of a service interface and its implementation (called
service implementation). Therefore, a service is
formally defined by the tuple <(), ()>, where
() represents the interface of service and () is
an implementation of service .
In OSGi, () is a set of public methods which
describes the behavior and functionality of service, and

496

modifications of service interfaces are regarded as


adding the new public methods with the same name
but different parameters. To guarantee type safe, it is
not allowed deleting the methods in the service
interfaces.

[2] R.P.Diaz Redondo, A.F. Vilas, M.R. Caber, J.P. Arias


and M.R.Lopez, Enhancing Residential Gateways: OSGi
Service Composition, IEEE Trans. Consumer Electronics,
vol.53, no.1, 2007, pp. 8795.
[3] S. Malabarba, R. Pandey, J. Gragg, E. Barr and J.F.
Barnes, Runtime support for type-safe dynamic Java
classes, In European Conf. on Object-Oriented
Programming, 2000, pp. 337361.

5. Related work
Previous many approaches to dynamic software
update have been presented [3,6,8,10]. In this section,
we present some of them relating to our techniques for
discussion. [8] proposes an approach based on dynamic
linking for C++ and utilizes abstract proxy classes to
define the interface that must remain constant over all
versions. A similar approach for Java based on wrapper
classes is discussed in [6] and class modifications are
handled via proxy classes; therefore the interface can
not be changed. Our techniques are similar to the
above two approaches in the use of proxy pattern, but
our techniques are adaptive to the service-oriented
application complying with the OSGi framework.
In [5], the authors propose the use of the bridge
design pattern to decouple service replacement from
component updates. However, there are many
constraints on the definition of components and the
proof of type safe service updating has not been
provided.

[4] Y. Murarka, U. Bellur and R.K. Joshi, Safety analysis


for dynamic update of object oriented programs, in
APSEC'06, 2006, pp. 225-232.
[5] H.W. Pohl and J. Gerlach, Using the bridge design
pattern for OSGi service update, In Proc. of EuroPLoP,
2003,http://www.hillside.net/europlop/europlop2003/papers.
html#WorkshopD.
[6] A. Orso, A. Rao and M.J. Harrold, A technique for
dynamic updating of java software, In Proc. of ICSM,
Washington, DC, 2002, pp. 649-658.
[7]S. Liang and G. Brach, Dynamic class loading in the java
virtual machine, In C. Chambers, editor, Object-Oriented
Programming Systems, Language and Applications Conf., in
Special Issue of SIGPLAN Notices, no.10, Vancouver, 1998,
pp. 3644.
[8] H. Gilsi and G. Robert, Dynamic C++ classes: A
lightweight mechanism to update code in a running program.
In proceedings of the 1998 USENIX Annual Technical
Conf., New Orleans, Louisiana, May 1998, pp. 6576.

6. Conclusions
Bundles in an application on top of OSGi cooperate
through sharing of service object. According to OSGi
specification, stopping all dependent bundles and
restarting the replaced bundles, seems inconvenient for
service updating. This paper has present two
techniques not only to solve the problem of dangling
references but also to avoid stopping and starting
dependent bundles. Finally, we can prove that our
techniques make the service update type-safe.
However, the second technique is only adaptive to
stateless service updating. Therefore, in future work,
how to solve the state service updating combined by
proxy design pattern and guarantee semantic
correctness is the next our aims.

[9] M. Desertot, D. Donsez and P. Lalanda, A dynamic


Service-Oriented implementation for Java EE Servers, In
IEEE Intel. Conf. on Services Computing (SCC'06), 2006,
pp. 159-166.
[10] D. Gupta, P. Jalote and G. Barua, A formal framework
for online software version change, In IEEE Transactions on
Software Engineering, 22(2), Feb. 1996, pp. 120131.
[11] S. Ajmani, B. Liskov and L. Shrira, Modular software
upgrades for distributed systems, In European Conf. on
Object-Oriented Programming(ECOOP), July 2006, pp. 452476.
[12] A. Bottaro, E. Simon, S. Seyvoz and A. Gerodolle,
Dynamic Web Services on a Home Service Platform, In
22nd International Conf. on Advanced Information
Networking and Appliaction, 2008, pp. 378-385.

7. References
[1] OSGi Service Platform, Core Specification r4, The OSGi
Alliance,
2008,
available:
http://www.osgi.org/Specifications/HomePage.

497

You might also like