• Keine Ergebnisse gefunden

6. System Implementation

6.3. Session State Management

This section discusses how session objects are preserved during bundle swaps. The preservation process is done by serialization of Managed Beans214 belonging to a bundle because the Managed Beans hold the state of a JSF application.

6.3.1. Managed Bean Serialization

Managed Bean serialization only occurs when the core bundle receives a bundle UPDATE or UNINSTALL event from the Equinox framework215. To receive notification of these events, an EnvironmentChangeListener216 class was implemented which contains a bundleChanged() method for receiving bundle events. This method captures bundle events that are of type OSGi UPDATE or UNINSTALL and stores the qualified name of the bundle which initiated the events in a list. Thereafter a SessionObjectSerializer217 object is created to serialize the Managed Beans belonging to the bundle which caused the events.

The SessionObjectSerializer class accesses Jetty’s AbstractSessionManager class in order to retrieve the application session map. The session map is required to get Managed Bean objects belonging to an uninstalled or updated bundle so that they can be serialized. The Managed Beans are stored in the session map where the Managed Bean reference name is the key and the Managed Bean object is the value. The SessionObjectSerializer additionally calls the ClintwebManagedBeanResolver218 class instance to retrieve a list of Managed Bean

214See section 5.7

215See section 3.2.2.1

216See section 5.7.1

217See section 5.7.1

218See section 5.6.1

87 | P a g e

names which belong to the bundle which caused the UNINSTALL/UPDATE event. This list is used to reference the Managed Bean objects in the session map. For each active session, the required Managed Beans objects are serialized into byte streams and saved in a storage location (RAM or disk). After a Managed Bean is serialized, its entry in the session map is removed. This conserves application memory and reduces redundancy of data.

The serialization process is a batch process, meaning that Managed Beans belonging to all active user sessions are serialized at once. The Managed Bean preservation task is time costly. During this process, user requests received by the framework are delayed until bundle swaps are successfully completed.

6.3.2. Managed Bean De-serialization

When a bundle is swapped out, its Managed Beans are serialized and removed from the application session map. Shortly after, another version of the swapped out bundle is installed and the attribute values of the serialized Managed Beans are supposed to be restored into the swapped in bundle’s Managed Beans. The core bundle219 handles the restoration of the serialized of Managed Beans. When a Managed Bean is not found in the session map, JSF calls the OSGiLifecycleProviderAdapter220 to create a new instance of the requested Managed Bean class. When a new Managed Bean instance is requested, the application initially checks if a version of the Managed Bean belonging to the requesting user has been previously serialized. This process is done by the SessionObjectDeserializer221 class as shown in the following figure:

Figure 6.16: De-serializing Managed Beans

219See section 5.2

220See section 5.6.1

221See section 5.7.2

88 | P a g e

The loadObject() function belonging to the SessionObjectDeserializer, takes the requested bean simpleName (provided by the Managed Bean extension point) as an input parameter and uses it to search for a serialized Managed Bean which matches the specified simpleName parameter. Figure 6.17 describes the process flow of de-serializing a Managed Bean:

Check if serialized managed bean

exists

yes Is bean no found?

Read managed bean from its storage location

Return null

Return managed bean

instance Figure 6.17: Resolving Managed Beans

The SessionObjectDeserializer first obtains the session ID222 and the name of the bundle which hosts the referenced Managed Bean class. Using the session ID, the SessionObjectDeserializer checks if the requested serialized Managed Bean is in the storage location. If it is found, the requested Managed Bean is read into an Object using an OSGiObjectInputStream class instance. The OSGiObjectInputStream is an extension of the standard Java ObjectInputStream class. The ObjectInputStream could not be used in de-serializing a Managed Bean because it requires the Managed Bean class to be located in the core bundle where it can be associated with the serialized object; otherwise it throws a ClassNotFoundException exception. The OSGiObjectInputStream class uses the following code to associate serialized objects with their classes located in their host bundles:

Figure 6.18: OSGiObjectInputStream resolveClass function

222The session ID refers to a unique identifier assigned to active session by the web container

89 | P a g e

The loadClass method takes the bean class name as an input parameter and gets the requested Managed Bean class from its host bundle. After the Managed Bean class is resolved by the OSGiObjectInputStream, it is stored into an object and its originating serialized object is deleted. In the case where the serialized Managed Bean is to be casted into an object with a different class structure (different class version), the de-serializer maps the values of variables which are present in both class versions to the new object and ignores the variables which are not in both class structures. If the recovered Managed Bean object (denoted as ‘obj’ in Figure 6.16) is null, then no Managed Bean was found in the storage location, therefore a new Managed Bean can be created from the Managed Bean extension point using the createExecutableExtension function. Otherwise, if the object is not equal to null, the recovered Managed Bean will be forwarded to JSF. Note that the recovered beans will contain the variables values it previously had when the swapped out bundle was active.

Another consideration that had to be made was how serialized objects belonging to a user should be handled when a user session abruptly ends. According to the above described serialization process, the serialized data is only deleted when a Managed Bean request is received by an application. The main complication lies in, what should happen when a serialized Managed Bean was never requested before a user’s session was abruptly ended. It is not efficient to allow the server to continue storing session objects that are no longer valid within an application. To address this problem, a procedure was programmed where a session listener object listens for session-destroyed events and as soon as they occur, it extracts the session-id of the user who initiated the session-destroyed event. The application thereafter deletes all preserved session objects belonging to the user with the extracted session ID. If a user’s network connection breaks down abruptly but the browser remains open, his session can be later resumed and no session information will have been lost during the break down. The user’s browser application must not be closed because it stores the session information which is required to reconnect to the framework and resume the old session. Since the state of an application in JSF is stored on the server, it is certain that session information cannot be lost when connectivity problems occur on the client side.

90 | P a g e

6.4. System Constraints

Class versioning has to be taken into consideration when swapping bundles. In different bundle versions, Managed Bean classes may change in structure and content. Considerations had to be made on the rules governing how old Managed Bean classes can be converted to new Managed Bean classes when a bundle swap occurs. In order to successfully recover a serialized Managed Bean, the new Managed Bean class must have the same qualified class name as the serialized Managed Bean object. The new Managed Bean may contain additional attributes and methods;

these attributes will not affect the casting of the restored Managed Bean to the new Managed Bean. Static and transient variables will not be restored because the serialization API does not support them.

Another constraint is that, when changes are made to a bundle’s exported classes then all dependent bundles must be updated. Changes are not taken automatically by the dependent bundles. If the dependent bundles are not updated, they will continue referencing the old exported packages stored in their caches. It is therefore important to have a clear application outline, denoting the bundle dependencies and exported packages, so that when updates are made affected bundles can also be updated.

91 | P a g e